mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-19 19:35:26 +00:00
Cleaned up implementation of #712
Also updates other game classes like the shapebase to utilize the sound asset hooks properly.
This commit is contained in:
parent
3812ce2e82
commit
15ef8b4fbe
12 changed files with 312 additions and 187 deletions
|
|
@ -1562,33 +1562,50 @@ void GameConnection::packetDropped(PacketNotify *note)
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void GameConnection::play2D(SFXProfile* profile)
|
||||
void GameConnection::play2D(StringTableEntry assetId)
|
||||
{
|
||||
postNetEvent(new Sim2DAudioEvent(profile));
|
||||
if (AssetDatabase.isDeclaredAsset(assetId))
|
||||
{
|
||||
|
||||
AssetPtr<SoundAsset> tempSoundAsset;
|
||||
tempSoundAsset = assetId;
|
||||
|
||||
postNetEvent(new SimSoundAssetEvent(tempSoundAsset));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void GameConnection::play3D(SFXProfile* profile, const MatrixF *transform)
|
||||
void GameConnection::play3D(StringTableEntry assetId, const MatrixF *transform)
|
||||
{
|
||||
if ( !transform )
|
||||
play2D(profile);
|
||||
play2D(assetId);
|
||||
|
||||
else if ( !mControlObject )
|
||||
postNetEvent(new Sim3DAudioEvent(profile,transform));
|
||||
|
||||
else
|
||||
if (AssetDatabase.isDeclaredAsset(assetId))
|
||||
{
|
||||
// TODO: Maybe improve this to account for the duration
|
||||
// of the sound effect and if the control object can get
|
||||
// into hearing range within time?
|
||||
|
||||
// Only post the event if it's within audible range
|
||||
// of the control object.
|
||||
Point3F ear,pos;
|
||||
transform->getColumn(3,&pos);
|
||||
mControlObject->getTransform().getColumn(3,&ear);
|
||||
if ((ear - pos).len() < profile->getDescription()->mMaxDistance)
|
||||
postNetEvent(new Sim3DAudioEvent(profile,transform));
|
||||
}
|
||||
AssetPtr<SoundAsset> tempSoundAsset;
|
||||
tempSoundAsset = assetId;
|
||||
|
||||
if (!mControlObject)
|
||||
postNetEvent(new SimSoundAssetEvent(tempSoundAsset, transform));
|
||||
else
|
||||
{
|
||||
// TODO: Maybe improve this to account for the duration
|
||||
// of the sound effect and if the control object can get
|
||||
// into hearing range within time?
|
||||
|
||||
// Only post the event if it's within audible range
|
||||
// of the control object.
|
||||
tempSoundAsset->getSfxDescription();
|
||||
Point3F ear, pos;
|
||||
transform->getColumn(3, &pos);
|
||||
mControlObject->getTransform().getColumn(3, &ear);
|
||||
if ((ear - pos).len() < tempSoundAsset->getSfxDescription()->mMaxDistance)
|
||||
postNetEvent(new SimSoundAssetEvent(tempSoundAsset, transform));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GameConnection::doneScopingScene()
|
||||
|
|
@ -2010,49 +2027,49 @@ DefineEngineMethod( GameConnection, isControlObjectRotDampedCamera, bool, (),,
|
|||
return object->isControlObjectRotDampedCamera();
|
||||
}
|
||||
|
||||
DefineEngineMethod( GameConnection, play2D, bool, (SFXProfile* profile),,
|
||||
DefineEngineMethod( GameConnection, play2D, bool, (StringTableEntry assetId),,
|
||||
"@brief Used on the server to play a 2D sound that is not attached to any object.\n\n"
|
||||
|
||||
"@param profile The SFXProfile that defines the sound to play.\n\n"
|
||||
"@param assetID The SoundAsset ID that defines the sound to play.\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"function ServerPlay2D(%profile)\n"
|
||||
"function ServerPlay2D(%assetId)\n"
|
||||
"{\n"
|
||||
" // Play the given sound profile on every client.\n"
|
||||
" // Play the given sound asset on every client.\n"
|
||||
" // The sounds will be transmitted as an event, not attached to any object.\n"
|
||||
" for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)\n"
|
||||
" ClientGroup.getObject(%idx).play2D(%profile);\n"
|
||||
" ClientGroup.getObject(%idx).play2D(%assetId);\n"
|
||||
"}\n"
|
||||
"@endtsexample\n\n")
|
||||
{
|
||||
if(!profile)
|
||||
if(assetId == StringTable->EmptyString())
|
||||
return false;
|
||||
|
||||
object->play2D(profile);
|
||||
object->play2D(assetId);
|
||||
return true;
|
||||
}
|
||||
|
||||
DefineEngineMethod( GameConnection, play3D, bool, (SFXProfile* profile, TransformF location),,
|
||||
DefineEngineMethod( GameConnection, play3D, bool, (StringTableEntry assetId, TransformF location),,
|
||||
"@brief Used on the server to play a 3D sound that is not attached to any object.\n\n"
|
||||
|
||||
"@param profile The SFXProfile that defines the sound to play.\n"
|
||||
"@param assetID The SoundAsset ID that defines the sound to play.\n"
|
||||
"@param location The position and orientation of the 3D sound given in the form of \"x y z ax ay az aa\".\n\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"function ServerPlay3D(%profile,%transform)\n"
|
||||
"function ServerPlay3D(%assetId,%transform)\n"
|
||||
"{\n"
|
||||
" // Play the given sound profile at the given position on every client\n"
|
||||
" // Play the given sound asset at the given position on every client\n"
|
||||
" // The sound will be transmitted as an event, not attached to any object.\n"
|
||||
" for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)\n"
|
||||
" ClientGroup.getObject(%idx).play3D(%profile,%transform);\n"
|
||||
" ClientGroup.getObject(%idx).play3D(%assetID,%transform);\n"
|
||||
"}\n"
|
||||
"@endtsexample\n\n")
|
||||
{
|
||||
if(!profile)
|
||||
if(assetId == StringTable->EmptyString())
|
||||
return false;
|
||||
|
||||
MatrixF mat = location.getMatrix();
|
||||
object->play3D(profile,&mat);
|
||||
object->play3D(assetId,&mat);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -352,8 +352,8 @@ public:
|
|||
/// @name Sound
|
||||
/// @{
|
||||
|
||||
void play2D(SFXProfile *profile);
|
||||
void play3D(SFXProfile *profile, const MatrixF *transform);
|
||||
void play2D(StringTableEntry assetId);
|
||||
void play3D(StringTableEntry assetId, const MatrixF *transform);
|
||||
/// @}
|
||||
|
||||
/// @name Misc.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
//--------------------------------------------------------------------------
|
||||
IMPLEMENT_CO_CLIENTEVENT_V1(SimDataBlockEvent);
|
||||
IMPLEMENT_CO_CLIENTEVENT_V1(SimSoundAssetEvent);
|
||||
IMPLEMENT_CO_CLIENTEVENT_V1(Sim2DAudioEvent);
|
||||
IMPLEMENT_CO_CLIENTEVENT_V1(Sim3DAudioEvent);
|
||||
IMPLEMENT_CO_CLIENTEVENT_V1(SetMissionCRCEvent);
|
||||
|
|
@ -293,6 +294,104 @@ void SimDataBlockEvent::process(NetConnection *cptr)
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static F32 SoundPosAccuracy = 0.5;
|
||||
static S32 SoundRotBits = 8;
|
||||
|
||||
SimSoundAssetEvent::SimSoundAssetEvent(AssetPtr<SoundAsset> asset, const MatrixF* mat)
|
||||
{
|
||||
// cant get here unless the asset is declared.
|
||||
mAsset = asset;
|
||||
|
||||
if (mat)
|
||||
mTransform = *mat;
|
||||
}
|
||||
|
||||
void SimSoundAssetEvent::pack(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
NetStringHandle assetIdStr = mAsset->getAssetId();
|
||||
con->packNetStringHandleU(stream, assetIdStr);
|
||||
|
||||
// only stream if this is a 3d sound asset.
|
||||
if (mAsset->is3D())
|
||||
{
|
||||
SFXDescription* ad = mAsset->getSfxDescription();
|
||||
if (stream->writeFlag(ad->mConeInsideAngle || ad->mConeOutsideAngle))
|
||||
{
|
||||
QuatF q(mTransform);
|
||||
q.normalize();
|
||||
|
||||
// LH - we can get a valid quat that's very slightly over 1 in and so
|
||||
// this fails (barely) check against zero. So use some error-
|
||||
AssertFatal((1.0 - ((q.x * q.x) + (q.y * q.y) + (q.z * q.z))) >= (0.0 - 0.001),
|
||||
"QuatF::normalize() is broken in Sim3DAudioEvent");
|
||||
|
||||
stream->writeSignedFloat(q.x, SoundRotBits);
|
||||
stream->writeSignedFloat(q.y, SoundRotBits);
|
||||
stream->writeSignedFloat(q.z, SoundRotBits);
|
||||
stream->writeFlag(q.w < 0.0);
|
||||
}
|
||||
|
||||
Point3F pos;
|
||||
mTransform.getColumn(3, &pos);
|
||||
stream->writeCompressedPoint(pos, SoundPosAccuracy);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SimSoundAssetEvent::write(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
// Just do the normal pack...
|
||||
pack(con, stream);
|
||||
}
|
||||
|
||||
void SimSoundAssetEvent::unpack(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
|
||||
StringTableEntry temp = StringTable->insert(con->unpackNetStringHandleU(stream).getString());
|
||||
if (AssetDatabase.isDeclaredAsset(temp))
|
||||
{
|
||||
AssetPtr<SoundAsset> tempSoundAsset;
|
||||
tempSoundAsset = temp;
|
||||
|
||||
mAsset = temp;
|
||||
}
|
||||
|
||||
if (mAsset->is3D())
|
||||
{
|
||||
if (stream->readFlag()) {
|
||||
QuatF q;
|
||||
q.x = stream->readSignedFloat(SoundRotBits);
|
||||
q.y = stream->readSignedFloat(SoundRotBits);
|
||||
q.z = stream->readSignedFloat(SoundRotBits);
|
||||
F32 value = ((q.x * q.x) + (q.y * q.y) + (q.z * q.z));
|
||||
// #ifdef __linux
|
||||
// Hmm, this should never happen, but it does...
|
||||
if (value > 1.f)
|
||||
value = 1.f;
|
||||
// #endif
|
||||
q.w = mSqrt(1.f - value);
|
||||
if (stream->readFlag())
|
||||
q.w = -q.w;
|
||||
q.setMatrix(&mTransform);
|
||||
}
|
||||
else
|
||||
mTransform.identity();
|
||||
|
||||
Point3F pos;
|
||||
stream->readCompressedPoint(&pos, SoundPosAccuracy);
|
||||
mTransform.setColumn(3, pos);
|
||||
}
|
||||
}
|
||||
|
||||
void SimSoundAssetEvent::process(NetConnection* con)
|
||||
{
|
||||
|
||||
if (mAsset->is3D())
|
||||
SFX->playOnce(mAsset->getSfxProfile(), &mTransform);
|
||||
else
|
||||
SFX->playOnce(mAsset->getSfxProfile());
|
||||
|
||||
}
|
||||
|
||||
Sim2DAudioEvent::Sim2DAudioEvent(SFXProfile *profile)
|
||||
{
|
||||
|
|
@ -321,11 +420,6 @@ void Sim2DAudioEvent::process(NetConnection *)
|
|||
SFX->playOnce( mProfile );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static F32 SoundPosAccuracy = 0.5;
|
||||
static S32 SoundRotBits = 8;
|
||||
|
||||
Sim3DAudioEvent::Sim3DAudioEvent(SFXProfile *profile,const MatrixF* mat)
|
||||
{
|
||||
mProfile = profile;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
#include "core/stream/bitStream.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/SoundAsset.h"
|
||||
|
||||
|
||||
|
||||
class QuitEvent : public SimEvent
|
||||
{
|
||||
|
|
@ -102,6 +105,23 @@ class SimDataBlockEvent : public NetEvent
|
|||
DECLARE_CATEGORY( "Game Networking" );
|
||||
};
|
||||
|
||||
class SimSoundAssetEvent : public NetEvent
|
||||
{
|
||||
private:
|
||||
AssetPtr<SoundAsset> mAsset;
|
||||
MatrixF mTransform;
|
||||
|
||||
public:
|
||||
typedef NetEvent Parent;
|
||||
|
||||
SimSoundAssetEvent(AssetPtr<SoundAsset> asset = NULL, const MatrixF* mat = NULL);
|
||||
void pack(NetConnection*, BitStream* bstream);
|
||||
void write(NetConnection*, BitStream* bstream);
|
||||
void unpack(NetConnection*, BitStream* bstream);
|
||||
void process(NetConnection*);
|
||||
DECLARE_CONOBJECT(SimSoundAssetEvent);
|
||||
};
|
||||
|
||||
class Sim2DAudioEvent: public NetEvent
|
||||
{
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue