ActorInstanceId default to -1 when no %lastresult matches (#6442)

* small bugfix

Signed-off-by: rhhong <rhhong@amazon.com>

* ActorInstanceId default to -1 when no %lastresult matches

Signed-off-by: rhhong <rhhong@amazon.com>

* CR feedback - wrap function to get the first available editor actor instance.

Signed-off-by: rhhong <rhhong@amazon.com>

* Remove mcore inline

Signed-off-by: rhhong <rhhong@amazon.com>

* Fixed the bug that delete an instance from actor manager crashes the editor.

Signed-off-by: rhhong <rhhong@amazon.com>
This commit is contained in:
Roman
2022-01-03 09:25:41 -08:00
committed by GitHub
parent 8cccef019f
commit ee554f6464
8 changed files with 87 additions and 6 deletions
@@ -439,6 +439,12 @@ namespace CommandSystem
return false;
}
if (actorInstance->GetEntity())
{
outResult = AZStd::string::format("Cannot remove actor instance. Actor instance %i belongs to an entity.", actorInstanceID);
return false;
}
// store the old values before removing the instance
m_oldPosition = actorInstance->GetLocalSpaceTransform().m_position;
m_oldRotation = actorInstance->GetLocalSpaceTransform().m_rotation;
@@ -618,7 +624,7 @@ namespace CommandSystem
MCore::CommandGroup commandGroup("Remove actor instances", numActorInstances);
AZStd::string tempString;
// iterate over the selected instances and clone them
// iterate over the selected instances and remove them
for (size_t i = 0; i < numActorInstances; ++i)
{
// get the current actor instance
@@ -628,6 +634,18 @@ namespace CommandSystem
continue;
}
// Do not remove any runtime instance from the manager using the commands.
if (actorInstance->GetIsOwnedByRuntime())
{
continue;
}
// Do not remove the any instances owned by an entity from the manager using the commands.
if (actorInstance->GetEntity())
{
continue;
}
tempString = AZStd::string::format("RemoveActorInstance -actorInstanceID %i", actorInstance->GetID());
commandGroup.AddCommandString(tempString.c_str());
}
@@ -455,8 +455,17 @@ namespace CommandSystem
EMotionFX::ActorInstance* actorInstance = nullptr;
if (parameters.CheckIfHasParameter("actorInstanceID"))
{
const uint32 actorInstanceID = parameters.GetValueAsInt("actorInstanceID", this);
actorInstance = EMotionFX::GetActorManager().FindActorInstanceByID(actorInstanceID);
const int actorInstanceID = parameters.GetValueAsInt("actorInstanceID", this);
if (actorInstanceID == -1)
{
// If there isn't an actorInstanceId, grab the first actor instance.
actorInstance = EMotionFX::GetActorManager().GetFirstEditorActorInstance();
}
else
{
actorInstance = EMotionFX::GetActorManager().FindActorInstanceByID(actorInstanceID);
}
if (!actorInstance)
{
outResult = AZStd::string::format("Cannot activate anim graph. Actor instance id '%i' is not valid.", actorInstanceID);
@@ -434,6 +434,20 @@ namespace EMotionFX
}
ActorInstance* ActorManager::GetFirstEditorActorInstance() const
{
const size_t numActorInstances = m_actorInstances.size();
for (size_t i = 0; i < numActorInstances; ++i)
{
if (!m_actorInstances[i]->GetIsOwnedByRuntime())
{
return m_actorInstances[i];
}
}
return nullptr;
}
const AZStd::vector<ActorInstance*>& ActorManager::GetActorInstanceArray() const
{
return m_actorInstances;
@@ -136,6 +136,12 @@ namespace EMotionFX
*/
MCORE_INLINE ActorInstance* GetActorInstance(size_t nr) const { return m_actorInstances[nr]; }
/**
* Get a given registered actor instance owned by editor (not owned by runtime).
* @result A pointer to the actor instance.
*/
ActorInstance* GetFirstEditorActorInstance() const;
/**
* Get the array of actor instances.
* @result The const reference to the actor instance array.
@@ -26,6 +26,7 @@
#include <EMotionFX/CommandSystem/Source/CommandManager.h>
#include <EMotionFX/CommandSystem/Source/MiscCommands.h>
#include <EMotionFX/CommandSystem/Source/SelectionCommands.h>
#include <EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/OpenGLRenderPlugin.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzQtComponents/Components/FancyDocking.h>
@@ -1340,8 +1341,15 @@ namespace EMStudio
// add the load and the create instance commands
commandGroup.AddCommandString(loadActorCommand.c_str());
commandGroup.AddCommandString("CreateActorInstance -actorID %LASTRESULT%");
// Temp solution after we refactor / remove the actor manager.
// We only need to create the actor instance by ourselves when openGLRenderPlugin is present.
// Atom render viewport will create actor instance along with the actor component.
PluginManager* pluginManager = GetPluginManager();
if (pluginManager->FindActivePlugin(static_cast<uint32>(OpenGLRenderPlugin::CLASS_ID)))
{
commandGroup.AddCommandString("CreateActorInstance -actorID %LASTRESULT%");
}
// execute the group command
if (GetCommandManager()->ExecuteCommandGroup(commandGroup, outResult) == false)
@@ -429,6 +429,7 @@ namespace EMStudio
// 3. Relink the actor instances with the emstudio actors
const size_t numActorInstances = EMotionFX::GetActorManager().GetNumActorInstances();
size_t numActorInstancesInRenderPlugin = 0;
for (size_t i = 0; i < numActorInstances; ++i)
{
EMotionFX::ActorInstance* actorInstance = EMotionFX::GetActorManager().GetActorInstance(i);
@@ -440,6 +441,12 @@ namespace EMStudio
continue;
}
if (actorInstance->GetEntity())
{
continue;
}
numActorInstancesInRenderPlugin++;
if (!emstudioActor)
{
for (EMStudioRenderActor* currentEMStudioActor : m_actors)
@@ -485,6 +492,7 @@ namespace EMStudio
if (found == false)
{
emstudioActor->m_actorInstances.erase(AZStd::next(begin(emstudioActor->m_actorInstances), j));
numActorInstancesInRenderPlugin--;
}
else
{
@@ -497,7 +505,7 @@ namespace EMStudio
m_reinitRequested = false;
// zoom the camera to the available character only in case we're dealing with a single instance
if (resetViewCloseup && numActorInstances == 1)
if (resetViewCloseup && numActorInstancesInRenderPlugin == 1)
{
ViewCloseup(false);
}
@@ -23,6 +23,7 @@
#include <EMotionFX/CommandSystem/Source/CommandManager.h>
#include <EMotionFX/CommandSystem/Source/MotionSetCommands.h>
#include <EMotionFX/Source/ActorManager.h>
#include <EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/OpenGLRenderPlugin.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
@@ -430,6 +431,18 @@ namespace EMStudio
continue;
}
// Temp solution after we refactor / remove the actor manager.
// We only need to create the actor instance by ourselves when openGLRenderPlugin is present.
// Atom render viewport will create actor instance along with the actor component.
PluginManager* pluginManager = GetPluginManager();
if (!pluginManager->FindActivePlugin(static_cast<uint32>(OpenGLRenderPlugin::CLASS_ID)))
{
if (commands[i].find("CreateActorInstance") == 0)
{
continue;
}
}
AzFramework::StringFunc::Replace(commands[i], "@products@", assetCacheFolder.c_str());
AzFramework::StringFunc::Replace(commands[i], "@assets@", assetCacheFolder.c_str());
AzFramework::StringFunc::Replace(commands[i], "@root@", assetCacheFolder.c_str());
@@ -547,7 +547,12 @@ namespace MCore
}
tmpStr = commandString.substr(lastResultIndex, rightPercentagePos - lastResultIndex + 1);
AzFramework::StringFunc::Replace(commandString, tmpStr.c_str(), intermediateCommandResults[i - relativeIndex].c_str());
AZStd::string replaceStr = intermediateCommandResults[i - relativeIndex];
if (replaceStr.empty())
{
replaceStr = "-1";
}
AzFramework::StringFunc::Replace(commandString, tmpStr.c_str(), replaceStr.c_str());
replaceHappen = true;
// Search again in case the command group is referring to other results