diff options
Diffstat (limited to 'src/mumble/PositionalData.h')
-rw-r--r-- | src/mumble/PositionalData.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/mumble/PositionalData.h b/src/mumble/PositionalData.h new file mode 100644 index 000000000..a0f6f4013 --- /dev/null +++ b/src/mumble/PositionalData.h @@ -0,0 +1,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 |