mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-14 03:09:08 +00:00
264 lines
8.8 KiB
C++
264 lines
8.8 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef NL_CLUSTERED_SOUND_H
|
|
#define NL_CLUSTERED_SOUND_H
|
|
|
|
#include "nel/misc/types_nl.h"
|
|
#include "nel/misc/string_mapper.h"
|
|
#include "nel/misc/sheet_id.h"
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
namespace NLMISC
|
|
{
|
|
class CAABBox;
|
|
}
|
|
namespace NL3D
|
|
{
|
|
class UScene;
|
|
class CScene;
|
|
class CCluster;
|
|
}
|
|
|
|
namespace NLSOUND
|
|
{
|
|
|
|
class USource;
|
|
|
|
/** This class will manage the clipping/positioning/occlusion of sound placed inside the
|
|
* cluster/portal system.
|
|
*
|
|
* \author Boris Boucher
|
|
* \author Nevrax France
|
|
* \date 2002
|
|
*/
|
|
class CClusteredSound
|
|
{
|
|
public:
|
|
/// This structure contain data about sound status in a cluster
|
|
struct CClusterSoundStatus
|
|
{
|
|
/// The relative gain of sound in the cluster
|
|
float Gain;
|
|
/// The distance from listener.
|
|
float Dist;
|
|
/// The ratio distance/max earing distance
|
|
float DistFactor;
|
|
/// The sound virtual position (in fact Dist * Direction)
|
|
NLMISC::CVector Position;
|
|
/// The blending factor between real sound pos and virtual pos (1 mean virtual pos, 0 mean real pos).
|
|
float PosAlpha;
|
|
/// The direction vector for the virtual sound source.
|
|
NLMISC::CVector Direction;
|
|
/// The occlusion att.
|
|
sint32 Occlusion;
|
|
/// The occlusion LF factor (see EAX spec)
|
|
float OcclusionLFFactor;
|
|
/// The occlusion romm ration
|
|
float OcclusionRoomRatio;
|
|
/// The obsctruction att db
|
|
sint32 Obstruction;
|
|
};
|
|
|
|
/// Container for audible cluster status
|
|
typedef std::map<NL3D::CCluster*, CClusterSoundStatus> TClusterStatusMap;
|
|
|
|
/// This structure is used when we traverse the cluster/portal graph.
|
|
struct CSoundTravContext
|
|
{
|
|
/// The current gain.
|
|
float Gain;
|
|
sint32 Occlusion;
|
|
float OcclusionLFFactor;
|
|
float OcclusionRoomRatio;
|
|
sint32 Obstruction;
|
|
/// The distance acumulator
|
|
float Dist;
|
|
/// A flag that indicate if we need to filter the unvisible child.
|
|
bool FilterUnvisibleChild;
|
|
/// A flag that iindicate if we need to filter the unvisible father.
|
|
bool FilterUnvisibleFather;
|
|
/// The number of traversed portals
|
|
uint NbPortal;
|
|
/// A blending factor to compute virtual source position.
|
|
float Alpha;
|
|
/// The direction vector from listener to the first portal/cluster
|
|
NLMISC::CVector Direction1;
|
|
/// The direction vector from the first portal/cluster to the second one.
|
|
NLMISC::CVector Direction2;
|
|
/// The current blended direction used to place vitual source.
|
|
NLMISC::CVector Direction;
|
|
/// The previously traversed cluster. Used to stop back traversal.
|
|
NL3D::CCluster *PreviousCluster;
|
|
/// The previous sound propagation vector
|
|
NLMISC::CVector PreviousVector;
|
|
|
|
/// The last pseudo listener position
|
|
NLMISC::CVector ListenerPos;
|
|
|
|
/// Constructor. Init all default value.
|
|
CSoundTravContext(const NLMISC::CVector &listenerPos,
|
|
bool filterUnvisibleChild, bool filterUnvisibleFather)
|
|
: Gain(1.0f),
|
|
Occlusion(0),
|
|
OcclusionLFFactor(1.0f),
|
|
OcclusionRoomRatio(1.0f),
|
|
Obstruction(0),
|
|
Dist(0),
|
|
FilterUnvisibleChild(filterUnvisibleChild),
|
|
FilterUnvisibleFather(filterUnvisibleFather),
|
|
NbPortal(0),
|
|
Alpha(0.0f),
|
|
Direction1(NLMISC::CVector::Null),
|
|
Direction2(NLMISC::CVector::Null),
|
|
Direction(NLMISC::CVector::Null),
|
|
PreviousCluster(0),
|
|
PreviousVector(NLMISC::CVector::Null),
|
|
ListenerPos(listenerPos)
|
|
{}
|
|
|
|
/// Assignment operator.
|
|
CSoundTravContext &operator = (const CSoundTravContext &other)
|
|
{
|
|
Gain = other.Gain;
|
|
Occlusion = other.Occlusion;
|
|
OcclusionLFFactor = other.OcclusionLFFactor;
|
|
OcclusionRoomRatio = other.OcclusionRoomRatio;
|
|
Obstruction = other.Obstruction;
|
|
Dist = other.Dist;
|
|
FilterUnvisibleChild = other.FilterUnvisibleChild;
|
|
FilterUnvisibleFather = other.FilterUnvisibleFather;
|
|
NbPortal = other.NbPortal;
|
|
Alpha = other.Alpha;
|
|
Direction1 = other.Direction1;
|
|
Direction2 = other.Direction2;
|
|
Direction = other.Direction;
|
|
PreviousCluster = other.PreviousCluster;
|
|
ListenerPos = other.ListenerPos;
|
|
PreviousVector = other.PreviousVector;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
///
|
|
struct CClusterSound
|
|
{
|
|
USource *Source;
|
|
float Distance;
|
|
};
|
|
|
|
|
|
/// Container for the next traversal step
|
|
typedef std::map<NL3D::CCluster*, CSoundTravContext> TClusterTravContextMap;
|
|
|
|
|
|
/// Constructor
|
|
CClusteredSound();
|
|
|
|
/** Initialize the class
|
|
* \param scene The scene of interest for cluster management.
|
|
* \param portalInterpolate Ditance from listener to portal for interpolation.
|
|
* \param maxEarDist The maximum traversal distance to limit graph traversal.
|
|
* \param minGain The minimun gain to stop traversal.
|
|
*/
|
|
void init(NL3D::CScene *scene, float portalInterpolate, float maxEarDistance, float minGain);
|
|
|
|
/** Update the cluster sound system.
|
|
*/
|
|
void update(const NLMISC::CVector &listenerPos, const NLMISC::CVector &view, const NLMISC::CVector &up);
|
|
|
|
NL3D::CCluster *getRootCluster();
|
|
|
|
|
|
const CClusterSoundStatus *getClusterSoundStatus(NL3D::CCluster *cluster);
|
|
|
|
const TClusterStatusMap &getAudibleClusters() {return _AudibleClusters;}
|
|
|
|
const std::vector<std::pair<NLMISC::CVector, NLMISC::CVector> > &getAudioPath() { return _AudioPath;}
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// Traverse the cluster system to build/update the audible cluster set and theire respective status.
|
|
void soundTraverse(const std::vector<NL3D::CCluster *> &clusters, CSoundTravContext &travContext);
|
|
/// Add a cluster for the next traversal step
|
|
void addNextTraverse(NL3D::CCluster *cluster, CSoundTravContext &travContext);
|
|
/// Add a cluster into the list of audible cluster.
|
|
bool addAudibleCluster(NL3D::CCluster *cluster, CClusterSoundStatus &soundStatus);
|
|
/// Compute a positional blending depending on context.
|
|
NLMISC::CVector interpolateSourceDirection(const CSoundTravContext &context, float portalDist, const NLMISC::CVector &nearPoint, const NLMISC::CVector &realListener, NLMISC::CVector &d1, NLMISC::CVector &d2, float &alpha);
|
|
//\name Utility method
|
|
//@{
|
|
/** Compute the point on the poly that is the nearest from a given position.
|
|
* This point can be on the surface of the poly, on a segment or on one of the vertex.
|
|
* In addition, the method also return the distance from the nearest point to the
|
|
* reference position.
|
|
* \param poly The polygone description.
|
|
* \param pos The reference position.
|
|
* \param nearPoint The nearest point (out var).
|
|
* \return The distance between pos and nearPoint.
|
|
*/
|
|
float getPolyNearestPos(const std::vector<NLMISC::CVector> &poly, const NLMISC::CVector &pos, NLMISC::CVector &nearPoint);
|
|
|
|
/** Compute the point in the bounding box that is the nearest from a given position.
|
|
* This point can be in the volume of the box, on a segment of one of the vertex.
|
|
* In addition, the method also return the distance from the nearest point to the
|
|
* reference position.
|
|
* \param poly The bounding box description.
|
|
* \param pos The reference position.
|
|
* \param nearPoint The nearest point (out var).
|
|
* \return The distance between pos and nearPoint.
|
|
*/
|
|
float getAABoxNearestPos(const NLMISC::CAABBox &box, const NLMISC::CVector &pos, NLMISC::CVector &nearPos);
|
|
//@}
|
|
|
|
/// The scene of interest
|
|
NL3D::CScene *_Scene;
|
|
/// Interpolation distance when listener is near a portal.
|
|
float _PortalInterpolate;
|
|
/// Maximum earing distance.
|
|
float _MaxEarDistance;
|
|
/// Minimum gain.
|
|
float _MinGain;
|
|
/// The root cluster of the scene.
|
|
NL3D::CCluster *_RootCluster;
|
|
|
|
|
|
/// The current audible cluster
|
|
TClusterStatusMap _AudibleClusters;
|
|
/// The cluster for the next travesal step
|
|
TClusterTravContextMap _NextTraversalStep;
|
|
/// The last setted environement.
|
|
NLMISC::TStringId _LastEnv;
|
|
/// The last set environment size.
|
|
float _LastEnvSize;
|
|
/// The segment of all the audio path.
|
|
std::vector<std::pair<NLMISC::CVector, NLMISC::CVector> > _AudioPath;
|
|
|
|
typedef CHashMap<NLMISC::TStringId, CClusterSound, NLMISC::CStringIdHashMapTraits> TClusterSoundCont;
|
|
/// The current cluster playing source indexed with sound group id
|
|
TClusterSoundCont _Sources;
|
|
|
|
typedef CHashMap<NLMISC::TStringId, NLMISC::CSheetId, NLMISC::CStringIdHashMapTraits> TStringSheetMap;
|
|
/// The sound_group to sound assoc
|
|
TStringSheetMap _SoundGroupToSound;
|
|
};
|
|
|
|
} // NLSOUND
|
|
|
|
#endif // NL_CLUSTERED_SOUND_H
|