very small sound asset changes

Adds the resolved track stuff from the soundAsset refactor
also uses the refresh asset so changes do not cause a sound to stop working
This commit is contained in:
marauder2k7 2026-05-09 15:54:04 +01:00
parent bcde183786
commit 823054ed86
6 changed files with 459 additions and 260 deletions

View file

@ -59,31 +59,43 @@
IMPLEMENT_CONOBJECT(SoundAsset); IMPLEMENT_CONOBJECT(SoundAsset);
ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, const char*, ASSET_ID_FIELD_PREFIX) IMPLEMENT_STRUCT(AssetPtr<SoundAsset>, AssetPtrSoundAsset, , "")
END_IMPLEMENT_STRUCT
//----------------------------------------------------------------------------- ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, AssetPtr<SoundAsset>, ASSET_ID_FIELD_PREFIX)
ConsoleGetType(TypeSoundAssetPtr) ConsoleGetType(TypeSoundAssetPtr)
{ {
// Fetch asset Id. // Fetch asset Id.
return *((const char**)(dptr)); return (*((AssetPtr<SoundAsset>*)dptr)).getAssetId();
} }
//-----------------------------------------------------------------------------
ConsoleSetType(TypeSoundAssetPtr) ConsoleSetType(TypeSoundAssetPtr)
{ {
// Was a single argument specified? // Was a single argument specified?
if (argc == 1) if (argc == 1)
{ {
// Yes, so fetch field value. // Yes, so fetch field value.
*((const char**)dptr) = StringTable->insert(argv[0]); const char* pFieldValue = argv[0];
// Fetch asset pointer.
AssetPtr<SoundAsset>* pAssetPtr = dynamic_cast<AssetPtr<SoundAsset>*>((AssetPtrBase*)(dptr));
// Is the asset pointer the correct type?
if (pAssetPtr == NULL)
{
Con::warnf("(TypeSoundAssetPtrRefactor) - Failed to set asset Id '%d'.", pFieldValue);
return;
}
// Set asset.
pAssetPtr->setAssetId(pFieldValue);
return; return;
} }
// Warn. // Warn.
Con::warnf("(TypeSoundAssetPtr) - Cannot set multiple args to a single asset."); Con::warnf("(TypeSoundAssetPtrRefactor) - Cannot set multiple args to a single asset.");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -134,7 +146,7 @@ SoundAsset::SoundAsset()
for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++) for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++)
{ {
mSoundFile[i] = StringTable->EmptyString(); mSoundFile[i] = StringTable->EmptyString();
mSoundPath[i] = StringTable->EmptyString(); mSoundResource[i] = NULL;
mPlaylist.mSlots.mTransitionOut[i] = SFXPlayList::TRANSITION_Wait; mPlaylist.mSlots.mTransitionOut[i] = SFXPlayList::TRANSITION_Wait;
mPlaylist.mSlots.mVolumeScale.mValue[i] = 1.f; mPlaylist.mSlots.mVolumeScale.mValue[i] = 1.f;
@ -184,6 +196,9 @@ SoundAsset::SoundAsset()
mPlaylist.mLoopMode = SFXPlayList::LOOP_All; mPlaylist.mLoopMode = SFXPlayList::LOOP_All;
mPlaylist.mActiveSlots = 1; mPlaylist.mActiveSlots = 1;
mResolvedTrack = NULL;
mResolvedDescription = NULL;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -191,8 +206,17 @@ SoundAsset::SoundAsset()
SoundAsset::~SoundAsset() SoundAsset::~SoundAsset()
{ {
if (mPlaylist.isProperlyAdded() && !mPlaylist.isDeleted()) if (mResolvedTrack)
mPlaylist.unregisterObject(); {
if (mResolvedTrack->isProperlyAdded() && !mResolvedTrack->isDeleted())
mResolvedTrack->deleteObject();
}
if (mResolvedDescription)
{
if (mResolvedDescription->isProperlyAdded() && !mResolvedDescription->isDeleted())
mResolvedDescription->deleteObject();
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -203,77 +227,77 @@ void SoundAsset::initPersistFields()
Parent::initPersistFields(); Parent::initPersistFields();
addGroup("SoundSlots"); addGroup("SoundSlots");
addArray("slots", SFXPlayList::SFXPlaylistSettings::NUM_SLOTS); addArray("slots", SFXPlayList::SFXPlaylistSettings::NUM_SLOTS);
addProtectedField("soundFile", TypeAssetLooseFilePath, Offset(mSoundFile, SoundAsset), addProtectedField("soundFile", TypeAssetLooseFilePath, Offset(mSoundFile, SoundAsset),
&_setSoundFile, &defaultProtectedGetFn, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, "Path to the sound file."); &_setSoundFile, &defaultProtectedGetFn, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, "Path to the sound file.");
addField("replay", TYPEID< SFXPlayList::EReplayMode >(), Offset(mPlaylist.mSlots.mReplayMode, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("replay", TYPEID< SFXPlayList::EReplayMode >(), Offset(mPlaylist.mSlots.mReplayMode, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Behavior when an already playing sound is encountered on this slot from a previous cycle.\n" "Behavior when an already playing sound is encountered on this slot from a previous cycle.\n"
"Each slot can have an arbitrary number of sounds playing on it from previous cycles. This field determines " "Each slot can have an arbitrary number of sounds playing on it from previous cycles. This field determines "
"how SFXController will handle these sources."); "how SFXController will handle these sources.");
addField("transitionIn", TYPEID< SFXPlayList::ETransitionMode >(), Offset(mPlaylist.mSlots.mTransitionIn, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("transitionIn", TYPEID< SFXPlayList::ETransitionMode >(), Offset(mPlaylist.mSlots.mTransitionIn, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Behavior when moving into this slot.\n" "Behavior when moving into this slot.\n"
"After the delayIn time has expired (if any), this slot determines what the controller " "After the delayIn time has expired (if any), this slot determines what the controller "
"will do before actually playing the slot."); "will do before actually playing the slot.");
addField("transitionOut", TYPEID< SFXPlayList::ETransitionMode >(), Offset(mPlaylist.mSlots.mTransitionOut, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("transitionOut", TYPEID< SFXPlayList::ETransitionMode >(), Offset(mPlaylist.mSlots.mTransitionOut, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Behavior when moving out of this slot.\n" "Behavior when moving out of this slot.\n"
"After the #detailTimeOut has expired (if any), this slot determines what the controller " "After the #detailTimeOut has expired (if any), this slot determines what the controller "
"will do before moving on to the next slot."); "will do before moving on to the next slot.");
addFieldV("delayTimeIn", TypeRangedF32, Offset(mPlaylist.mSlots.mDelayTimeIn.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("delayTimeIn", TypeRangedF32, Offset(mPlaylist.mSlots.mDelayTimeIn.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Seconds to wait after moving into slot before #transitionIn."); "Seconds to wait after moving into slot before #transitionIn.");
addField("delayTimeInVariance", TypePoint2F, Offset(mPlaylist.mSlots.mDelayTimeIn.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("delayTimeInVariance", TypePoint2F, Offset(mPlaylist.mSlots.mDelayTimeIn.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #delayTimeIn.\n\n" "Bounds on randomization of #delayTimeIn.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("delayTimeOut", TypeRangedF32, Offset(mPlaylist.mSlots.mDelayTimeOut.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("delayTimeOut", TypeRangedF32, Offset(mPlaylist.mSlots.mDelayTimeOut.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Seconds to wait before moving out of slot after #transitionOut."); "Seconds to wait before moving out of slot after #transitionOut.");
addField("delayTimeOutVariance", TypePoint2F, Offset(mPlaylist.mSlots.mDelayTimeOut.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("delayTimeOutVariance", TypePoint2F, Offset(mPlaylist.mSlots.mDelayTimeOut.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #delayTimeOut.\n\n" "Bounds on randomization of #delayTimeOut.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("fadeTimeIn", TypeRangedF32, Offset(mPlaylist.mSlots.mFadeTimeIn.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("fadeTimeIn", TypeRangedF32, Offset(mPlaylist.mSlots.mFadeTimeIn.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Seconds to fade sound in (-1 to use the track's own fadeInTime.)\n" "Seconds to fade sound in (-1 to use the track's own fadeInTime.)\n"
"@see SFXDescription::fadeTimeIn"); "@see SFXDescription::fadeTimeIn");
addField("fadeTimeInVariance", TypePoint2F, Offset(mPlaylist.mSlots.mFadeTimeIn.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("fadeTimeInVariance", TypePoint2F, Offset(mPlaylist.mSlots.mFadeTimeIn.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #fadeInTime.\n\n" "Bounds on randomization of #fadeInTime.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("fadeTimeOut", TypeRangedF32, Offset(mPlaylist.mSlots.mFadeTimeOut.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("fadeTimeOut", TypeRangedF32, Offset(mPlaylist.mSlots.mFadeTimeOut.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Seconds to fade sound out (-1 to use the track's own fadeOutTime.)\n" "Seconds to fade sound out (-1 to use the track's own fadeOutTime.)\n"
"@see SFXDescription::fadeTimeOut"); "@see SFXDescription::fadeTimeOut");
addField("fadeTimeOutVariance", TypePoint2F, Offset(mPlaylist.mSlots.mFadeTimeOut.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("fadeTimeOutVariance", TypePoint2F, Offset(mPlaylist.mSlots.mFadeTimeOut.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #fadeOutTime\n\n" "Bounds on randomization of #fadeOutTime\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("referenceDistance", TypeRangedF32, Offset(mPlaylist.mSlots.mMinDistance.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("referenceDistance", TypeRangedF32, Offset(mPlaylist.mSlots.mMinDistance.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"@c referenceDistance to set for 3D sounds in this slot (<1 to use @c referenceDistance of track's own description).\n" "@c referenceDistance to set for 3D sounds in this slot (<1 to use @c referenceDistance of track's own description).\n"
"@see SFXDescription::referenceDistance"); "@see SFXDescription::referenceDistance");
addField("referenceDistanceVariance", TypePoint2F, Offset(mPlaylist.mSlots.mMinDistance.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("referenceDistanceVariance", TypePoint2F, Offset(mPlaylist.mSlots.mMinDistance.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #referenceDistance.\n\n" "Bounds on randomization of #referenceDistance.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("maxSlotDistance", TypeRangedF32, Offset(mPlaylist.mSlots.mMaxDistance.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("maxSlotDistance", TypeRangedF32, Offset(mPlaylist.mSlots.mMaxDistance.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"@c maxDistance to apply to 3D sounds in this slot (<1 to use @c maxDistance of track's own description).\n" "@c maxDistance to apply to 3D sounds in this slot (<1 to use @c maxDistance of track's own description).\n"
"@see SFXDescription::maxDistance"); "@see SFXDescription::maxDistance");
addField("maxSlotDistanceVariance", TypePoint2F, Offset(mPlaylist.mSlots.mMaxDistance.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("maxSlotDistanceVariance", TypePoint2F, Offset(mPlaylist.mSlots.mMaxDistance.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #maxDistance.\n\n" "Bounds on randomization of #maxDistance.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("volumeScale", TypeRangedF32, Offset(mPlaylist.mSlots.mVolumeScale.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("volumeScale", TypeRangedF32, Offset(mPlaylist.mSlots.mVolumeScale.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Scale factor to apply to volume of sounds played on this list slot.\n" "Scale factor to apply to volume of sounds played on this list slot.\n"
"This value will scale the actual volume level set on the track assigned to the slot, i.e. a value of 0.5 will " "This value will scale the actual volume level set on the track assigned to the slot, i.e. a value of 0.5 will "
"cause the track to play at half-volume."); "cause the track to play at half-volume.");
addField("volumeScaleVariance", TypePoint2F, Offset(mPlaylist.mSlots.mVolumeScale.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("volumeScaleVariance", TypePoint2F, Offset(mPlaylist.mSlots.mVolumeScale.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #volumeScale.\n\n" "Bounds on randomization of #volumeScale.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("pitchScale", TypeRangedF32, Offset(mPlaylist.mSlots.mPitchScale.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("pitchScale", TypeRangedF32, Offset(mPlaylist.mSlots.mPitchScale.mValue, SoundAsset), &CommonValidators::PositiveFloat, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Scale factor to apply to pitch of sounds played on this list slot.\n" "Scale factor to apply to pitch of sounds played on this list slot.\n"
"This value will scale the actual pitch set on the track assigned to the slot, i.e. a value of 0.5 will " "This value will scale the actual pitch set on the track assigned to the slot, i.e. a value of 0.5 will "
"cause the track to play at half its assigned speed."); "cause the track to play at half its assigned speed.");
addField("pitchScaleVariance", TypePoint2F, Offset(mPlaylist.mSlots.mPitchScale.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("pitchScaleVariance", TypePoint2F, Offset(mPlaylist.mSlots.mPitchScale.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Bounds on randomization of #pitchScale.\n\n" "Bounds on randomization of #pitchScale.\n\n"
"@ref SFXPlayList_randomization\n"); "@ref SFXPlayList_randomization\n");
addFieldV("repeatCount", TypeRangedS32, Offset(mPlaylist.mSlots.mRepeatCount, SoundAsset), &CommonValidators::PositiveInt, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addFieldV("repeatCount", TypeRangedS32, Offset(mPlaylist.mSlots.mRepeatCount, SoundAsset), &CommonValidators::PositiveInt, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Number of times to loop this slot."); "Number of times to loop this slot.");
addField("state", TypeSFXStateName, Offset(mPlaylist.mSlots.mState, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("state", TypeSFXStateName, Offset(mPlaylist.mSlots.mState, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"State that must be active for this slot to play.\n\n" "State that must be active for this slot to play.\n\n"
"@ref SFXPlayList_states"); "@ref SFXPlayList_states");
addField("stateMode", TYPEID< SFXPlayList::EStateMode >(), Offset(mPlaylist.mSlots.mStateMode, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, addField("stateMode", TYPEID< SFXPlayList::EStateMode >(), Offset(mPlaylist.mSlots.mStateMode, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
"Behavior when assigned state is deactivated while slot is playing.\n\n" "Behavior when assigned state is deactivated while slot is playing.\n\n"
"@ref SFXPlayList_states"); "@ref SFXPlayList_states");
endArray("slots"); endArray("slots");
endGroup("SoundSlots"); endGroup("SoundSlots");
@ -285,48 +309,79 @@ void SoundAsset::initPersistFields()
// if streaming, a default packet size should be chosen for all sounds. // if streaming, a default packet size should be chosen for all sounds.
addField("isStreaming", TypeBool, Offset(mProfileDesc.mIsStreaming, SoundAsset), "Use streaming."); addField("isStreaming", TypeBool, Offset(mProfileDesc.mIsStreaming, SoundAsset), "Use streaming.");
//....why? //....why?
addFieldV("priority", TypeRangedF32, Offset(mProfileDesc.mPriority, SoundAsset), &CommonValidators::PositiveFloat, "Priority level for virtualization of sounds (1 = base level).\n"
"When there are more concurrently active sounds than supported by the audio mixer, some of the sounds "
"need to be culled. Which sounds are culled first depends primarily on total audibility of individual sounds. "
"However, the priority of invidual sounds may be decreased or decreased through this field.\n\n"
"@ref SFXSound_virtualization");
addField("parameters", TypeSFXParameterName, Offset(mProfileDesc.mParameters, SoundAsset), SFXDescription::MaxNumParameters,
"Names of the parameters to which sources using this description will automatically be linked.\n\n"
"Individual parameters are identified by their #internalName.\n\n"
"@ref SFX_interactive");
addField("useHardware", TypeBool, Offset(mProfileDesc.mUseHardware, SoundAsset), "Use hardware mixing for this sound."); addField("useHardware", TypeBool, Offset(mProfileDesc.mUseHardware, SoundAsset), "Use hardware mixing for this sound.");
addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into."); addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into.");
addField("preload", TypeBool, Offset(mPreload, SoundAsset), "Whether to preload sound data when the profile is added to system."); addField("preload", TypeBool, Offset(mPreload, SoundAsset), "Whether to preload sound data when the profile is added to system.");
endGroup("General Profile"); endGroup("General Profile");
addGroup("Fading"); addGroup("Fading");
addFieldV("fadeInTime", TypeRangedF32, Offset(mProfileDesc.mFadeInTime, SoundAsset), &CommonValidators::PositiveFloat, "Number of seconds to gradually fade in volume from zero when playback starts."); addFieldV("fadeInTime", TypeRangedF32, Offset(mProfileDesc.mFadeInTime, SoundAsset), &CommonValidators::PositiveFloat, "Number of seconds to gradually fade in volume from zero when playback starts.");
addFieldV("fadeOutTime", TypeRangedF32, Offset(mProfileDesc.mFadeOutTime, SoundAsset), &CommonValidators::PositiveFloat, "Number of seconds to gradually fade out volume down to zero when playback is stopped or paused."); addFieldV("fadeOutTime", TypeRangedF32, Offset(mProfileDesc.mFadeOutTime, SoundAsset), &CommonValidators::PositiveFloat, "Number of seconds to gradually fade out volume down to zero when playback is stopped or paused.");
addField("fadeInEase", TypeEaseF, Offset(mProfileDesc.mFadeInEase, SoundAsset), "Easing curve for fade-in transition."); addField("fadeInEase", TypeEaseF, Offset(mProfileDesc.mFadeInEase, SoundAsset), "Easing curve for fade-in transition.");
addField("fadeOutEase", TypeEaseF, Offset(mProfileDesc.mFadeOutEase, SoundAsset), "Easing curve for fade-out transition."); addField("fadeOutEase", TypeEaseF, Offset(mProfileDesc.mFadeOutEase, SoundAsset), "Easing curve for fade-out transition.");
addField("fadeLoops", TypeBool, Offset(mProfileDesc.mFadeLoops, SoundAsset), "Fade each cycle of a loop in and/or out; otherwise only fade-in first cycle."); addField("fadeLoops", TypeBool, Offset(mProfileDesc.mFadeLoops, SoundAsset), "Fade each cycle of a loop in and/or out; otherwise only fade-in first cycle.");
endGroup("Fading"); endGroup("Fading");
addGroup("3D"); addGroup("3D");
addFieldV("minDistance", TypeRangedF32, Offset(mProfileDesc.mMinDistance, SoundAsset), &CommonValidators::PositiveFloat, "Minimum distance for sound."); addFieldV("minDistance", TypeRangedF32, Offset(mProfileDesc.mMinDistance, SoundAsset), &CommonValidators::PositiveFloat, "Minimum distance for sound.");
addFieldV("maxDistance", TypeRangedF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), &CommonValidators::PositiveFloat, "Max distance for sound."); addFieldV("maxDistance", TypeRangedF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), &CommonValidators::PositiveFloat, "Max distance for sound.");
addFieldV("coneInsideAngle", TypeRangedS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), &CommonValidators::S32_PosDegreeRange, "Cone inside angle."); addFieldV("coneInsideAngle", TypeRangedS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), &CommonValidators::S32_PosDegreeRange, "Cone inside angle.");
addFieldV("coneOutsideAngle", TypeRangedS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), &CommonValidators::S32_PosDegreeRange, "Cone outside angle."); addFieldV("coneOutsideAngle", TypeRangedS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), &CommonValidators::S32_PosDegreeRange, "Cone outside angle.");
addFieldV("coneOutsideVolume", TypeRangedF32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), &CommonValidators::NormalizedFloat, "Cone outside volume."); addFieldV("coneOutsideVolume", TypeRangedF32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), &CommonValidators::NormalizedFloat, "Cone outside volume.");
addFieldV("rolloffFactor", TypeRangedF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), &CommonValidators::NegDefaultF32, "Rolloff factor."); addFieldV("rolloffFactor", TypeRangedF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), &CommonValidators::NegDefaultF32, "Rolloff factor.");
addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound."); addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound.");
endGroup("3D"); endGroup("3D");
addGroup("Playlist settings"); addGroup("Playlist settings");
addField("random", TYPEID< SFXPlayList::ERandomMode >(), Offset(mPlaylist.mRandomMode, SoundAsset), "Slot playback order randomization pattern."); addField("random", TYPEID< SFXPlayList::ERandomMode >(), Offset(mPlaylist.mRandomMode, SoundAsset), "Slot playback order randomization pattern.");
addField("loopMode", TYPEID< SFXPlayList::ELoopMode >(), Offset(mPlaylist.mLoopMode, SoundAsset), "Behavior when description has looping enabled."); addField("loopMode", TYPEID< SFXPlayList::ELoopMode >(), Offset(mPlaylist.mLoopMode, SoundAsset), "Behavior when description has looping enabled.");
addFieldV("numSlotsToPlay", TypeRangedS32, Offset(mPlaylist.mNumSlotsToPlay, SoundAsset), &playlistSlotRange, "Number of slots to play."); addFieldV("numSlotsToPlay", TypeRangedS32, Offset(mPlaylist.mNumSlotsToPlay, SoundAsset), &playlistSlotRange, "Number of slots to play.");
addField("trace", TypeBool, Offset(mPlaylist.mTrace, SoundAsset), "Enable/disable execution tracing for this playlist (local only)."); addField("trace", TypeBool, Offset(mPlaylist.mTrace, SoundAsset), "Enable/disable execution tracing for this playlist (local only).");
endGroup("Playlist settings"); endGroup("Playlist settings");
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void SoundAsset::onRemove()
{
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
{
if (mSoundFile[i] == StringTable->EmptyString())
break;
Torque::FS::RemoveChangeNotification(mSoundFile[i], this, &SoundAsset::_onResourceChanged);
}
Parent::onRemove();
}
void SoundAsset::inspectPostApply()
{
Parent::inspectPostApply();
refreshAsset();
}
void SoundAsset::copyTo(SimObject* object) void SoundAsset::copyTo(SimObject* object)
{ {
// Call to parent. // Call to parent.
Parent::copyTo(object); Parent::copyTo(object);
} }
void SoundAsset::initializeAsset(void) void SoundAsset::initializeAsset(void)
{ {
Parent::initializeAsset(); Parent::initializeAsset();
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++) for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
{ {
if (i == 0 && mSoundFile[i] == StringTable->EmptyString()) if (i == 0 && mSoundFile[i] == StringTable->EmptyString())
@ -335,134 +390,59 @@ void SoundAsset::initializeAsset(void)
if (mSoundFile[i] == StringTable->EmptyString()) if (mSoundFile[i] == StringTable->EmptyString())
break; break;
mSoundPath[i] = getOwned() ? expandAssetFilePath(mSoundFile[i]) : mSoundPath[i]; mSoundFile[i] = expandAssetFilePath(mSoundFile[i]);
if (!Torque::FS::IsFile(mSoundPath[i])) if (getOwned())
Con::errorf("SoundAsset::initializeAsset (%s)[%d] could not find %s!", getAssetName(), i, mSoundPath[i]); Torque::FS::AddChangeNotification(mSoundFile[i], this, &SoundAsset::_onResourceChanged);
} }
populateSFXTrack();
} }
void SoundAsset::_onResourceChanged(const Torque::Path &path) void SoundAsset::_onResourceChanged(const Torque::Path& path)
{ {
for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++) for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++)
{ {
if (path != Torque::Path(mSoundPath[i])) if (path != Torque::Path(mSoundFile[i]))
return; return;
} }
refreshAsset(); refreshAsset();
} }
void SoundAsset::onAssetRefresh(void) void SoundAsset::onAssetRefresh(void)
{ {
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++) if (!isProperlyAdded())
{ return;
if (i == 0 && mSoundFile[i] == StringTable->EmptyString())
return;
if (mSoundFile[i] == StringTable->EmptyString()) Parent::onAssetRefresh();
break;
mSoundPath[i] = getOwned() ? expandAssetFilePath(mSoundFile[i]) : mSoundPath[i];
}
populateSFXTrack();
} }
U32 SoundAsset::load() U32 SoundAsset::load()
{ {
if (mLoadedState == AssetErrCode::Ok) return mLoadedState; if (mLoadedState == AssetErrCode::Ok)
return mLoadedState;
// find out how many active slots we have. if (!mResolvedTrack)
U32 numSlots = 0;
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
{ {
if (i == 0 && mSoundPath[i] == StringTable->EmptyString()) if (mIsPlaylist)
return false;
if (mSoundPath[i] == StringTable->EmptyString())
break;
numSlots++;
}
if (mProfileDesc.mSourceGroup == NULL)
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
if (numSlots > 1)
{
mIsPlaylist = true;
for (U32 i = 0; i < numSlots; i++)
{ {
if (mSoundPath[i]) mResolvedTrack = buildPlaylist();
{ }
if (!Torque::FS::IsFile(mSoundPath[i])) else
{ {
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile[i]); mResolvedTrack = buildProfile();
mLoadedState = BadFileReference;
return mLoadedState;
}
else
{
mSFXProfile[i] = new SFXProfile;
mSFXProfile[i]->setDescription(&mProfileDesc);
mSFXProfile[i]->setSoundFileName(mSoundPath[i]);
mSFXProfile[i]->setPreload(mPreload);
mSFXProfile[i]->registerObject(String::ToString("%s_profile_track%d", getAssetName()).c_str());
mPlaylist.mSlots.mTrack[i] = mSFXProfile[i];
}
}
} }
mPlaylist.setDescription(&mProfileDesc); mResolvedTrack->registerObject(String::ToString("%s_profile_track", getAssetName()).c_str());
mPlaylist.registerObject(String::ToString("%s_playlist", getAssetName()).c_str());
}
else
{
if (mSoundPath[0])
{
if (!Torque::FS::IsFile(mSoundPath[0]))
{
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile[0]);
mLoadedState = BadFileReference;
return mLoadedState;
}
else
{
mSFXProfile[0] = new SFXProfile;
mSFXProfile[0]->setDescription(&mProfileDesc);
mSFXProfile[0]->setSoundFileName(mSoundPath[0]);
mSFXProfile[0]->setPreload(mPreload);
mSFXProfile[0]->registerObject(String::ToString("%s_profile", getAssetName()).c_str());
}
}
} }
mChangeSignal.trigger();
mLoadedState = Ok; mLoadedState = Ok;
return mLoadedState; return mLoadedState;
} }
bool SoundAsset::_setSoundFile(void* object, const char* index, const char* data)
{
SoundAsset* pData = static_cast<SoundAsset*>(object);
U32 id = 0;
if (index)
id = dAtoui(index);
// Update.
pData->mSoundFile[id] = StringTable->insert(data, true);
if (pData->mSoundFile[id] == StringTable->EmptyString())
pData->mSoundPath[id] = StringTable->EmptyString();
// Refresh the asset.
pData->refreshAsset();
return true;
}
StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName) StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName)
{ {
if (fileName == StringTable->EmptyString()) if (fileName == StringTable->EmptyString())
@ -479,7 +459,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName)
SoundAsset* soundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]); SoundAsset* soundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]);
if (soundAsset) if (soundAsset)
{ {
if (soundAsset->getSoundPath() == fileName) if (soundAsset->getSoundFile() == fileName)
soundAssetId = soundAsset->getAssetId(); soundAssetId = soundAsset->getAssetId();
AssetDatabase.releaseAsset(query.mAssetList[i]); AssetDatabase.releaseAsset(query.mAssetList[i]);
@ -506,7 +486,7 @@ U32 SoundAsset::getAssetById(StringTableEntry assetId, AssetPtr<SoundAsset>* sou
} }
} }
U32 SoundAsset::getAssetByFileName(StringTableEntry fileName, AssetPtr<SoundAsset>* soundAsset) U32 SoundAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<SoundAsset>* soundAsset)
{ {
AssetQuery query; AssetQuery query;
U32 foundAssetcount = AssetDatabase.findAssetType(&query, "SoundAsset"); U32 foundAssetcount = AssetDatabase.findAssetType(&query, "SoundAsset");
@ -521,7 +501,7 @@ U32 SoundAsset::getAssetByFileName(StringTableEntry fileName, AssetPtr<SoundAsse
for (U32 i = 0; i < foundAssetcount; i++) for (U32 i = 0; i < foundAssetcount; i++)
{ {
SoundAsset* tSoundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]); SoundAsset* tSoundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]);
if (tSoundAsset && tSoundAsset->getSoundPath() == fileName) if (tSoundAsset && tSoundAsset->getSoundFile() == fileName)
{ {
soundAsset->setAssetId(query.mAssetList[i]); soundAsset->setAssetId(query.mAssetList[i]);
AssetDatabase.releaseAsset(query.mAssetList[i]); AssetDatabase.releaseAsset(query.mAssetList[i]);
@ -535,9 +515,172 @@ U32 SoundAsset::getAssetByFileName(StringTableEntry fileName, AssetPtr<SoundAsse
return AssetErrCode::Failed; return AssetErrCode::Failed;
} }
void SoundAsset::buildDescription()
{
if (!mResolvedDescription)
{
mResolvedDescription = new SFXDescription;
// calls on add which should validate the description. but do it on mProfileDesc before applying values anyway.
mResolvedDescription->registerObject(String::ToString("%s_profile_description", getAssetName()).c_str());
}
mProfileDesc.validate();
mResolvedDescription->mPitch = mProfileDesc.mPitch;
mResolvedDescription->mVolume = mProfileDesc.mVolume;
mResolvedDescription->mIs3D = mProfileDesc.mIs3D;
mResolvedDescription->mIsLooping = mProfileDesc.mIsLooping;
mResolvedDescription->mIsStreaming = mProfileDesc.mIsStreaming;
mResolvedDescription->mUseHardware = mProfileDesc.mUseHardware;
mResolvedDescription->mMinDistance = mProfileDesc.mMinDistance;
mResolvedDescription->mMaxDistance = mProfileDesc.mMaxDistance;
mResolvedDescription->mConeInsideAngle = mProfileDesc.mConeInsideAngle;
mResolvedDescription->mConeOutsideAngle = mProfileDesc.mConeOutsideAngle;
mResolvedDescription->mConeOutsideVolume = mProfileDesc.mConeOutsideVolume;
mResolvedDescription->mRolloffFactor = mProfileDesc.mRolloffFactor;
mResolvedDescription->mFadeInTime = mProfileDesc.mFadeInTime;
mResolvedDescription->mFadeOutTime = mProfileDesc.mFadeOutTime;
mResolvedDescription->mFadeLoops = mProfileDesc.mFadeLoops;
mResolvedDescription->mScatterDistance = mProfileDesc.mScatterDistance;
mResolvedDescription->mStreamPacketSize = mProfileDesc.mStreamPacketSize;
mResolvedDescription->mStreamReadAhead = mProfileDesc.mStreamReadAhead;
mResolvedDescription->mPriority = mProfileDesc.mPriority;
mResolvedDescription->mSourceGroup = mProfileDesc.mSourceGroup;
mResolvedDescription->mFadeInEase = mProfileDesc.mFadeInEase;
mResolvedDescription->mSourceGroup = mProfileDesc.mSourceGroup;
}
SFXProfile* SoundAsset::buildProfile()
{
SFXProfile* profile = new SFXProfile(mResolvedDescription, mSoundFile[0], mPreload);
mSoundResource[0] = profile->getResource();
return profile;
}
//-----------------------------------------------------------------------------
// BUILD PLAYLIST
//-----------------------------------------------------------------------------
SFXPlayList* SoundAsset::buildPlaylist()
{
SFXPlayList* pl = new SFXPlayList();
pl->mRandomMode = mPlaylist.mRandomMode;
pl->mLoopMode = mPlaylist.mLoopMode;
pl->mNumSlotsToPlay = mPlaylist.mNumSlotsToPlay;
pl->mTrace = mPlaylist.mTrace;
pl->mSlots = mPlaylist.mSlots;
// Build child tracks for each valid slot
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; ++i)
{
if (mSoundFile[i] == StringTable->EmptyString())
continue;
// Build child SFXProfile
SFXProfile* child = new SFXProfile(mResolvedDescription, mSoundFile[i], mPreload);
mSoundResource[i] = child->getResource();
pl->mSlots.mTrack[i] = child;
}
return pl;
}
void SoundAsset::populateSFXTrack(void)
{
U32 count = 0;
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; ++i)
{
if (mSoundFile[i] != StringTable->EmptyString())
{
if (!Torque::FS::IsFile(mSoundFile[i]))
{
mLoadedState = AssetErrCode::BadFileReference;
return;
}
++count;
}
}
mIsPlaylist = (count > 1);
buildDescription();
if (mResolvedTrack && mResolvedDescription)
{
if (SFX)
SFX->notifyDescriptionChanged(mResolvedDescription);
return;
}
mResolvedTrack = NULL;
// reset loaded state.
mLoadedState = AssetErrCode::NotLoaded;
}
void SoundAsset::setSoundFile(StringTableEntry pSoundFile, U32 slot)
{
AssertFatal(pSoundFile != NULL, "Cannot use a NULL sound file.");
pSoundFile = StringTable->insert(pSoundFile);
if (pSoundFile == mSoundFile[slot])
return;
mSoundFile[slot] = getOwned() ? expandAssetFilePath(pSoundFile) : StringTable->insert(pSoundFile);;
refreshAsset();
}
void SoundAsset::onTamlPreWrite(void)
{
// Call parent.
Parent::onTamlPreWrite();
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
{
if (mSoundFile[i] == StringTable->EmptyString())
break;
mSoundFile[i] = collapseAssetFilePath(mSoundFile[i]);
}
}
void SoundAsset::onTamlPostWrite(void)
{
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
{
if (mSoundFile[i] == StringTable->EmptyString())
break;
mSoundFile[i] = expandAssetFilePath(mSoundFile[i]);
}
}
void SoundAsset::onTamlCustomWrite(TamlCustomNodes& customNodes)
{
// Debug Profiling.
PROFILE_SCOPE(SoundAsset_OnTamlCustomWrite);
// Call parent.
Parent::onTamlCustomRead(customNodes);
}
void SoundAsset::onTamlCustomRead(const TamlCustomNodes& customNodes)
{
// Debug Profiling.
PROFILE_SCOPE(SoundAsset_OnTamlCustomRead);
// Call parent.
Parent::onTamlCustomRead(customNodes);
}
DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "") DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "")
{ {
return object->getSoundPath(); return object->getSoundFile();
} }
DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zero), DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zero),
@ -549,12 +692,18 @@ DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zer
MatrixF transform; MatrixF transform;
transform.setPosition(position); transform.setPosition(position);
SFXSource* source; SFXSource* source;
if (position == Point3F::Zero || !object->is3D()) if (position == Point3F::Zero && !object->is3D())
{
source = SFX->playOnce(object->getSFXTrack()); source = SFX->playOnce(object->getSFXTrack());
}
else else
{
if (position == Point3F::Zero)
transform = SFX->getListener().getTransform();
source = SFX->playOnce(object->getSFXTrack(), &transform, NULL, -1); source = SFX->playOnce(object->getSFXTrack(), &transform, NULL, -1);
}
if(source) if (source)
return source->getId(); return source->getId();
else else
return 0; return 0;
@ -585,7 +734,7 @@ void GuiInspectorTypeSoundAssetPtr::consoleInit()
ConsoleBaseType::getType(TypeSoundAssetPtr)->setInspectorFieldType("GuiInspectorTypeSoundAssetPtr"); ConsoleBaseType::getType(TypeSoundAssetPtr)->setInspectorFieldType("GuiInspectorTypeSoundAssetPtr");
} }
GuiControl * GuiInspectorTypeSoundAssetPtr::constructEditControl() GuiControl* GuiInspectorTypeSoundAssetPtr::constructEditControl()
{ {
// Create base filename edit controls // Create base filename edit controls
GuiControl* retCtrl = Parent::constructEditControl(); GuiControl* retCtrl = Parent::constructEditControl();

View file

@ -87,21 +87,12 @@ class SoundAsset : public AssetBase
typedef AssetPtr<SoundAsset> ConcreteAssetPtr; typedef AssetPtr<SoundAsset> ConcreteAssetPtr;
protected: protected:
StringTableEntry mSoundFile[SFXPlayList::SFXPlaylistSettings::NUM_SLOTS];
StringTableEntry mSoundPath[SFXPlayList::SFXPlaylistSettings::NUM_SLOTS];
SimObjectPtr<SFXProfile> mSFXProfile[SFXPlayList::SFXPlaylistSettings::NUM_SLOTS];
SFXDescription mProfileDesc;
SFXPlayList mPlaylist;
// subtitles
StringTableEntry mSubtitleString;
bool mPreload;
bool mIsPlaylist;
//SFXPlayList::SlotData mSlots; //SFXPlayList::SlotData mSlots;
/*These will be needed in the refactor! /*These will be needed in the refactor!
Resource<SFXResource> mSoundResource; Resource<SFXResource> mSoundResource;
// SFXDesctriptions, some off these will be removed // SFXDesctriptions, some off these will be removed
F32 mPitchAdjust; F32 mPitchAdjust;
@ -121,9 +112,6 @@ protected:
F32 mPriority; F32 mPriority;
*/ */
typedef Signal<void()> SoundAssetChanged;
SoundAssetChanged mChangeSignal;
public: public:
enum SoundAssetErrCode enum SoundAssetErrCode
{ {
@ -142,41 +130,79 @@ public:
if (errCode > SoundAssetErrCode::Extended) return "undefined error"; if (errCode > SoundAssetErrCode::Extended) return "undefined error";
return mErrCodeStrings[errCode - Parent::Extended]; return mErrCodeStrings[errCode - Parent::Extended];
}; };
private:
StringTableEntry mSoundFile[SFXPlayList::SFXPlaylistSettings::NUM_SLOTS];
Resource<SFXResource> mSoundResource[SFXPlayList::SFXPlaylistSettings::NUM_SLOTS];
SFXDescription mProfileDesc;
SFXPlayList mPlaylist;
// subtitles
StringTableEntry mSubtitleString;
bool mPreload;
bool mIsPlaylist;
SFXTrack* mResolvedTrack;
SFXDescription* mResolvedDescription;
public:
SoundAsset(); SoundAsset();
virtual ~SoundAsset(); virtual ~SoundAsset();
/// Engine. /// Engine.
static void initPersistFields(); static void initPersistFields();
void onRemove() override;
void inspectPostApply() override;
void copyTo(SimObject* object) override; void copyTo(SimObject* object) override;
//SFXResource* getSound() { return mSoundResource; } //SFXResource* getSound() { return mSoundResource; }
Resource<SFXResource> getSoundResource(const U32 slotId = 0) { load(); return mSFXProfile[slotId]->getResource(); } Resource<SFXResource> getSoundResource(const U32 slotId = 0) { load(); return mSoundResource[slotId]; }
/// Declare Console Object. /// Declare Console Object.
DECLARE_CONOBJECT(SoundAsset); DECLARE_CONOBJECT(SoundAsset);
static bool _setSoundFile(void* object, const char* index, const char* data); // asset Base load
U32 load() override; U32 load() override;
inline StringTableEntry getSoundPath(const U32 slotId = 0) const { return mSoundPath[slotId]; };
SFXProfile* getSfxProfile(const U32 slotId = 0) { return mSFXProfile[slotId]; } void setSoundFile(StringTableEntry pSoundFile, U32 slot = 0);
SFXPlayList* getSfxPlaylist() { return &mPlaylist; } inline StringTableEntry getSoundFile(U32 slot = 0) { return mSoundFile[slot]; }
SFXTrack* getSFXTrack() { load(); return mIsPlaylist ? dynamic_cast<SFXTrack*>(&mPlaylist) : dynamic_cast<SFXTrack*>(mSFXProfile[0].getPointer()); } inline StringTableEntry getRelativeSoundFile(U32 slot = 0) { return collapseAssetFilePath(mSoundFile[slot]); }
SFXDescription* getSfxDescription() { return &mProfileDesc; }
bool isPlaylist(){ return mIsPlaylist; } SFXTrack* getSFXTrack() { load(); return mResolvedTrack; }
SFXDescription* getSfxDescription() { return mResolvedDescription ? mResolvedDescription : &mProfileDesc; }
bool isPlaylist() { return mIsPlaylist; }
bool isLoop() { return mProfileDesc.mIsLooping; } bool isLoop() { return mProfileDesc.mIsLooping; }
bool is3D() { return mProfileDesc.mIs3D; } bool is3D() { return mProfileDesc.mIs3D; }
static StringTableEntry getAssetIdByFileName(StringTableEntry fileName); static StringTableEntry getAssetIdByFileName(StringTableEntry fileName);
static U32 getAssetById(StringTableEntry assetId, AssetPtr<SoundAsset>* materialAsset); static U32 getAssetById(StringTableEntry assetId, AssetPtr<SoundAsset>* materialAsset);
static U32 getAssetByFileName(StringTableEntry fileName, AssetPtr<SoundAsset>* matAsset); static U32 getAssetByFilename(StringTableEntry fileName, AssetPtr<SoundAsset>* matAsset);
void buildDescription();
SFXProfile* buildProfile();
SFXPlayList* buildPlaylist();
void populateSFXTrack(void);
protected: protected:
void initializeAsset(void) override; // Asset Base callback
void _onResourceChanged(const Torque::Path & path); void initializeAsset(void) override;
void onAssetRefresh(void) override; void _onResourceChanged(const Torque::Path& path);
void onAssetRefresh(void) override;
/// Taml callbacks.
void onTamlPreWrite(void) override;
void onTamlPostWrite(void) override;
void onTamlCustomWrite(TamlCustomNodes& customNodes) override;
void onTamlCustomRead(const TamlCustomNodes& customNodes) override;
protected:
static bool _setSoundFile(void* obj, const char* index, const char* data) { U32 idx = 0; if (index) idx = dAtoi(index); static_cast<SoundAsset*>(obj)->setSoundFile(data, idx); return false; }
}; };
DECLARE_STRUCT(AssetPtr<SoundAsset>)
DefineConsoleType(TypeSoundAssetPtr, SoundAsset) DefineConsoleType(TypeSoundAssetPtr, SoundAsset)
DefineConsoleType(TypeSoundAssetId, String) DefineConsoleType(TypeSoundAssetId, String)
@ -272,8 +298,8 @@ public: \
\ \
const StringTableEntry get##name() const\ const StringTableEntry get##name() const\
{\ {\
if (m##name##Asset && (m##name##Asset->getSoundPath() != StringTable->EmptyString()))\ if (m##name##Asset && (m##name##Asset->getSoundFile() != StringTable->EmptyString()))\
return m##name##Asset->getSoundPath();\ return m##name##Asset->getSoundFile();\
else if (m##name##AssetId != StringTable->EmptyString())\ else if (m##name##AssetId != StringTable->EmptyString())\
return m##name##AssetId;\ return m##name##AssetId;\
else if (m##name##Name != StringTable->EmptyString())\ else if (m##name##Name != StringTable->EmptyString())\
@ -467,8 +493,8 @@ public: \
\ \
const StringTableEntry get##name(const U32& index) const\ const StringTableEntry get##name(const U32& index) const\
{\ {\
if (m##name##Asset[index] && (m##name##Asset[index]->getSoundPath() != StringTable->EmptyString()))\ if (m##name##Asset[index] && (m##name##Asset[index]->getSoundFile() != StringTable->EmptyString()))\
return m##name##Asset[index]->getSoundPath();\ return m##name##Asset[index]->getSoundFile();\
else if (m##name##AssetId[index] != StringTable->EmptyString())\ else if (m##name##AssetId[index] != StringTable->EmptyString())\
return m##name##AssetId[index];\ return m##name##AssetId[index];\
else if (m##name##Name[index] != StringTable->EmptyString())\ else if (m##name##Name[index] != StringTable->EmptyString())\

View file

@ -3309,30 +3309,19 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem)
StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str()); StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
String soundFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension(); String soundFileName = assetItem->filePath.getFullFileName();
String assetPath = targetPath + "/" + soundFileName; String assetPath = "@" + soundFileName;
String tamlPath = targetPath + "/" + assetName + ".asset.taml"; String tamlPath = targetPath + "/" + assetName + ".asset.taml";
String originalPath = assetItem->filePath.getFullPath().c_str(); String originalPath = assetItem->filePath.getFullPath().c_str();
char qualifiedFromFile[2048];
char qualifiedToFile[2048];
#ifndef TORQUE_SECURE_VFS
Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
#else
dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile));
#endif
newAsset->setAssetName(assetName); newAsset->setAssetName(assetName);
newAsset->_setSoundFile(newAsset, "0", soundFileName.c_str()); newAsset->setSoundFile(assetPath.c_str());
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
//file path for reimporting support later //file path for reimporting support later
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile)) if (!isReimport)
{ {
newAsset->setDataField(StringTable->insert("originalFilePath"), NULL, qualifiedFromFile); newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, originalPath.c_str());
} }
Taml tamlWriter; Taml tamlWriter;
@ -3345,18 +3334,6 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem)
return ""; return "";
} }
if (!isReimport)
{
bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile);
if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport))
{
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
activityLog.push_back(importLogBuffer);
return "";
}
}
return tamlPath; return tamlPath;
} }

View file

@ -820,7 +820,7 @@ void SFXEmitter::_update()
// is toggled on a local profile sound. It makes the // is toggled on a local profile sound. It makes the
// editor feel responsive and that things are working. // editor feel responsive and that things are working.
if( gEditingMission && if( gEditingMission &&
(SoundAsset::getAssetErrCode(mSoundAsset) || !mSoundAsset->getSfxProfile()) && (SoundAsset::getAssetErrCode(mSoundAsset) || !mSoundAsset->getSFXTrack()) &&
mPlayOnAdd && mPlayOnAdd &&
mDirty.test( IsLooping ) ) mDirty.test( IsLooping ) )
prevState = SFXStatusPlaying; prevState = SFXStatusPlaying;

View file

@ -1888,13 +1888,13 @@ DefineEngineFunction( sfxPlayOnce, S32, (StringTableEntry assetId, const char* a
if (String::isEmpty(arg0) || !tempSoundAsset->is3D()) if (String::isEmpty(arg0) || !tempSoundAsset->is3D())
{ {
source = SFX->playOnce(tempSoundAsset->getSfxProfile()); source = SFX->playOnce(tempSoundAsset->getSFXTrack());
} }
else else
{ {
MatrixF transform; MatrixF transform;
transform.set(EulerF(0, 0, 0), Point3F(dAtof(arg0), dAtof(arg1), dAtof(arg2))); transform.set(EulerF(0, 0, 0), Point3F(dAtof(arg0), dAtof(arg1), dAtof(arg2)));
source = SFX->playOnce(tempSoundAsset->getSfxProfile(), &transform, NULL, dAtof(arg3)); source = SFX->playOnce(tempSoundAsset->getSFXTrack(), &transform, NULL, dAtof(arg3));
} }
} }
else else

View file

@ -12,6 +12,53 @@ function SoundAsset::onChanged(%this)
if (isObject($PreviewSoundSource)) if (isObject($PreviewSoundSource))
sfxStop($PreviewSoundSource); sfxStop($PreviewSoundSource);
} }
function SoundAsset::onShowActionMenu(%this)
{
GenericAsset::onShowActionMenu(%this);
%assetId = %this.getAssetId();
EditAssetPopup.objectData = %assetId;
EditAssetPopup.objectType = AssetDatabase.getAssetType(%assetId);
EditAssetPopup.reloadItems();
EditAssetPopup.showPopup(Canvas);
}
function SoundAsset::onEditProperties(%this)
{
Canvas.pushDialog(AssetBrowser_editAsset);
AssetBrowser_editAssetWindow.text = "Asset Properties - " @ %this.getAssetId();
AssetEditInspector.tempAsset = %this.deepClone();
AssetEditInspector.inspect(%this);
AssetBrowser_editAsset.editedObjectData = %this.getAssetId();
AssetBrowser_editAsset.editedObject = %this;
AssetBrowser_editAsset.editedObjectType = AssetDatabase.getAssetType(%this.getAssetId());
//remove some of the groups we don't need:
for(%i=0; %i < AssetEditInspector.getCount(); %i++)
{
%caption = AssetEditInspector.getObject(%i).caption;
if(%caption $= "Ungrouped" || %caption $= "Object" || %caption $= "Editing"
|| %caption $= "Persistence" || %caption $= "Dynamic Fields")
{
AssetEditInspector.remove(AssetEditInspector.getObject(%i));
%i--;
}
}
}
//Called when the AssetType has it's properties saved from the onEditProperties process
function SoundAsset::onSaveProperties(%this)
{
%this.refreshAsset();
}
function SoundAsset::buildBrowserElement(%this, %previewData) function SoundAsset::buildBrowserElement(%this, %previewData)
{ {