/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include #include #include #include namespace EMStudio { AnimViewportWidget::AnimViewportWidget(QWidget* parent) : AtomToolsFramework::RenderViewportWidget(parent) { setObjectName(QString::fromUtf8("AtomViewportWidget")); QSizePolicy qSize(QSizePolicy::Preferred, QSizePolicy::Preferred); qSize.setHorizontalStretch(0); qSize.setVerticalStretch(0); qSize.setHeightForWidth(sizePolicy().hasHeightForWidth()); setSizePolicy(qSize); setAutoFillBackground(false); setStyleSheet(QString::fromUtf8("")); m_renderer = AZStd::make_unique(GetViewportContext()); LoadRenderFlags(); SetupCameras(); SetupCameraController(); Reinit(); AnimViewportRequestBus::Handler::BusConnect(); } AnimViewportWidget::~AnimViewportWidget() { SaveRenderFlags(); AnimViewportRequestBus::Handler::BusDisconnect(); } void AnimViewportWidget::Reinit(bool resetCamera) { if (resetCamera) { ResetCamera(); } m_renderer->Reinit(); m_renderer->UpdateActorRenderFlag(m_renderFlags); } EMotionFX::ActorRenderFlagBitset AnimViewportWidget::GetRenderFlags() const { return m_renderFlags; } void AnimViewportWidget::SetupCameras() { m_rotateCamera = AZStd::make_shared(EMStudio::ViewportUtil::BuildRotateCameraInputId()); const auto translateCameraInputChannelIds = EMStudio::ViewportUtil::BuildTranslateCameraInputChannelIds(); m_translateCamera = AZStd::make_shared( translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivotLook); m_translateCamera.get()->m_translateSpeedFn = [] { return 3.0f; }; m_orbitDollyScrollCamera = AZStd::make_shared(); } void AnimViewportWidget::SetupCameraController() { auto controller = AZStd::make_shared(); controller->SetCameraViewportContextBuilderCallback( [viewportId = GetViewportContext()->GetId()](AZStd::unique_ptr& cameraViewportContext) { cameraViewportContext = AZStd::make_unique(viewportId); }); controller->SetCameraPriorityBuilderCallback( [](AtomToolsFramework::CameraControllerPriorityFn& cameraControllerPriorityFn) { cameraControllerPriorityFn = AtomToolsFramework::DefaultCameraControllerPriority; }); controller->SetCameraPropsBuilderCallback( [](AzFramework::CameraProps& cameraProps) { cameraProps.m_rotateSmoothnessFn = [] { return EMStudio::ViewportUtil::CameraRotateSmoothness(); }; cameraProps.m_translateSmoothnessFn = [] { return EMStudio::ViewportUtil::CameraTranslateSmoothness(); }; cameraProps.m_rotateSmoothingEnabledFn = [] { return EMStudio::ViewportUtil::CameraRotateSmoothingEnabled(); }; cameraProps.m_translateSmoothingEnabledFn = [] { return EMStudio::ViewportUtil::CameraTranslateSmoothingEnabled(); }; }); controller->SetCameraListBuilderCallback( [this](AzFramework::Cameras& cameras) { cameras.AddCamera(m_rotateCamera); cameras.AddCamera(m_translateCamera); cameras.AddCamera(m_orbitDollyScrollCamera); }); GetControllerList()->Add(controller); } void AnimViewportWidget::ResetCamera() { SetCameraViewMode(CameraViewMode::DEFAULT); } void AnimViewportWidget::SetCameraViewMode(CameraViewMode mode) { // Set the camera view mode. const AZ::Vector3 targetPosition = m_renderer->GetCharacterCenter(); AZ::Vector3 cameraPosition; switch (mode) { case CameraViewMode::FRONT: cameraPosition.Set(0.0f, CameraDistance, targetPosition.GetZ()); break; case CameraViewMode::BACK: cameraPosition.Set(0.0f, -CameraDistance, targetPosition.GetZ()); break; case CameraViewMode::TOP: cameraPosition.Set(0.0f, 0.0f, CameraDistance + targetPosition.GetZ()); break; case CameraViewMode::BOTTOM: cameraPosition.Set(0.0f, 0.0f, -CameraDistance + targetPosition.GetZ()); break; case CameraViewMode::LEFT: cameraPosition.Set(-CameraDistance, 0.0f, targetPosition.GetZ()); break; case CameraViewMode::RIGHT: cameraPosition.Set(CameraDistance, 0.0f, targetPosition.GetZ()); break; case CameraViewMode::DEFAULT: // The default view mode is looking from the top left of the character. cameraPosition.Set(-CameraDistance, CameraDistance, CameraDistance + targetPosition.GetZ()); break; } GetViewportContext()->SetCameraTransform(AZ::Transform::CreateLookAt(cameraPosition, targetPosition)); } void AnimViewportWidget::ToggleRenderFlag(EMotionFX::ActorRenderFlag flag) { m_renderFlags[flag] = !m_renderFlags[flag]; m_renderer->UpdateActorRenderFlag(m_renderFlags); } void AnimViewportWidget::LoadRenderFlags() { AZStd::string renderFlagsFilename(EMStudioManager::GetInstance()->GetAppDataFolder()); renderFlagsFilename += "AnimViewportRenderFlags.cfg"; QSettings settings(renderFlagsFilename.c_str(), QSettings::IniFormat, this); for (uint32 i = 0; i < EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS; ++i) { QString name = QString(i); const bool isEnabled = settings.value(name).toBool(); m_renderFlags[i] = isEnabled; } m_renderer->UpdateActorRenderFlag(m_renderFlags); } void AnimViewportWidget::SaveRenderFlags() { AZStd::string renderFlagsFilename(EMStudioManager::GetInstance()->GetAppDataFolder()); renderFlagsFilename += "AnimViewportRenderFlags.cfg"; QSettings settings(renderFlagsFilename.c_str(), QSettings::IniFormat, this); for (uint32 i = 0; i < EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS; ++i) { QString name = QString(i); settings.setValue(name, (bool)m_renderFlags[i]); } } } // namespace EMStudio