Using modular camera system to replace the camera entity.

Signed-off-by: rhhong <rhhong@amazon.com>
monroegm-disable-blank-issue-2
rhhong 4 years ago
parent 09f9e5c6c3
commit 47a2240fc3

@ -32,17 +32,19 @@
#include <AtomLyIntegration/CommonFeatures/PostProcess/ExposureControl/ExposureControlComponentConstants.h>
#include <AtomLyIntegration/CommonFeatures/ImageBasedLights/ImageBasedLightComponentConstants.h>
#include <EMStudio/AnimViewportRenderer.h>
#include <EMotionFX/Source/EMotionFXManager.h>
#include <EMotionFX/Source/ActorManager.h>
#include <EMStudio/AnimViewportRenderer.h>
#include <EMotionFX/CommandSystem/Source/CommandManager.h>
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
namespace EMStudio
{
static constexpr float DepthNear = 0.01f;
AnimViewportRenderer::AnimViewportRenderer(AZStd::shared_ptr<AZ::RPI::WindowContext> windowContext)
: m_windowContext(windowContext)
AnimViewportRenderer::AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext)
: m_windowContext(viewportContext->GetWindowContext())
{
// Create a new entity context
m_entityContext = AZStd::make_unique<AzFramework::EntityContext>();
@ -72,33 +74,14 @@ namespace EMStudio
m_renderPipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineAsset, *m_windowContext.get());
pipelineAsset.Release();
m_scene->AddRenderPipeline(m_renderPipeline);
m_renderPipeline->SetDefaultView(viewportContext->GetDefaultView());
// Currently the scene has to be activated after render pipeline was added so some feature processors (i.e. imgui) can be
// initialized properly with pipeline's pass information.
m_scene->Activate();
AZ::RPI::RPISystemInterface::Get()->RegisterScene(m_scene);
AzFramework::EntityContextId entityContextId = m_entityContext->GetContextId();
// Configure camera
AzFramework::EntityContextRequestBus::EventResult(
m_cameraEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "Cameraentity");
AZ_Assert(m_cameraEntity != nullptr, "Failed to create camera entity.");
// Add debug camera and controller components
AZ::Debug::CameraComponentConfig cameraConfig(m_windowContext);
cameraConfig.m_fovY = AZ::Constants::HalfPi;
cameraConfig.m_depthNear = DepthNear;
m_cameraComponent = m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::CameraComponent>());
m_cameraComponent->SetConfiguration(cameraConfig);
m_cameraEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
m_cameraEntity->Init();
m_cameraEntity->Activate();
// Connect camera to pipeline's default view after camera entity activated
m_renderPipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId());
// Get the FeatureProcessors
m_meshFeatureProcessor = m_scene->GetFeatureProcessor<AZ::Render::MeshFeatureProcessorInterface>();
@ -162,7 +145,7 @@ namespace EMStudio
// Destroy all the entity we created.
m_entityContext->DestroyEntity(m_iblEntity);
m_entityContext->DestroyEntity(m_postProcessEntity);
m_entityContext->DestroyEntity(m_cameraEntity);
//m_entityContext->DestroyEntity(m_cameraEntity);
m_entityContext->DestroyEntity(m_gridEntity);
for (AZ::Entity* entity : m_actorEntities)
{
@ -204,26 +187,6 @@ namespace EMStudio
AZ::RPI::ScenePtr scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene();
auto skyBoxFeatureProcessorInterface = scene->GetFeatureProcessor<AZ::Render::SkyBoxFeatureProcessorInterface>();
skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix);
Camera::Configuration cameraConfig;
Camera::CameraRequestBus::EventResult(
cameraConfig, m_cameraEntity->GetId(), &Camera::CameraRequestBus::Events::GetCameraConfiguration);
// Reset the camera position
static constexpr float StartingDistanceMultiplier = 2.0f;
static constexpr float StartingRotationAngle = AZ::Constants::QuarterPi / 2.0f;
AZ::Vector3 targetPosition = iblTransform.GetTranslation();
const float distance = 1.0f * StartingDistanceMultiplier;
const AZ::Quaternion cameraRotation = AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), StartingRotationAngle);
AZ::Vector3 cameraPosition(targetPosition.GetX(), targetPosition.GetY() - distance, targetPosition.GetZ());
cameraPosition = cameraRotation.TransformVector(cameraPosition);
AZ::Transform cameraTransform = AZ::Transform::CreateFromQuaternionAndTranslation(cameraRotation, cameraPosition);
AZ::TransformBus::Event(m_cameraEntity->GetId(), &AZ::TransformBus::Events::SetLocalTM, cameraTransform);
// Setup primary camera controls
AZ::Debug::CameraControllerRequestBus::Event(
m_cameraEntity->GetId(), &AZ::Debug::CameraControllerRequestBus::Events::Enable, azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
}
void AnimViewportRenderer::ReinitActorEntities()
@ -292,6 +255,13 @@ namespace EMStudio
EMotionFX::Integration::ActorComponent* actorComponent = actorEntity->FindComponent<EMotionFX::Integration::ActorComponent>();
actorComponent->SetActorAsset(actorAsset);
// Since this entity belongs to the animation editor, we need to set the isOwnByRuntime flag to false.
actorComponent->GetActorInstance()->SetIsOwnedByRuntime(false);
// Selet the actor instance in the command manager after it has been created.
AZStd::string outResult;
EMStudioManager::GetInstance()->GetCommandManager()->ExecuteCommandInsideCommand(
AZStd::string::format("Select -actorInstanceID %i", actorComponent->GetActorInstance()->GetID()).c_str(), outResult);
return actorEntity;
}
@ -312,8 +282,8 @@ namespace EMStudio
->GetOrCreateExposureControlSettingsInterface();
Camera::Configuration cameraConfig;
Camera::CameraRequestBus::EventResult(
cameraConfig, m_cameraEntity->GetId(), &Camera::CameraRequestBus::Events::GetCameraConfiguration);
cameraConfig.m_fovRadians = AZ::Constants::HalfPi;
cameraConfig.m_nearClipDistance = DepthNear;
preset->ApplyLightingPreset(
iblFeatureProcessor, m_skyboxFeatureProcessor, exposureControlSettingInterface, m_directionalLightFeatureProcessor,

@ -14,7 +14,7 @@
#include <Integration/Assets/ActorAsset.h>
#include <Atom/RPI.Public/Base.h>
#include <Atom/RPI.Public/WindowContext.h>
#include <Atom/RPI.Public/ViewportContext.h>
#include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
#include <Atom/Feature/CoreLights/DirectionalLightFeatureProcessorInterface.h>
#include <Atom/Feature/Utils/LightingPreset.h>
@ -44,7 +44,7 @@ namespace EMStudio
public:
AZ_CLASS_ALLOCATOR(AnimViewportRenderer, AZ::SystemAllocator, 0);
AnimViewportRenderer(AZStd::shared_ptr<AZ::RPI::WindowContext> windowContext);
AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext);
~AnimViewportRenderer();
void Reinit();

