141 lines
4.9 KiB
C++
141 lines
4.9 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
|
|
#include <ScriptCanvas/Libraries/Spawning/SpawnNodeable.h>
|
|
|
|
#include <AzFramework/Components/TransformComponent.h>
|
|
#include <AzFramework/Spawnable/SpawnableAssetHandler.h>
|
|
|
|
namespace ScriptCanvas::Nodeables::Spawning
|
|
{
|
|
SpawnNodeable::SpawnNodeable(const SpawnNodeable& rhs)
|
|
: m_spawnableAsset(rhs.m_spawnableAsset)
|
|
{}
|
|
|
|
SpawnNodeable& SpawnNodeable::operator=(SpawnNodeable& rhs)
|
|
{
|
|
m_spawnableAsset = rhs.m_spawnableAsset;
|
|
return *this;
|
|
}
|
|
|
|
void SpawnNodeable::OnInitializeExecutionState()
|
|
{
|
|
if (!AZ::TickBus::Handler::BusIsConnected())
|
|
{
|
|
AZ::TickBus::Handler::BusConnect();
|
|
}
|
|
|
|
m_spawnTicket = AzFramework::EntitySpawnTicket(m_spawnableAsset);
|
|
}
|
|
|
|
void SpawnNodeable::OnDeactivate()
|
|
{
|
|
AZ::TickBus::Handler::BusDisconnect();
|
|
|
|
m_spawnTicket = AzFramework::EntitySpawnTicket();
|
|
}
|
|
|
|
void SpawnNodeable::OnTick([[maybe_unused]] float delta, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
|
|
{
|
|
AZStd::vector<Data::EntityIDType> swappedSpawnedEntityList;
|
|
AZStd::vector<size_t> swappedSpawnBatchSizes;
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_idBatchMutex);
|
|
|
|
swappedSpawnedEntityList.swap(m_spawnedEntityList);
|
|
swappedSpawnBatchSizes.swap(m_spawnBatchSizes);
|
|
}
|
|
|
|
AZ::EntityId* batchBegin = swappedSpawnedEntityList.data();
|
|
for (size_t batchSize : swappedSpawnBatchSizes)
|
|
{
|
|
if (batchSize == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
AZStd::vector<AZ::EntityId> spawnedEntitiesBatch(
|
|
batchBegin, batchBegin + batchSize);
|
|
|
|
CallOnSpawn(AZStd::move(spawnedEntitiesBatch));
|
|
|
|
batchBegin += batchSize;
|
|
}
|
|
}
|
|
|
|
void SpawnNodeable::OnSpawnAssetChanged()
|
|
{
|
|
if (m_spawnableAsset.GetId().IsValid())
|
|
{
|
|
AZStd::string rootSpawnableFile;
|
|
AzFramework::StringFunc::Path::GetFileName(m_spawnableAsset.GetHint().c_str(), rootSpawnableFile);
|
|
|
|
rootSpawnableFile += AzFramework::Spawnable::DotFileExtension;
|
|
|
|
AZ::u32 rootSubId = AzFramework::SpawnableAssetHandler::BuildSubId(AZStd::move(rootSpawnableFile));
|
|
|
|
if (m_spawnableAsset.GetId().m_subId != rootSubId)
|
|
{
|
|
AZ::Data::AssetId rootAssetId = m_spawnableAsset.GetId();
|
|
rootAssetId.m_subId = rootSubId;
|
|
|
|
m_spawnableAsset = AZ::Data::AssetManager::Instance().
|
|
FindOrCreateAsset<AzFramework::Spawnable>(rootAssetId, AZ::Data::AssetLoadBehavior::Default);
|
|
}
|
|
else
|
|
{
|
|
m_spawnableAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::Default);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SpawnNodeable::RequestSpawn(Data::Vector3Type translation, Data::Vector3Type rotation, Data::NumberType scale)
|
|
{
|
|
if (m_spawnableAsset.GetAutoLoadBehavior() == AZ::Data::AssetLoadBehavior::NoLoad)
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto preSpawnCB = [this, translation, rotation, scale]([[maybe_unused]] AzFramework::EntitySpawnTicket::Id ticketId,
|
|
AzFramework::SpawnableEntityContainerView view)
|
|
{
|
|
AZ::Entity* rootEntity = *view.begin();
|
|
|
|
AzFramework::TransformComponent* entityTransform =
|
|
rootEntity->FindComponent<AzFramework::TransformComponent>();
|
|
|
|
if (entityTransform)
|
|
{
|
|
AZ::Vector3 rotationCopy = rotation;
|
|
AZ::Quaternion rotationQuat = AZ::Quaternion::CreateFromEulerAnglesDegrees(rotationCopy);
|
|
|
|
entityTransform->SetWorldTM(AZ::Transform(translation, rotationQuat, scale));
|
|
}
|
|
};
|
|
|
|
auto spawnCompleteCB = [this]([[maybe_unused]] AzFramework::EntitySpawnTicket::Id ticketId,
|
|
AzFramework::SpawnableConstEntityContainerView view)
|
|
{
|
|
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_idBatchMutex);
|
|
m_spawnedEntityList.reserve(m_spawnedEntityList.size() + view.size());
|
|
for (const AZ::Entity* entity : view)
|
|
{
|
|
m_spawnedEntityList.emplace_back(entity->GetId());
|
|
}
|
|
m_spawnBatchSizes.push_back(view.size());
|
|
};
|
|
|
|
AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(
|
|
m_spawnTicket, AzFramework::SpawnablePriority_Default, preSpawnCB, spawnCompleteCB);
|
|
}
|
|
}
|