diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/physconstraint_sounds.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/physconstraint_sounds.h')
| -rw-r--r-- | game/server/physconstraint_sounds.h | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/game/server/physconstraint_sounds.h b/game/server/physconstraint_sounds.h new file mode 100644 index 0000000..71b9a57 --- /dev/null +++ b/game/server/physconstraint_sounds.h @@ -0,0 +1,291 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Data types used inside constraints for the purpose of playing sounds +// during movement. +// +//=============================================================================// + +#ifndef PHYSCONSTRAINT_SOUNDS_H +#define PHYSCONSTRAINT_SOUNDS_H +#ifdef _WIN32 +#pragma once +#endif + + +#include <mathlib/ssemath.h> +#include "soundenvelope.h" + + +/** \brief Class to store a sampled history of velocity for an object -- used for certain sound calculations + +Although this contains only one sample for now, it exists as an interface +so as to make simpler the possibility of moving to a ring buffer +implementation in the future. + +The "sample rate" variable is not nominal: it should be used to specify +the ClientThink() interval. + +Be sure to use the beginSampling() function for the first sample, and +addSample() thereafter: this will be relevant and necessary for a ring +buffer implementation (which will have to perform certain initialization). +*/ +class VelocitySampler +{ +public: + /* + enum + { + HISTORY_DEPTH_LOG = 3, // < log-base-2 of the sampler's array depth + HISTORY_DEPTH = (1 << VELOCITY_SAMPLER_HISTORY_DEPTH_LOG), + }; + */ + + /// Return the internally stored sample rate. + inline float getSampleRate() + { + return m_fIdealSampleRate; + } + + + /// Store off the first recorded sample for the given object. + inline void BeginSampling(const Vector &relativeVelocity); + + /// Record a sample. Do this LAST, after calling hasReversed() et al. + inline void AddSample(const Vector &relativeVelocity); + + /// Using the sample history, determine if the object has reversed direction + /// with at least the given acceleration (in units/sec^2). + int HasReversed(const Vector &relativeVelocity, const float thresholdAcceleration[], const unsigned short numThresholds); + + /// Call this in spawn(). (Not a constructor because those are difficult to use in entities.) + void Initialize(float samplerate); + + + /// A convenience function for extracting the linear velocity of one object relative to another. + inline static Vector GetRelativeVelocity(IPhysicsObject *pObj, IPhysicsObject *pReferenceFrame); + + /// A convenience function for extracting the angular velocity of one object relative to another. + inline static Vector GetRelativeAngularVelocity(IPhysicsObject *pObj, IPhysicsObject *pReferenceFrame); + + +protected: + Vector m_prevSample; + float m_fPrevSampleTime; + + float m_fIdealSampleRate; + +}; + +struct SimpleConstraintSoundProfile +{ + // define the indices of the sound points: + enum + { + kMIN_THRESHOLD, ///< below this no sound is played + kMIN_FULL, ///< at this velocity sound is at its loudest + + kHIGHWATER, ///< high water mark for this enum + } eKeypoints; + + float m_keyPoints[kHIGHWATER]; + + /// Number of entries in the reversal sound array + enum { kREVERSAL_SOUND_ARRAY_SIZE = 3 }; + + /// Acceleration threshold for playing the hard-reverse sound. Divided into sections. + /// Below the 0th threshold no sound will play. + float m_reversalSoundThresholds[kREVERSAL_SOUND_ARRAY_SIZE]; + + /// Get volume for given velocity [0..1] + float GetVolume(float inVel); +}; + +float SimpleConstraintSoundProfile::GetVolume(float inVel) +{ + // clamped lerp on 0-1 + if (inVel <= m_keyPoints[kMIN_THRESHOLD]) + { + return 0; + } + else if (inVel >= m_keyPoints[kMIN_FULL]) + { + return 1; + } + else // lerp... + { + return (inVel - m_keyPoints[kMIN_THRESHOLD])/(m_keyPoints[kMIN_FULL] - m_keyPoints[kMIN_THRESHOLD]); + } +} + +class CPhysConstraint; +/** This class encapsulates the data and behavior necessary for a constraint to play sounds. + + For the moment I have no easy means of populating this from an entity's datadesc. + You should explicitly fill out the fields with eg + + DEFINE_KEYFIELD( m_soundInfo.m_soundProfile.m_keyPoints[SimpleConstraintSoundProfile::kMIN_THRESHOLD] , FIELD_FLOAT, "minSoundThreshold" ), + DEFINE_KEYFIELD( m_soundInfo.m_soundProfile.m_keyPoints[SimpleConstraintSoundProfile::kMIN_FULL] , FIELD_FLOAT, "maxSoundThreshold" ), + DEFINE_KEYFIELD( m_soundInfo.m_iszTravelSoundFwd, FIELD_SOUNDNAME, "slidesoundfwd" ), + DEFINE_KEYFIELD( m_soundInfo.m_iszTravelSoundBack, FIELD_SOUNDNAME, "slidesoundback" ), + DEFINE_KEYFIELD( m_soundInfo.m_iszReversalSound, FIELD_SOUNDNAME, "reversalsound" ), + DEFINE_KEYFIELD( m_soundInfo.m_soundProfile.m_reversalSoundThreshold , FIELD_FLOAT, "reversalsoundthreshold" ), + + */ +class ConstraintSoundInfo +{ +public: + // no ctor. + // dtor + ~ConstraintSoundInfo(); + + /// Call from the constraint's Activate() + void OnActivate( CPhysConstraint *pOuter ); + + /// Constraint should have a think function that calls this. It should pass in relative velocity + /// between child and parent. (This need not be linear velocity; it may be angular.) + void OnThink( CPhysConstraint *pOuter, const Vector &relativeVelocity ); + + /// This is how often the think function should be run: + inline float getThinkRate() const { return 0.09f; } + + /// Call this before the first call to OnThink() + void StartThinking( CPhysConstraint *pOuter, const Vector &relativeVelocity, const Vector &forwardVector ); + + /// Call this if you intend to stop calling OnThink(): + void StopThinking( CPhysConstraint *pOuter ); + + /// Call from owner's Precache(). + void OnPrecache( CPhysConstraint *pOuter ); + + + VelocitySampler m_vSampler; + SimpleConstraintSoundProfile m_soundProfile; + + Vector m_forwardAxis; ///< velocity in this direction is forward. The opposite direction is backward. + + string_t m_iszTravelSoundFwd,m_iszTravelSoundBack; // Path/filename of WAV file to play. + CSoundPatch *m_pTravelSound; + bool m_bPlayTravelSound; + + string_t m_iszReversalSounds[SimpleConstraintSoundProfile::kREVERSAL_SOUND_ARRAY_SIZE]; // Path/filename of WAV files to play -- one per entry in threshold. + // CSoundPatch *m_pReversalSound; + bool m_bPlayReversalSound; + +protected: + /// Maintain consistency of internal datastructures on start + void ValidateInternals( CPhysConstraint *pOuter ); + + /// Stop playing any active sounds. + void DeleteAllSounds(); +}; + + +/////////////// INLINE FUNCTIONS + + +/// compute the relative velocity between an object and its parent. Just a convenience. +Vector VelocitySampler::GetRelativeVelocity( IPhysicsObject *pObj, IPhysicsObject *pReferenceFrame ) +{ + Vector childVelocity, parentVelocity; + pObj->GetImplicitVelocity( &childVelocity, NULL ); + pReferenceFrame->GetImplicitVelocity(&parentVelocity, NULL); + + return (childVelocity - parentVelocity); +} + + +Vector VelocitySampler::GetRelativeAngularVelocity( IPhysicsObject *pObj, IPhysicsObject *pReferenceFrame ) +{ + Assert(pObj); + + if ( pReferenceFrame ) + { + Vector childVelocityLocal, parentVelocityLocal, childVelocityWorld, parentVelocityWorld; + pObj->GetImplicitVelocity( NULL, &childVelocityLocal ); + pObj->LocalToWorldVector( &childVelocityWorld, childVelocityLocal ); + pReferenceFrame->GetImplicitVelocity( NULL, &parentVelocityLocal ); + pObj->LocalToWorldVector( &parentVelocityWorld, parentVelocityLocal ); + + return (childVelocityWorld - parentVelocityWorld); + } + else + { + Vector childVelocityLocal, childVelocityWorld; + pObj->GetImplicitVelocity( NULL, &childVelocityLocal ); + pObj->LocalToWorldVector( &childVelocityWorld, childVelocityLocal ); + + return (childVelocityWorld); + } +} + +/************************************************************************/ +// This function is nominal -- it's here as an interface because in the +// future there will need to be special initialization for the first entry +// in a ring buffer. (I made a test implementation of this, then reverted it +// later; this is not an arbitrary assumption.) +/************************************************************************/ +/// Store off the first recorded sample for the given object. +void VelocitySampler::BeginSampling(const Vector &relativeVelocity) +{ + return AddSample(relativeVelocity); +} + +// Record a sample for the given object +void VelocitySampler::AddSample(const Vector &relativeVelocity) +{ + m_prevSample = relativeVelocity; + m_fPrevSampleTime = gpGlobals->curtime; +} + + + +/* // abandoned -- too complicated, no way to set from keyfields +#pragma warning(push) +#pragma warning( disable:4201 ) // C4201: nonstandard extension used: nameless struct/union +/// Stores information used for playing sounds based on +/// constraint movement +class ConstraintSoundProfile +{ +public: +/// Defines a point in the sound profile: volume and pitch for the sound to play. +/// Implicit crossfading between two sounds. Used to map velocity to a sound profile. +struct SoundInfoTuple +{ +float minVelocity; +union { +struct{ +float volume1,pitch1; //< volume and pitch of sound 1 +float volume2,pitch2; //< volume and pitch of sound 2 +}; +fltx4 m_as4; +}; + +inline SoundInfoTuple(float _minVelocity, float _volume1, float _pitch1, float _volume2, float _pitch2) : +minVelocity(_minVelocity), volume1(_volume1), pitch1(_pitch1), volume2(_volume2), pitch2(_pitch2) +{} +}; + +ConstraintSoundProfile(const SoundInfoTuple *soundTable, unsigned int tableSize) +: m_pSoundInfos(soundTable), m_numSoundInfos(tableSize) +{} + + +protected: + +/// A table of sound info structs +const SoundInfoTuple * const m_pSoundInfos; +/// Size of the table +const unsigned int m_numSoundInfos; +}; + +static ConstraintSoundProfile::SoundInfoTuple CSDebugProfileTable[] = +{ +ConstraintSoundProfile::SoundInfoTuple(12,0,0,0,0), +ConstraintSoundProfile::SoundInfoTuple(24,0,0,0,0), + +}; +#pragma warning(pop) +*/ + + +#endif |