@ -6,7 +6,11 @@
*
*/
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzFramework/Viewport/ViewportControllerList.h>
#include <AzFramework/Viewport/CameraInput.h>
#include <Atom/RPI.Public/ViewportContext.h>
#include <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
#include <EMStudio/AnimViewportWidget.h>
#include <EMStudio/AnimViewportRenderer.h>
@ -17,7 +21,6 @@ namespace EMStudio
: AtomToolsFramework::RenderViewportWidget(parent)
{
setObjectName(QString::fromUtf8("AtomViewportWidget"));
resize(869, 574);
QSizePolicy qSize(QSizePolicy::Preferred, QSizePolicy::Preferred);
qSize.setHorizontalStretch(0);
qSize.setVerticalStretch(0);
@ -26,6 +29,119 @@ namespace EMStudio
setAutoFillBackground(false);
setStyleSheet(QString::fromUtf8(""));
m_renderer = AZStd::make_unique<AnimViewportRenderer>(GetViewportContext()->GetWindowContext());
m_renderer = AZStd::make_unique<AnimViewportRenderer>(GetViewportContext());
SetupCameras();
SetupCameraController();
}
template<typename T>
AZStd::remove_cvref_t<T> GetRegistry(const AZStd::string_view setting, T&& defaultValue)
{
AZStd::remove_cvref_t<T> value = AZStd::forward<T>(defaultValue);
if (const auto* registry = AZ::SettingsRegistry::Get())
{
T potentialValue;
if (registry->Get(potentialValue, setting))
{
value = AZStd::move(potentialValue);
}
}
return value;
}
// TODO: TranslateCameraInput should have a way to initiate with default channel id setup.
static AzFramework::TranslateCameraInputChannelIds BuildTranslateCameraInputChannelIds()
{
constexpr AZStd::string_view CameraTranslateForwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateForwardId";
constexpr AZStd::string_view CameraTranslateBackwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateBackwardId";
constexpr AZStd::string_view CameraTranslateLeftIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateLeftId";
constexpr AZStd::string_view CameraTranslateRightIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateRightId";
constexpr AZStd::string_view CameraTranslateUpIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpId";
constexpr AZStd::string_view CameraTranslateDownIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpDownId";
constexpr AZStd::string_view CameraTranslateBoostIdSetting = "/Amazon/Preferences/Editor/Camera/TranslateBoostId";
AzFramework::TranslateCameraInputChannelIds translateCameraInputChannelIds;
translateCameraInputChannelIds.m_leftChannelId =
AzFramework::InputChannelId(GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
translateCameraInputChannelIds.m_rightChannelId =
AzFramework::InputChannelId(GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
translateCameraInputChannelIds.m_forwardChannelId =
AzFramework::InputChannelId(GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
translateCameraInputChannelIds.m_backwardChannelId = AzFramework::InputChannelId(
GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
translateCameraInputChannelIds.m_upChannelId =
AzFramework::InputChannelId(GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
translateCameraInputChannelIds.m_downChannelId =
AzFramework::InputChannelId(GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
translateCameraInputChannelIds.m_boostChannelId =
AzFramework::InputChannelId(GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
return translateCameraInputChannelIds;
}
void AnimViewportWidget::SetupCameras()
{
constexpr AZStd::string_view CameraOrbitIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitId";
constexpr AZStd::string_view CameraOrbitLookIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitLookId";
m_orbitRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(
AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str()));
const auto translateCameraInputChannelIds = BuildTranslateCameraInputChannelIds();
m_orbitTranslateCamera =
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::OrbitTranslation, translateCameraInputChannelIds);
m_orbitDollyScrollCamera = AZStd::make_shared<AzFramework::OrbitDollyScrollCameraInput>();
}
void AnimViewportWidget::SetupCameraController()
{
auto controller = AZStd::make_shared<AtomToolsFramework::ModularViewportCameraController>();
controller->SetCameraViewportContextBuilderCallback(
[viewportId =
GetViewportContext()->GetId()](AZStd::unique_ptr<AtomToolsFramework::ModularCameraViewportContext>& cameraViewportContext)
{
cameraViewportContext = AZStd::make_unique<AtomToolsFramework::ModularCameraViewportContextImpl>(viewportId);
});
controller->SetCameraPriorityBuilderCallback(
[](AtomToolsFramework::CameraControllerPriorityFn& cameraControllerPriorityFn)
{
cameraControllerPriorityFn = AtomToolsFramework::DefaultCameraControllerPriority;
});
controller->SetCameraPropsBuilderCallback(
[](AzFramework::CameraProps& cameraProps)
{
cameraProps.m_rotateSmoothnessFn = []
{
return 5.0f;
};
cameraProps.m_translateSmoothnessFn = []
{
return 5.0f;
};
cameraProps.m_rotateSmoothingEnabledFn = []
{
return true;
};
cameraProps.m_translateSmoothingEnabledFn = []
{
return true;
};
});
controller->SetCameraListBuilderCallback(
[this](AzFramework::Cameras& cameras)
{
cameras.AddCamera(m_orbitRotateCamera);
cameras.AddCamera(m_orbitTranslateCamera);
cameras.AddCamera(m_orbitDollyScrollCamera);
});
GetControllerList()->Add(controller);
}
}
} // namespace EMStudio

@ -8,7 +8,7 @@
#pragma once
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
#include <AzFramework/Viewport/CameraInput.h>
namespace EMStudio
{
@ -22,6 +22,12 @@ namespace EMStudio
AnimViewportRenderer* GetAnimViewportRenderer() { return m_renderer.get(); }
private:
void SetupCameras();
void SetupCameraController();
AZStd::unique_ptr<AnimViewportRenderer> m_renderer;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_orbitRotateCamera;
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_orbitTranslateCamera;
AZStd::shared_ptr<AzFramework::OrbitDollyScrollCameraInput> m_orbitDollyScrollCamera;
};
}

@ -28,7 +28,7 @@ namespace EMStudio
const char* AtomRenderPlugin::GetName() const
{
return "Atom Render Window";
return "Atom Render Window (Preview)";
}
uint32 AtomRenderPlugin::GetClassID() const
@ -86,6 +86,7 @@ namespace EMStudio
verticalLayout->setSpacing(1);
verticalLayout->setMargin(0);
m_animViewportWidget = new AnimViewportWidget(m_innerWidget);
verticalLayout->addWidget(m_animViewportWidget);
// Register command callbacks.
m_createActorInstanceCallback = new CreateActorInstanceCallback(false);

Loading…
Cancel
Save