1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
// Copyright 2021 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_MUMBLE_POSITIONAL_AUDIO_CONTEXT_H_
#define MUMBLE_MUMBLE_POSITIONAL_AUDIO_CONTEXT_H_
#include <QtCore/QString>
#include <QtCore/QReadWriteLock>
/// An enum for the three cartesian coordinate axes x, y and z
enum class Coord {X=0,Y,Z};
/// A 3D vector class holding an x-, y- and z-coordinate
struct Vector3D {
/// The vector's x-coordinate
float x;
/// The vector's y-coordinate
float y;
/// The vector's z-coordinate
float z;
/// Access the respective coordinate in an array-like fashion
///
/// @param coord The Coord to access
/// @returns The value of the respective coordinate
float operator[](Coord coord) const;
/// @param factor The factor to scale by
/// @returns A new vector that has been created by scaling this vector by the given factor
Vector3D operator*(float factor) const;
/// @param divisor The divisor to apply to all coordinates
/// @returns A new vector obtained from this one by applying the divisor to all coordinates
Vector3D operator/(float divisor) const;
/// Scales this vector by the given factor
///
/// @param factor The factor to use
void operator*=(float factor);
/// Divides all of this vector's coordinates by the given divisor
///
/// @param divisor The divisor to use
void operator/=(float divisor);
/// @param other The vector to compare this one to
/// @returns Whether the given vector is equal to this one (their coordinates are the same)
bool operator==(const Vector3D& other) const;
/// @param other The vector to subtract from this one
/// @returns A new vector representing the difference of this vector and the other one
Vector3D operator-(const Vector3D& other) const;
/// @param other The vector to add to this one
/// @returns A new vector representing the sum of this vector and the other one
Vector3D operator+(const Vector3D& other) const;
/// @param other The vector to copy
/// @returns A copy of the other vector
Vector3D& operator=(const Vector3D& other) = default;
// allow explicit conversions from this struct to a float-array / float-pointer
/// Explicit conversion to a float-array (of length 3) containing the coordinates of this vector
explicit operator const float*() const { return &x; };
/// Explicit conversion to a float-array (of length 3) containing the coordinates of this vector
explicit operator float*() { return &x; };
/// Default constructor - sets all coordinates to 0
Vector3D();
/// @param x The x-coordinate
/// @param y The y-coordinate
/// @param z The z-coordinate
Vector3D(float x, float y, float z);
/// Copy constructor
///
/// @param other The vector to copy
Vector3D(const Vector3D& other);
/// Destructor
~Vector3D();
/// @returns The squared euclidean norm (length of the vector)
float normSquared() const;
/// If possible normSquared() should be preferred as this doesn't require a square-root operator
///
/// @returns The euclidean norm (length of the vector)
float norm() const;
/// @param other The vector to calculate the dot-product with
/// @returns The dot-product between this vector an the other one
float dotProduct(const Vector3D& other) const;
/// @param other The vector to calculate the cross-product (vector-product) with
/// @returns The vector resulting from the cross-product (vector-product)
Vector3D crossProduct(const Vector3D& other) const;
/// @param other The vector to compare this one to
/// @param threshold The maximum absolute difference for coordinates to still be considered equal
/// @returns Whether this and the given vector are equal
bool equals(const Vector3D& other, float threshold = 0.0f) const;
/// @param threshold The maximum absolute value a coordinate may have to still be considered zero
/// @returns Whether this vector is the zero-vector
bool isZero(float threshold = 0.0f) const;
/// Normalizes this vector to a unit-vector. Callin this function on a zero-vector results in undefined behaviour!
void normalize();
/// Transforms this vector to a zero-vector by setting all coordinates to zero
void toZero();
};
// As we're casting the vector struct to float-arrays, we have to make sure that the compiler won't introduce any padding
// into the structure
static_assert(sizeof(Vector3D) == 3*sizeof(float), "The compiler added padding to the Vector3D structure so it can't be cast to a float-array!");
/// A convenient alias as a position can be treated the same way a vector can
typedef Vector3D Position3D;
/// A class holding positional data used in the positional audio feature
class PositionalData {
friend class PluginManager; // needed in order for PluginManager::fetch to write to the contained fields
protected:
/// The player's position in the 3D world
Position3D m_playerPos;
/// The direction in which the player is looking
Vector3D m_playerDir;
/// The connection vector between the player's feet and his/her head
Vector3D m_playerAxis;
/// The camera's position un the 3D world
Position3D m_cameraPos;
/// The direction in which the camera is looking
Vector3D m_cameraDir;
/// The connection from the camera's bottom to its top
Vector3D m_cameraAxis;
/// The context of this positional data. This might include the game's name, the server currently connected to, etc. and is used
/// to determine which players can hear one another
QString m_context;
/// The player's ingame identity (name)
QString m_identity;
/// The lock guarding all fields of this class
mutable QReadWriteLock m_lock;
public:
/// Default constructor
PositionalData();
/// Constructor initializing all fields to a specific value
PositionalData(Position3D playerPos, Vector3D playerDir, Vector3D playerAxis, Position3D cameraPos, Vector3D cameraDir,
Vector3D cameraAxis, QString context, QString identity);
/// Destructor
~PositionalData();
/// @param[out] pos The player's 3D position
void getPlayerPos(Position3D& pos) const;
/// @returns The player's 3D position
Position3D getPlayerPos() const;
/// @param[out] vec The direction in which the player is currently looking
void getPlayerDir(Vector3D& vec) const;
/// @returns The direction in which the player is currently looking
Vector3D getPlayerDir() const;
/// @param[out] axis The connection between the player's feet and his/her head
void getPlayerAxis(Vector3D& axis) const;
/// @returns The connection between the player's feet and his/her head
Vector3D getPlayerAxis() const;
/// @param[out] pos The camera's 3D position
void getCameraPos(Position3D& pos) const;
/// @returns The camera's 3D position
Position3D getCameraPos() const;
/// @param[out] vec The direction in which the camera is currently looking
void getCameraDir(Vector3D& vec) const;
/// @returns The direction in which the camera is currently looking
Vector3D getCameraDir() const;
/// @param[out] axis The connection between the player's feet and his/her head
void getCameraAxis(Vector3D& axis) const;
/// @returns The connection between the player's feet and his/her head
Vector3D getCameraAxis() const;
/// @returns The player's identity
QString getPlayerIdentity() const;
/// @returns The current context
QString getContext() const;
/// Resets all fields in this object
void reset();
};
#endif
|