2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-03-17 02:13:02 +00:00

refactor: introduce subasset loading

This commit is contained in:
Jan Laupetin
2026-02-05 16:25:00 +00:00
parent 1be411b371
commit aa47ffa629
255 changed files with 1668 additions and 3132 deletions

View File

@@ -16,7 +16,7 @@ IgnoredAssetLookup::IgnoredAssetLookup(const AssetList& assetList)
}
}
bool IgnoredAssetLookup::IsAssetIgnored(asset_type_t assetType, const std::string& name) const
bool IgnoredAssetLookup::IsAssetIgnored(const asset_type_t assetType, const std::string& name) const
{
const auto entries = m_ignored_asset_lookup.equal_range(name);
@@ -66,7 +66,8 @@ std::unique_ptr<XAssetInfoGeneric> GenericAssetRegistration::CreateXAssetInfo()
AssetCreationContext::AssetCreationContext(Zone& zone, const AssetCreatorCollection* creators, const IgnoredAssetLookup* ignoredAssetLookup)
: ZoneAssetCreationStateContainer(zone),
m_zone(zone),
m_forced_asset_pools(ZoneAssetPools::CreateForGame(zone.m_game_id, &zone, zone.m_priority)),
m_forced_asset_pools(std::make_unique<ZoneAssetPools>(zone, zone.m_priority)),
m_sub_asset_pools(IGame::GetGameById(zone.m_game_id)->GetSubAssetTypeCount()),
m_creators(creators),
m_ignored_asset_lookup(ignoredAssetLookup),
m_forced_load_depth(0u)
@@ -85,10 +86,27 @@ XAssetInfoGeneric* AssetCreationContext::AddAssetGeneric(GenericAssetRegistratio
if (m_forced_load_depth > 0)
addedAsset = m_forced_asset_pools->AddAsset(std::move(xAssetInfo));
else
addedAsset = m_zone.m_pools->AddAsset(std::move(xAssetInfo));
addedAsset = m_zone.m_pools.AddAsset(std::move(xAssetInfo));
if (addedAsset == nullptr)
con::error(R"(Failed to add asset of type "{}" to pool: "{}")", *IGame::GetGameById(m_zone.m_game_id)->GetAssetTypeName(assetType), pAssetName);
return addedAsset;
}
XAssetInfoGeneric* AssetCreationContext::AddSubAssetGeneric(GenericAssetRegistration registration) const
{
auto xAssetInfo = registration.CreateXAssetInfo();
xAssetInfo->m_zone = &m_zone;
const auto subAssetType = xAssetInfo->m_type;
const auto* pAssetName = xAssetInfo->m_name.c_str();
auto* addedAsset = m_sub_asset_pools[subAssetType]->AddAsset(std::move(xAssetInfo));
if (addedAsset == nullptr)
con::error(R"(Failed to add sub asset of type "{}" to pool: "{}")", *IGame::GetGameById(m_zone.m_game_id)->GetAssetTypeName(subAssetType), pAssetName);
return addedAsset;
}
@@ -103,9 +121,9 @@ XAssetInfoGeneric* AssetCreationContext::LoadDefaultAssetDependency(const asset_
return nullptr;
}
XAssetInfoGeneric* AssetCreationContext::LoadDependencyGeneric(const asset_type_t assetType, const std::string& assetName, bool required)
XAssetInfoGeneric* AssetCreationContext::LoadDependencyGeneric(const asset_type_t assetType, const std::string& assetName, const bool required)
{
auto* alreadyLoadedAsset = m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName);
auto* alreadyLoadedAsset = m_zone.m_pools.GetAssetOrAssetReference(assetType, assetName);
if (alreadyLoadedAsset)
return alreadyLoadedAsset;
@@ -138,9 +156,28 @@ XAssetInfoGeneric* AssetCreationContext::LoadDependencyGeneric(const asset_type_
return nullptr;
}
XAssetInfoGeneric* AssetCreationContext::LoadSubAssetGeneric(const asset_type_t subAssetType, const std::string& assetName)
{
assert(subAssetType < m_sub_asset_pools.size());
auto* alreadyLoadedSubAsset = m_sub_asset_pools[subAssetType]->GetAsset(assetName);
if (alreadyLoadedSubAsset)
return alreadyLoadedSubAsset;
const auto result = m_creators->CreateSubAsset(subAssetType, assetName, *this);
if (result.HasTakenAction())
{
if (!result.HasFailed())
return result.GetAssetInfo();
con::error(R"(Could not load sub asset "{}" of type "{}")", assetName, *IGame::GetGameById(m_zone.m_game_id)->GetSubAssetTypeName(subAssetType));
}
return nullptr;
}
IndirectAssetReference AssetCreationContext::LoadIndirectAssetReferenceGeneric(const asset_type_t assetType, const std::string& assetName)
{
const auto* alreadyLoadedAsset = m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName);
const auto* alreadyLoadedAsset = m_zone.m_pools.GetAssetOrAssetReference(assetType, assetName);
if (alreadyLoadedAsset)
return IndirectAssetReference(assetType, assetName);
@@ -158,7 +195,7 @@ IndirectAssetReference AssetCreationContext::LoadIndirectAssetReferenceGeneric(c
XAssetInfoGeneric* AssetCreationContext::ForceLoadDependencyGeneric(const asset_type_t assetType, const std::string& assetName)
{
auto* alreadyLoadedAsset = m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName);
auto* alreadyLoadedAsset = m_zone.m_pools.GetAssetOrAssetReference(assetType, assetName);
if (alreadyLoadedAsset && !alreadyLoadedAsset->IsReference())
return alreadyLoadedAsset;
alreadyLoadedAsset = m_forced_asset_pools->GetAssetOrAssetReference(assetType, assetName);

View File

@@ -30,36 +30,47 @@ class AssetCreationContext : public ZoneAssetCreationStateContainer
public:
AssetCreationContext(Zone& zone, const AssetCreatorCollection* creators, const IgnoredAssetLookup* ignoredAssetLookup);
template<typename AssetType> XAssetInfo<typename AssetType::Type>* AddAsset(AssetRegistration<AssetType> registration)
template<AssetDefinition Asset_t> XAssetInfo<typename Asset_t::Type>* AddAsset(AssetRegistration<Asset_t> registration)
{
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
return static_cast<XAssetInfo<typename AssetType::Type>*>(AddAssetGeneric(std::move(registration)));
return static_cast<XAssetInfo<typename Asset_t::Type>*>(AddAssetGeneric(std::move(registration)));
}
template<typename AssetType> XAssetInfo<typename AssetType::Type>* AddAsset(std::string assetName, typename AssetType::Type* asset)
template<AssetDefinition Asset_t> XAssetInfo<typename Asset_t::Type>* AddAsset(std::string assetName, Asset_t::Type* asset)
{
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
return static_cast<XAssetInfo<typename AssetType::Type>*>(AddAssetGeneric(AssetRegistration<AssetType>(std::move(assetName), asset)));
return static_cast<XAssetInfo<typename Asset_t::Type>*>(AddAssetGeneric(AssetRegistration<Asset_t>(std::move(assetName), asset)));
}
XAssetInfoGeneric* AddAssetGeneric(GenericAssetRegistration registration) const;
template<typename AssetType> XAssetInfo<typename AssetType::Type>* LoadDependency(const std::string& assetName)
template<SubAssetDefinition SubAsset_t> XAssetInfo<typename SubAsset_t::Type>* AddSubAsset(AssetRegistration<SubAsset_t> registration)
{
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
return static_cast<XAssetInfo<typename SubAsset_t::Type>*>(AddSubAssetGeneric(std::move(registration)));
}
return static_cast<XAssetInfo<typename AssetType::Type>*>(LoadDependencyGeneric(AssetType::EnumEntry, assetName));
template<SubAssetDefinition SubAsset_t> XAssetInfo<typename SubAsset_t::Type>* AddSubAsset(std::string assetName, SubAsset_t::Type* asset)
{
return static_cast<XAssetInfo<typename SubAsset_t::Type>*>(AddSubAssetGeneric(AssetRegistration<SubAsset_t>(std::move(assetName), asset)));
}
XAssetInfoGeneric* AddSubAssetGeneric(GenericAssetRegistration registration) const;
template<AssetDefinition Asset_t> XAssetInfo<typename Asset_t::Type>* LoadDependency(const std::string& assetName)
{
return static_cast<XAssetInfo<typename Asset_t::Type>*>(LoadDependencyGeneric(Asset_t::EnumEntry, assetName));
}
XAssetInfoGeneric* LoadDependencyGeneric(asset_type_t assetType, const std::string& assetName, bool required = true);
template<typename AssetType> IndirectAssetReference LoadIndirectAssetReference(const std::string& assetName)
template<SubAssetDefinition SubAsset_t> XAssetInfo<typename SubAsset_t::Type>* LoadSubAsset(const std::string& assetName)
{
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
return static_cast<XAssetInfo<typename SubAsset_t::Type>*>(LoadSubAssetGeneric(SubAsset_t::EnumEntry, assetName));
}
return LoadIndirectAssetReferenceGeneric(AssetType::EnumEntry, assetName);
XAssetInfoGeneric* LoadSubAssetGeneric(asset_type_t subAssetType, const std::string& assetName);
template<AssetDefinition Asset_t> IndirectAssetReference LoadIndirectAssetReference(const std::string& assetName)
{
return LoadIndirectAssetReferenceGeneric(Asset_t::EnumEntry, assetName);
}
IndirectAssetReference LoadIndirectAssetReferenceGeneric(asset_type_t assetType, const std::string& assetName);
@@ -67,15 +78,13 @@ public:
/**
* \brief Loads an asset dependency like \c LoadDependency but guarantees that the returned asset is not a reference.
* If normally a reference would be created, the actual asset is loaded but a reference is added to the zone.
* \tparam AssetType The type of the asset
* \tparam Asset_t The type of the asset
* \param assetName The name of the asset
* \return XAssetInfo of the asset that is guaranteed to not be a reference or \c nullptr
*/
template<typename AssetType> XAssetInfo<typename AssetType::Type>* ForceLoadDependency(const std::string& assetName)
template<AssetDefinition Asset_t> XAssetInfo<typename Asset_t::Type>* ForceLoadDependency(const std::string& assetName)
{
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
return static_cast<XAssetInfo<typename AssetType::Type>*>(ForceLoadDependencyGeneric(AssetType::EnumEntry, assetName));
return static_cast<XAssetInfo<typename Asset_t::Type>*>(ForceLoadDependencyGeneric(Asset_t::EnumEntry, assetName));
}
XAssetInfoGeneric* ForceLoadDependencyGeneric(asset_type_t assetType, const std::string& assetName);
@@ -85,6 +94,7 @@ private:
Zone& m_zone;
std::unique_ptr<ZoneAssetPools> m_forced_asset_pools;
std::vector<std::unique_ptr<AssetPool>> m_sub_asset_pools;
const AssetCreatorCollection* m_creators;
const IgnoredAssetLookup* m_ignored_asset_lookup;

View File

@@ -6,6 +6,7 @@ AssetCreatorCollection::AssetCreatorCollection(const Zone& zone)
{
const auto* game = IGame::GetGameById(zone.m_game_id);
m_asset_creators_by_type.resize(game->GetAssetTypeCount());
m_sub_asset_creators_by_type.resize(game->GetSubAssetTypeCount());
m_asset_post_processors_by_type.resize(game->GetAssetTypeCount());
m_default_asset_creators_by_type.resize(game->GetAssetTypeCount());
}
@@ -20,6 +21,16 @@ void AssetCreatorCollection::AddAssetCreator(std::unique_ptr<IAssetCreator> crea
m_asset_creators.emplace_back(std::move(creator));
}
void AssetCreatorCollection::AddSubAssetCreator(std::unique_ptr<ISubAssetCreator> creator)
{
const auto maybeHandlingSubAssetType = creator->GetHandlingSubAssetType();
assert(!maybeHandlingSubAssetType || static_cast<unsigned>(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size());
if (maybeHandlingSubAssetType && static_cast<unsigned>(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size())
m_sub_asset_creators_by_type[static_cast<unsigned>(*maybeHandlingSubAssetType)].emplace_back(creator.get());
m_sub_asset_creators.emplace_back(std::move(creator));
}
void AssetCreatorCollection::AddAssetPostProcessor(std::unique_ptr<IAssetPostProcessor> postProcessor)
{
const auto handlingAssetType = postProcessor->GetHandlingAssetType();
@@ -42,9 +53,9 @@ void AssetCreatorCollection::AddDefaultAssetCreator(std::unique_ptr<IDefaultAsse
AssetCreationResult AssetCreatorCollection::CreateAsset(const asset_type_t assetType, const std::string& assetName, AssetCreationContext& context) const
{
assert(assetType >= 0 && static_cast<unsigned>(assetType) < m_asset_creators_by_type.size());
assert(assetType < m_asset_creators_by_type.size());
if (assetType >= 0 && static_cast<unsigned>(assetType) < m_asset_creators_by_type.size())
if (assetType < m_asset_creators_by_type.size())
{
for (const auto& creator : m_asset_creators_by_type[assetType])
{
@@ -68,11 +79,29 @@ AssetCreationResult AssetCreatorCollection::CreateAsset(const asset_type_t asset
return AssetCreationResult::NoAction();
}
AssetCreationResult
AssetCreatorCollection::CreateSubAsset(const asset_type_t subAssetType, const std::string& subAssetName, AssetCreationContext& context) const
{
assert(subAssetType < m_sub_asset_creators_by_type.size());
if (subAssetType < m_sub_asset_creators_by_type.size())
{
for (const auto& creator : m_sub_asset_creators_by_type[subAssetType])
{
const auto result = creator->CreateSubAsset(subAssetName, context);
if (result.HasTakenAction())
return result;
}
}
return AssetCreationResult::NoAction();
}
AssetCreationResult AssetCreatorCollection::CreateDefaultAsset(const asset_type_t assetType, const std::string& assetName, AssetCreationContext& context) const
{
assert(assetType >= 0 && static_cast<unsigned>(assetType) < m_default_asset_creators_by_type.size());
assert(assetType < m_default_asset_creators_by_type.size());
if (assetType >= 0 && static_cast<unsigned>(assetType) < m_default_asset_creators_by_type.size() && m_default_asset_creators_by_type[assetType])
if (assetType < m_default_asset_creators_by_type.size() && m_default_asset_creators_by_type[assetType])
{
return m_default_asset_creators_by_type[assetType]->CreateDefaultAsset(assetName, context);
}

View File

@@ -12,6 +12,7 @@
class AssetCreationContext;
class IAssetCreator;
class ISubAssetCreator;
class IAssetPostProcessor;
class AssetCreationResult;
class IDefaultAssetCreator;
@@ -22,17 +23,24 @@ public:
explicit AssetCreatorCollection(const Zone& zone);
void AddAssetCreator(std::unique_ptr<IAssetCreator> creator);
void AddSubAssetCreator(std::unique_ptr<ISubAssetCreator> creator);
void AddAssetPostProcessor(std::unique_ptr<IAssetPostProcessor> postProcessor);
void AddDefaultAssetCreator(std::unique_ptr<IDefaultAssetCreator> defaultAssetCreator);
AssetCreationResult CreateAsset(asset_type_t assetType, const std::string& assetName, AssetCreationContext& context) const;
AssetCreationResult CreateSubAsset(asset_type_t subAssetType, const std::string& subAssetName, AssetCreationContext& context) const;
AssetCreationResult CreateDefaultAsset(asset_type_t assetType, const std::string& assetName, AssetCreationContext& context) const;
void FinalizeZone(AssetCreationContext& context) const;
private:
std::vector<std::vector<IAssetCreator*>> m_asset_creators_by_type;
std::vector<std::unique_ptr<IAssetCreator>> m_asset_creators;
std::vector<std::vector<ISubAssetCreator*>> m_sub_asset_creators_by_type;
std::vector<std::unique_ptr<ISubAssetCreator>> m_sub_asset_creators;
std::vector<std::vector<IAssetPostProcessor*>> m_asset_post_processors_by_type;
std::vector<std::unique_ptr<IAssetPostProcessor>> m_asset_post_processors;
std::vector<std::unique_ptr<IDefaultAssetCreator>> m_default_asset_creators_by_type;
};

View File

@@ -34,18 +34,16 @@ protected:
std::unordered_set<IndirectAssetReference> m_indirect_asset_references;
};
template<typename AssetType> class AssetRegistration : public GenericAssetRegistration
template<AssetOrSubAssetDefinition Asset_t> class AssetRegistration : public GenericAssetRegistration
{
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
public:
AssetRegistration(std::string assetName)
: GenericAssetRegistration(AssetType::EnumEntry, std::move(assetName), nullptr)
explicit AssetRegistration(std::string assetName)
: GenericAssetRegistration(Asset_t::EnumEntry, std::move(assetName), nullptr)
{
}
AssetRegistration(std::string assetName, typename AssetType::Type* asset)
: GenericAssetRegistration(AssetType::EnumEntry, std::move(assetName), asset)
AssetRegistration(std::string assetName, typename Asset_t::Type* asset)
: GenericAssetRegistration(Asset_t::EnumEntry, std::move(assetName), asset)
{
}
@@ -54,7 +52,7 @@ public:
AssetRegistration& operator=(const AssetRegistration& other) = delete;
AssetRegistration& operator=(AssetRegistration&& other) noexcept = default;
void SetAsset(typename AssetType::Type* asset)
void SetAsset(typename Asset_t::Type* asset)
{
m_asset = asset;
}

View File

@@ -25,11 +25,9 @@ private:
bool m_failure;
};
template<typename AssetType> class GlobalAssetPoolsLoader : public AssetCreator<AssetType>
template<AssetDefinition Asset_t> class GlobalAssetPoolsLoader : public AssetCreator<Asset_t>
{
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
explicit GlobalAssetPoolsLoader(Zone& zone)
: m_zone(zone)
{
@@ -37,15 +35,15 @@ public:
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
auto* existingAsset = GlobalAssetPool<typename AssetType::Type>::GetAssetByName(assetName);
auto* existingAsset = GameGlobalAssetPools::GetGlobalPoolsForGame(m_zone.m_game_id)->GetAsset<Asset_t>(assetName);
if (!existingAsset)
return AssetCreationResult::NoAction();
AssetRegistration<AssetType> registration(assetName, existingAsset->Asset());
AssetRegistration<Asset_t> registration(assetName, existingAsset->Asset());
GlobalAssetPoolsRegistrationPreparation registrationPreparation(registration, m_zone, *existingAsset->m_zone, context);
AssetMarker<AssetType> marker(registrationPreparation);
AssetMarker<Asset_t> marker(registrationPreparation);
marker.Mark(existingAsset->Asset());
auto* newAsset = context.AddAsset(std::move(registration));

View File

@@ -29,13 +29,36 @@ public:
virtual void FinalizeZone(AssetCreationContext& context) {}
};
template<typename AssetType> class AssetCreator : public IAssetCreator
class ISubAssetCreator
{
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
ISubAssetCreator() = default;
virtual ~ISubAssetCreator() = default;
ISubAssetCreator(const ISubAssetCreator& other) = default;
ISubAssetCreator(ISubAssetCreator&& other) noexcept = default;
ISubAssetCreator& operator=(const ISubAssetCreator& other) = default;
ISubAssetCreator& operator=(ISubAssetCreator&& other) noexcept = default;
[[nodiscard]] virtual std::optional<asset_type_t> GetHandlingSubAssetType() const = 0;
virtual AssetCreationResult CreateSubAsset(const std::string& subAssetName, AssetCreationContext& context) = 0;
virtual void FinalizeZone(AssetCreationContext& context) {}
};
template<AssetDefinition Asset_t> class AssetCreator : public IAssetCreator
{
public:
[[nodiscard]] std::optional<asset_type_t> GetHandlingAssetType() const override
{
return AssetType::EnumEntry;
};
return Asset_t::EnumEntry;
}
};
template<SubAssetDefinition SubAsset_t> class SubAssetCreator : public ISubAssetCreator
{
public:
[[nodiscard]] std::optional<asset_type_t> GetHandlingSubAssetType() const override
{
return SubAsset_t::EnumEntry;
}
};

View File

@@ -24,27 +24,25 @@ public:
virtual AssetCreationResult CreateDefaultAsset(const std::string& assetName, AssetCreationContext& context) const = 0;
};
template<typename AssetType> class DefaultAssetCreator : public IDefaultAssetCreator
template<AssetDefinition Asset_t> class DefaultAssetCreator : public IDefaultAssetCreator
{
public:
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
DefaultAssetCreator(MemoryManager& memory)
explicit DefaultAssetCreator(MemoryManager& memory)
: m_memory(memory)
{
}
[[nodiscard]] asset_type_t GetHandlingAssetType() const override
{
return AssetType::EnumEntry;
return Asset_t::EnumEntry;
}
AssetCreationResult CreateDefaultAsset(const std::string& assetName, AssetCreationContext& context) const override
{
auto* asset = m_memory.Alloc<typename AssetType::Type>();
AssetName<AssetType>(*asset) = m_memory.Dup(assetName.c_str());
auto* asset = m_memory.Alloc<typename Asset_t::Type>();
AssetName<Asset_t>(*asset) = m_memory.Dup(assetName.c_str());
return AssetCreationResult::Success(context.AddAsset<AssetType>(assetName, asset));
return AssetCreationResult::Success(context.AddAsset<Asset_t>(assetName, asset));
}
private:

View File

@@ -5,7 +5,6 @@
#include "FontIcon/JsonLoaderFontIconT6.h"
#include "Game/T6/AssetMarkerT6.h"
#include "Game/T6/CommonT6.h"
#include "Game/T6/GameAssetPoolT6.h"
#include "Game/T6/GameT6.h"
#include "Game/T6/Image/ImageLoaderEmbeddedT6.h"
#include "Game/T6/Image/ImageLoaderExternalT6.h"
@@ -236,36 +235,29 @@ namespace T6
void ObjLoader::LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const
{
const auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(zone.m_pools.get());
const auto zoneNameHash = Common::Com_HashKey(zone.m_name.c_str(), 64);
LoadCommonIPaks(searchPath, zone);
if (assetPoolT6->m_key_value_pairs != nullptr)
for (auto* keyValuePairsEntry : zone.m_pools.PoolAssets<AssetKeyValuePairs>())
{
for (auto* keyValuePairsEntry : *assetPoolT6->m_key_value_pairs)
const auto* keyValuePairs = keyValuePairsEntry->Asset();
for (auto variableIndex = 0u; variableIndex < keyValuePairs->numVariables; variableIndex++)
{
const auto* keyValuePairs = keyValuePairsEntry->Asset();
for (auto variableIndex = 0u; variableIndex < keyValuePairs->numVariables; variableIndex++)
{
auto* variable = &keyValuePairs->keyValuePairs[variableIndex];
auto* variable = &keyValuePairs->keyValuePairs[variableIndex];
if (variable->namespaceHash == zoneNameHash && variable->keyHash == IPAK_READ_HASH)
{
LoadIPakForZone(searchPath, variable->value, zone);
}
if (variable->namespaceHash == zoneNameHash && variable->keyHash == IPAK_READ_HASH)
{
LoadIPakForZone(searchPath, variable->value, zone);
}
}
}
if (assetPoolT6->m_sound_bank != nullptr)
{
std::set<std::string> loadedSoundBanksForZone;
std::set<std::string> loadedSoundBanksForZone;
for (auto* sndBankAssetInfo : *assetPoolT6->m_sound_bank)
{
LoadSoundBanksFromAsset(searchPath, *sndBankAssetInfo->Asset(), zone, loadedSoundBanksForZone);
}
for (auto* sndBankAssetInfo : zone.m_pools.PoolAssets<AssetSoundBank>())
{
LoadSoundBanksFromAsset(searchPath, *sndBankAssetInfo->Asset(), zone, loadedSoundBanksForZone);
}
}