mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
357
Engine/source/T3D/sfx/sfx3DWorld.cpp
Normal file
357
Engine/source/T3D/sfx/sfx3DWorld.cpp
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "T3D/sfx/sfx3DWorld.h"
|
||||
#include "T3D/portal.h"
|
||||
#include "T3D/shapeBase.h"
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "sfx/sfxSystem.h"
|
||||
#include "math/mBox.h"
|
||||
#include "core/module.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
|
||||
|
||||
//#define DEBUG_SPEW
|
||||
|
||||
|
||||
MODULE_BEGIN( SFX3D )
|
||||
|
||||
MODULE_INIT_AFTER( Scene )
|
||||
MODULE_SHUTDOWN_BEFORE( Scene )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
if( !Con::getBoolVariable( "$SFX::noSFXWorld", false ) )
|
||||
gSFX3DWorld = new SFX3DWorld;
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
if( gSFX3DWorld )
|
||||
SAFE_DELETE( gSFX3DWorld );
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
|
||||
SFX3DWorld* gSFX3DWorld;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// SFX3DObject.
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFX3DObject::SFX3DObject( SFX3DWorld* world, SceneObject* object )
|
||||
: Parent( world, object )
|
||||
{
|
||||
if( mObject->isOccludingSound() )
|
||||
setFlags( SFXObjectOccluder );
|
||||
if( dynamic_cast< Portal* >( mObject ) )
|
||||
setFlags( SFXObjectPortal );
|
||||
if( object->getSoundAmbience() )
|
||||
setFlags( SFXObjectZone );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DObject::getEarTransform( MatrixF& transform ) const
|
||||
{
|
||||
// If it's not a ShapeBase, just use the object transform.
|
||||
ShapeBase* shape = dynamic_cast< ShapeBase* >( mObject );
|
||||
if ( !shape )
|
||||
{
|
||||
transform = mObject->getTransform();
|
||||
return;
|
||||
}
|
||||
|
||||
// It it's ShapeBase, use the earNode transform if one was defined.
|
||||
// Otherwise, use the camera transform.
|
||||
TSShapeInstance* shapeInstance = shape->getShapeInstance();
|
||||
if ( !shapeInstance )
|
||||
{
|
||||
// Just in case.
|
||||
transform = mObject->getTransform();
|
||||
return;
|
||||
}
|
||||
|
||||
ShapeBaseData* datablock = dynamic_cast< ShapeBaseData* >( shape->getDataBlock() );
|
||||
AssertFatal( datablock, "SFX3DObject::getEarTransform() - shape without ShapeBaseData datablock!" );
|
||||
|
||||
// Get the transform for the ear node.
|
||||
|
||||
const S32 earNode = datablock->earNode;
|
||||
|
||||
if ( earNode != -1 && earNode != datablock->eyeNode )
|
||||
{
|
||||
transform = shape->getTransform();
|
||||
transform *= shapeInstance->mNodeTransforms[ earNode ];
|
||||
}
|
||||
else
|
||||
{
|
||||
GameConnection* connection = dynamic_cast<GameConnection *>(NetConnection::getConnectionToServer());
|
||||
if ( !connection || !connection->getControlCameraTransform( 0.0f, &transform ) )
|
||||
transform = mObject->getTransform();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DObject::getReferenceCenter( F32 position[ 3 ] ) const
|
||||
{
|
||||
MatrixF transform;
|
||||
getEarTransform( transform );
|
||||
Point3F pos = transform.getPosition();
|
||||
|
||||
AssertFatal( TypeTraits< F32 >::MIN <= pos.x && pos.x <= TypeTraits< F32 >::MAX,
|
||||
"SFX3DObject::getReferenceCenter - invalid float in reference center X position" );
|
||||
AssertFatal( TypeTraits< F32 >::MIN <= pos.y && pos.y <= TypeTraits< F32 >::MAX,
|
||||
"SFX3DObject::getReferenceCenter - invalid float in reference center Y position" );
|
||||
AssertFatal( TypeTraits< F32 >::MIN <= pos.z && pos.z <= TypeTraits< F32 >::MAX,
|
||||
"SFX3DObject::getReferenceCenter - invalid float in reference center Z position" );
|
||||
|
||||
dMemcpy( position, &pos.x, sizeof( F32 ) * 3 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DObject::getBounds( F32 minBounds[ 3 ], F32 maxBounds[ 3 ] ) const
|
||||
{
|
||||
getRealBounds( minBounds, maxBounds );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DObject::getRealBounds( F32 minBounds[ 3 ], F32 maxBounds[ 3 ] ) const
|
||||
{
|
||||
const Box3F& worldBox = mObject->getWorldBox();
|
||||
dMemcpy( minBounds, &worldBox.minExtents.x, sizeof( F32 ) * 3 );
|
||||
dMemcpy( maxBounds, &worldBox.maxExtents.x, sizeof( F32 ) * 3 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXAmbience* SFX3DObject::getAmbience() const
|
||||
{
|
||||
return mObject->getSoundAmbience();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFX3DObject::containsPoint( const F32 point[ 3 ] ) const
|
||||
{
|
||||
return mObject->containsPoint( *( reinterpret_cast< const Point3F* >( &point[ 0 ] ) ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
String SFX3DObject::describeSelf() const
|
||||
{
|
||||
return mObject->describeSelf();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// SFX3DWorld.
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFX3DWorld::SFX3DWorld()
|
||||
: Parent( true, TYPEMASK )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFX3DWorld::_isTrackableObject( SceneObject* object ) const
|
||||
{
|
||||
if( !Parent::_isTrackableObject( object ) )
|
||||
return false;
|
||||
|
||||
// We are only interested in occluders, zones, and portals.
|
||||
|
||||
if( object->isOccludingSound() )
|
||||
return true;
|
||||
else if( object->getSoundAmbience() )
|
||||
return true;
|
||||
else if( dynamic_cast< Portal* >( object ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::update()
|
||||
{
|
||||
mSFXWorld.update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::registerObject( SceneObject* object )
|
||||
{
|
||||
if( !_isTrackableObject( object ) )
|
||||
return;
|
||||
|
||||
// Construct a new scene object link.
|
||||
|
||||
SFX3DObject* sfxObject = mChunker.alloc();
|
||||
constructInPlace( sfxObject, this, object );
|
||||
|
||||
// Register it with the SFX world.
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFX3DWorld] Registering %i:%s as 0x%x",
|
||||
object->getId(), object->getClassName(), sfxObject );
|
||||
#endif
|
||||
|
||||
mSFXWorld.registerObject( sfxObject );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::unregisterObject( SceneObject* object )
|
||||
{
|
||||
SFX3DObject* sfxObject = dynamic_cast< SFX3DObject* >( SFX3DObject::getLinkForTracker( this, object ) );
|
||||
if( !sfxObject )
|
||||
return;
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFX3DWorld] Unregistering %i:%s (was 0x%x)",
|
||||
object->getId(), object->getClassName(), sfxObject );
|
||||
#endif
|
||||
|
||||
// Remove the object from the SFX world.
|
||||
|
||||
if( sfxObject->isListener() )
|
||||
mSFXWorld.setReferenceObject( NULL );
|
||||
else
|
||||
mSFXWorld.unregisterObject( sfxObject );
|
||||
|
||||
// Destroy the scene object link.
|
||||
|
||||
destructInPlace( sfxObject );
|
||||
mChunker.free( sfxObject );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::updateObject( SceneObjectLink* object )
|
||||
{
|
||||
SFX3DObject* sfxObject = dynamic_cast< SFX3DObject* >( object );
|
||||
AssertFatal( sfxObject, "SFX3DWorld::updateObject - invalid object type" );
|
||||
|
||||
mSFXWorld.updateObject( sfxObject );
|
||||
|
||||
// If this is the listener object, update its
|
||||
// properties on the SFX system.
|
||||
|
||||
if( sfxObject->isListener() )
|
||||
{
|
||||
SFXListenerProperties listener;
|
||||
sfxObject->getEarTransform( listener.getTransform() );
|
||||
listener.getVelocity() = sfxObject->getObject()->getVelocity();
|
||||
|
||||
SFX->setListener( 0, listener );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SceneObject* SFX3DWorld::getListener() const
|
||||
{
|
||||
SFX3DObject* object = mSFXWorld.getReferenceObject();
|
||||
if( !object )
|
||||
return NULL;
|
||||
|
||||
return object->getObject();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::setListener( SceneObject* object )
|
||||
{
|
||||
SFX3DObject* oldListener = mSFXWorld.getReferenceObject();
|
||||
|
||||
// If it's the same object as our current listener,
|
||||
// return.
|
||||
|
||||
if( oldListener && oldListener->getObject() == object )
|
||||
return;
|
||||
|
||||
// Create a SFX3DObject for the given SceneObject.
|
||||
|
||||
SFX3DObject* sfxObject = NULL;
|
||||
if( object )
|
||||
{
|
||||
AssertFatal( !dynamic_cast< SFX3DObject* >( SFX3DObject::getLinkForTracker( this, object ) ),
|
||||
"SFX3DWorld::setListener - listener objects must not be registered for tracking" );
|
||||
|
||||
sfxObject = mChunker.alloc();
|
||||
constructInPlace( sfxObject, this, object );
|
||||
sfxObject->setFlags( SFXObjectListener );
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
if( object )
|
||||
Platform::outputDebugString( "[SFX3DWorld] Listener is now %i:%s (%s)",
|
||||
object->getId(), object->getClassName(), object->getName() );
|
||||
else
|
||||
Platform::outputDebugString( "[SFX3DWorld] Unsetting listener" );
|
||||
#endif
|
||||
|
||||
// Make this object the center of our SFX world.
|
||||
|
||||
mSFXWorld.setReferenceObject( sfxObject );
|
||||
|
||||
// Remove the tracking links from the old listener so we
|
||||
// don't see further updates on it.
|
||||
|
||||
if( oldListener )
|
||||
{
|
||||
destructInPlace( oldListener );
|
||||
mChunker.free( oldListener );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::notifyChanged( SceneObject* object )
|
||||
{
|
||||
SFX3DObject* sfxObject = dynamic_cast< SFX3DObject* >( SFX3DObject::getLinkForTracker( this, object ) );
|
||||
|
||||
if( !sfxObject && _isTrackableObject( object ) )
|
||||
registerObject( object );
|
||||
else if( sfxObject && !_isTrackableObject( object ) )
|
||||
unregisterObject( object );
|
||||
else if( sfxObject )
|
||||
mSFXWorld.notifyChanged( sfxObject );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFX3DWorld::debugDump()
|
||||
{
|
||||
mSFXWorld.debugDump();
|
||||
}
|
||||
130
Engine/source/T3D/sfx/sfx3DWorld.h
Normal file
130
Engine/source/T3D/sfx/sfx3DWorld.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFX3DWORLD_H_
|
||||
#define _SFX3DWORLD_H_
|
||||
|
||||
#ifndef _SCENETRACKER_H_
|
||||
#include "scene/sceneTracker.h"
|
||||
#endif
|
||||
#ifndef _SFXWORLD_H_
|
||||
#include "sfx/sfxWorld.h"
|
||||
#endif
|
||||
#ifndef _DATACHUNKER_H_
|
||||
#include "core/dataChunker.h"
|
||||
#endif
|
||||
#ifndef _OBJECTTYPES_H_
|
||||
#include "T3D/objectTypes.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SFX3DWorld;
|
||||
|
||||
|
||||
/// SFXObject implementation for the 3D system.
|
||||
class SFX3DObject : public SceneObjectLink, public SFXObject< 3 >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SceneObjectLink Parent;
|
||||
|
||||
///
|
||||
SFX3DObject( SFX3DWorld* world, SceneObject* object );
|
||||
|
||||
/// Return the transform for the ears on this object.
|
||||
void getEarTransform( MatrixF& transform ) const;
|
||||
|
||||
// SFXObject.
|
||||
void getReferenceCenter( F32 position[ 3 ] ) const;
|
||||
void getBounds( F32 minBounds[ 3 ], F32 maxBounds[ 3 ] ) const;
|
||||
void getRealBounds( F32 minBounds[ 3 ], F32 maxBounds[ 3 ] ) const;
|
||||
SFXAmbience* getAmbience() const;
|
||||
bool containsPoint( const F32 point[ 3 ] ) const;
|
||||
String describeSelf() const;
|
||||
};
|
||||
|
||||
|
||||
/// Manager for the 3D sound world.
|
||||
///
|
||||
/// Any SceneObject in the world can be made the current listener. It's ear position (if it's a ShapeBase)
|
||||
/// will then be used as the reference center for attenuating 3D sounds, traversing ambient spaces, etc.
|
||||
///
|
||||
class SFX3DWorld : public SceneTracker
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SceneTracker Parent;
|
||||
typedef SFXWorld< 3, SFX3DObject* > SFXWorldType;
|
||||
|
||||
enum
|
||||
{
|
||||
/// The scene object type mask used to filter out the
|
||||
/// type of objects we are interested in.
|
||||
TYPEMASK = WaterObjectType // Sound ambience.
|
||||
| StaticShapeObjectType // Occlusion and sound ambience.
|
||||
| StaticObjectType // Portals and zones.
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
/// The SFX world tracking system.
|
||||
SFXWorldType mSFXWorld;
|
||||
|
||||
/// Allocator for the SFX3DObject SceneObjectLinks we attach to SceneObjects.
|
||||
FreeListChunker< SFX3DObject > mChunker;
|
||||
|
||||
// SceneTracker.
|
||||
virtual bool _isTrackableObject( SceneObject* object ) const;
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
SFX3DWorld();
|
||||
|
||||
///
|
||||
void update();
|
||||
|
||||
/// Return the current listener object.
|
||||
SceneObject* getListener() const;
|
||||
|
||||
/// Make the given object the current listener object.
|
||||
void setListener( SceneObject* object );
|
||||
|
||||
/// Notify the SFX world that the given object had a (potential) change in its
|
||||
/// sound-related properties.
|
||||
void notifyChanged( SceneObject* object );
|
||||
|
||||
///
|
||||
void debugDump();
|
||||
|
||||
// SceneTracker.
|
||||
virtual void registerObject( SceneObject* object );
|
||||
virtual void unregisterObject( SceneObject* object );
|
||||
virtual void updateObject( SceneObjectLink* object );
|
||||
};
|
||||
|
||||
|
||||
/// The singleton instance of SFX3DWorld, if there is one.
|
||||
extern SFX3DWorld* gSFX3DWorld;
|
||||
|
||||
#endif // !_SFX3DWORLD_H_
|
||||
|
||||
1177
Engine/source/T3D/sfx/sfxEmitter.cpp
Normal file
1177
Engine/source/T3D/sfx/sfxEmitter.cpp
Normal file
File diff suppressed because it is too large
Load diff
243
Engine/source/T3D/sfx/sfxEmitter.h
Normal file
243
Engine/source/T3D/sfx/sfxEmitter.h
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFXEMITTER_H_
|
||||
#define _SFXEMITTER_H_
|
||||
|
||||
#ifndef _SCENEOBJECT_H_
|
||||
#include "scene/sceneObject.h"
|
||||
#endif
|
||||
#ifndef _SFXPROFILE_H_
|
||||
#include "sfx/sfxProfile.h"
|
||||
#endif
|
||||
#ifndef _SFXDESCRIPTION_H_
|
||||
#include "sfx/sfxDescription.h"
|
||||
#endif
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SFXSource;
|
||||
class SFXTrack;
|
||||
|
||||
//RDTODO: make 3D sound emitters yield their source when being culled
|
||||
|
||||
/// The SFXEmitter is used to place 2D or 3D sounds into a
|
||||
/// mission.
|
||||
///
|
||||
/// If the profile is set then the emitter plays that. If the
|
||||
/// profile is null and the filename is set then the local emitter
|
||||
/// options are used.
|
||||
///
|
||||
/// Note that you can call SFXEmitter.play() and SFXEmitter.stop()
|
||||
/// to control playback from script.
|
||||
///
|
||||
class SFXEmitter : public SceneObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SceneObject Parent;
|
||||
|
||||
protected:
|
||||
|
||||
/// Network update masks.
|
||||
enum UpdateMasks
|
||||
{
|
||||
InitialUpdateMask = BIT(0),
|
||||
TransformUpdateMask = BIT(1),
|
||||
DirtyUpdateMask = BIT(2),
|
||||
|
||||
SourcePlayMask = BIT(3),
|
||||
SourceStopMask = BIT(4),
|
||||
|
||||
AllSourceMasks = SourcePlayMask | SourceStopMask,
|
||||
};
|
||||
|
||||
/// Dirty flags used to handle sound property
|
||||
/// updates locally and across the network.
|
||||
enum Dirty
|
||||
{
|
||||
Track = BIT( 0 ),
|
||||
Filename = BIT( 2 ),
|
||||
Volume = BIT( 4 ),
|
||||
IsLooping = BIT( 5 ),
|
||||
Is3D = BIT( 6 ),
|
||||
MinDistance = BIT( 7 ),
|
||||
MaxDistance = BIT( 8 ),
|
||||
ConeInsideAngle = BIT( 9 ),
|
||||
ConeOutsideAngle = BIT( 10 ),
|
||||
ConeOutsideVolume = BIT( 11 ),
|
||||
Transform = BIT( 12 ),
|
||||
SourceGroup = BIT( 13 ),
|
||||
OutsideAmbient = BIT( 14 ),
|
||||
IsStreaming = BIT( 15 ),
|
||||
FadeInTime = BIT( 16 ),
|
||||
FadeOutTime = BIT( 17 ),
|
||||
Pitch = BIT( 18 ),
|
||||
ScatterDistance = BIT( 19 ),
|
||||
TrackOnly = BIT( 20 ),
|
||||
|
||||
AllDirtyMask = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
/// The current dirty flags.
|
||||
BitSet32 mDirty;
|
||||
|
||||
/// The sound source for the emitter.
|
||||
SFXSource *mSource;
|
||||
|
||||
/// The selected track or null if the local
|
||||
/// profile should be used.
|
||||
SFXTrack *mTrack;
|
||||
|
||||
/// Whether to leave sound setup exclusively to the assigned mTrack and not
|
||||
/// override part of the track's description with emitter properties.
|
||||
bool mUseTrackDescriptionOnly;
|
||||
|
||||
/// A local profile object used to coax the
|
||||
/// sound system to play a custom sound.
|
||||
SFXProfile mLocalProfile;
|
||||
|
||||
/// The description used by the local profile.
|
||||
SFXDescription mDescription;
|
||||
|
||||
/// If true playback starts when the emitter
|
||||
/// is added to the scene.
|
||||
bool mPlayOnAdd;
|
||||
|
||||
/// State block for cone rendering in editor.
|
||||
GFXStateBlockRef mRenderSB;
|
||||
|
||||
/// If true, render all emitters when in editor (not only selected one).
|
||||
static bool smRenderEmitters;
|
||||
|
||||
/// Point size for rendering point clouds of emitter cones in editor.
|
||||
/// @todo Currently not implemented.
|
||||
static F32 smRenderPointSize;
|
||||
|
||||
///
|
||||
static F32 smRenderRadialIncrements;
|
||||
|
||||
///
|
||||
static F32 smRenderSweepIncrements;
|
||||
|
||||
///
|
||||
static F32 smRenderPointDistance;
|
||||
|
||||
/// Point color when emitter is playing and in range of listener.
|
||||
static ColorI smRenderColorPlayingInRange;
|
||||
|
||||
/// Point color when emitter is playing but out of range of listern.
|
||||
static ColorI smRenderColorPlayingOutOfRange;
|
||||
|
||||
/// Point color when emitter is not playing but in range of listener.
|
||||
static ColorI smRenderColorStoppedInRange;
|
||||
|
||||
/// Point color when emitter is not playing and not in range of listener.
|
||||
static ColorI smRenderColorStoppedOutOfRange;
|
||||
|
||||
///
|
||||
static ColorI smRenderColorInnerCone;
|
||||
|
||||
///
|
||||
static ColorI smRenderColorOuterCone;
|
||||
|
||||
///
|
||||
static ColorI smRenderColorOutsideVolume;
|
||||
|
||||
///
|
||||
static ColorI smRenderColorRangeSphere;
|
||||
|
||||
/// Helper which reads a flag from the stream and
|
||||
/// updates the mDirty bits.
|
||||
bool _readDirtyFlag( BitStream *stream, U32 flag );
|
||||
|
||||
/// Called when the emitter state has been marked
|
||||
/// dirty and the source needs to be updated.
|
||||
void _update();
|
||||
|
||||
/// Render emitter object in editor.
|
||||
void _renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat );
|
||||
|
||||
/// Render visual feedback for 3D sounds in editor.
|
||||
void _render3DVisualFeedback();
|
||||
|
||||
///
|
||||
void _renderCone( F32 radialIncrements,
|
||||
F32 sweepIncrements,
|
||||
F32 pointDistance,
|
||||
F32 startAngle,
|
||||
F32 stopAngle,
|
||||
F32 startVolume,
|
||||
F32 stopVolume,
|
||||
const ColorI& color );
|
||||
|
||||
/// Return the playback status of the emitter's associated sound.
|
||||
/// This should only be called on either the ghost or the server object if the server is running
|
||||
/// in-process. Otherwise, the method will not return a meaningful value.
|
||||
SFXStatus _getPlaybackStatus() const;
|
||||
|
||||
public:
|
||||
|
||||
SFXEmitter();
|
||||
virtual ~SFXEmitter();
|
||||
|
||||
/// Return the sound source object associated with the emitter.
|
||||
/// @note This will only return a meaningful result when called on ghost objects.
|
||||
SFXSource* getSource() const { return mSource; }
|
||||
|
||||
/// Return true if this object emits a 3D sound.
|
||||
bool is3D() const;
|
||||
|
||||
/// Return true if the SFX system's listener is in range of this emitter.
|
||||
bool isInRange() const;
|
||||
|
||||
/// Sends network event to start playback if
|
||||
/// the emitter source is not already playing.
|
||||
void play();
|
||||
|
||||
/// Sends network event to stop emitter
|
||||
/// playback on all ghosted clients.
|
||||
void stop();
|
||||
|
||||
// SimObject
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
void onStaticModified( const char *slotName, const char *newValue = NULL );
|
||||
U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
||||
void unpackUpdate( NetConnection *conn, BitStream *stream );
|
||||
void setTransform( const MatrixF &mat );
|
||||
void setScale( const VectorF &scale );
|
||||
bool containsPoint( const Point3F& point ) { return false; }
|
||||
void prepRenderImage( SceneRenderState* state );
|
||||
void inspectPostApply();
|
||||
|
||||
static void initPersistFields();
|
||||
static void consoleInit();
|
||||
|
||||
DECLARE_CONOBJECT( SFXEmitter );
|
||||
DECLARE_DESCRIPTION( "A 3D object emitting sound." );
|
||||
DECLARE_CATEGORY( "3D Sound" );
|
||||
};
|
||||
|
||||
#endif // _SFXEMITTER_H_
|
||||
56
Engine/source/T3D/sfx/sfxSpace.cpp
Normal file
56
Engine/source/T3D/sfx/sfxSpace.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/sfx/sfxSpace.h"
|
||||
|
||||
#include "scene/mixin/sceneAmbientSoundObject.impl.h"
|
||||
#include "scene/mixin/scenePolyhedralObject.impl.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1( SFXSpace );
|
||||
|
||||
ConsoleDocClass( SFXSpace,
|
||||
"@brief A volume in space that defines an ambient sound zone.\n\n"
|
||||
|
||||
"@ingroup SFX"
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXSpace::SFXSpace()
|
||||
{
|
||||
mObjScale.set( 10, 10, 10 );
|
||||
mObjBox.set(
|
||||
Point3F( -0.5f, -0.5f, -0.5f ),
|
||||
Point3F( 0.5f, 0.5f, 0.5f )
|
||||
);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXSpace::consoleInit()
|
||||
{
|
||||
// Disable rendering of SFXSpaces by default.
|
||||
getStaticClassRep()->mIsRenderEnabled = false;
|
||||
}
|
||||
63
Engine/source/T3D/sfx/sfxSpace.h
Normal file
63
Engine/source/T3D/sfx/sfxSpace.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFXSPACE_H_
|
||||
#define _SFXSPACE_H_
|
||||
|
||||
#ifndef _SCENESPACE_H_
|
||||
#include "scene/sceneSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SCENEAMBIENTSOUNDOBJECT_H_
|
||||
#include "scene/mixin/sceneAmbientSoundObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SCENEPOLYHEDRALOBJECT_H_
|
||||
#include "scene/mixin/scenePolyhedralObject.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// A convex space that defines a custom ambient sound space.
|
||||
class SFXSpace : public SceneAmbientSoundObject< ScenePolyhedralObject< SceneSpace > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SceneAmbientSoundObject< ScenePolyhedralObject< SceneSpace > > Parent;
|
||||
|
||||
protected:
|
||||
|
||||
// SceneSpace.
|
||||
virtual ColorI _getDefaultEditorSolidColor() const { return ColorI( 244, 135, 18, 45 ); }
|
||||
|
||||
public:
|
||||
|
||||
SFXSpace();
|
||||
|
||||
// SimObject.
|
||||
DECLARE_CONOBJECT( SFXSpace );
|
||||
DECLARE_DESCRIPTION( "A box volume that defines an ambient sound space." );
|
||||
DECLARE_CATEGORY( "3D Sound" );
|
||||
|
||||
static void consoleInit();
|
||||
};
|
||||
|
||||
#endif // !_SFXSPACE_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue