mumble-voip_mumble/src/mumble/PositionalData.h

173 lines
7.3 KiB
C++

// Copyright 2021-2023 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/QReadWriteLock>
#include <QtCore/QString>
/// 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