You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
9.9 KiB
C++
208 lines
9.9 KiB
C++
/*
|
|
* 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 <QToolButton>
|
|
#include <QPushButton>
|
|
#include <QMenu>
|
|
#include <QSettings>
|
|
#include <EMStudio/AtomRenderPlugin.h>
|
|
#include <EMStudio/AnimViewportToolBar.h>
|
|
#include <EMStudio/AnimViewportRequestBus.h>
|
|
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
|
|
#include <AzCore/std/string/string.h>
|
|
#include <AzQtComponents/Components/Widgets/ToolBar.h>
|
|
|
|
|
|
namespace EMStudio
|
|
{
|
|
AnimViewportToolBar::AnimViewportToolBar(AtomRenderPlugin* plugin, QWidget* parent)
|
|
: QToolBar(parent)
|
|
, m_plugin(plugin)
|
|
{
|
|
AzQtComponents::ToolBar::addMainToolBarStyle(this);
|
|
|
|
// Add the manipulator actions
|
|
QActionGroup* manipulatorGroup = new QActionGroup(this);
|
|
manipulatorGroup->setExclusive(true);
|
|
manipulatorGroup->setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional);
|
|
m_manipulatorActions[RenderOptions::TRANSLATE] = addAction(QIcon(":/EMotionFXAtom/Translate.svg"), "Translate");
|
|
m_manipulatorActions[RenderOptions::ROTATE] = addAction(QIcon(":/EMotionFXAtom/Rotate.svg"), "Rotate");
|
|
m_manipulatorActions[RenderOptions::SCALE] = addAction(QIcon(":/EMotionFXAtom/Scale.svg"), "Scale");
|
|
for (size_t i = RenderOptions::ManipulatorMode::TRANSLATE; i < RenderOptions::ManipulatorMode::NUM_MODES; ++i)
|
|
{
|
|
m_manipulatorActions[i]->setCheckable(true);
|
|
connect(
|
|
m_manipulatorActions[i], &QAction::triggered, this,
|
|
[this, i]()
|
|
{
|
|
const RenderOptions::ManipulatorMode mode =
|
|
m_manipulatorActions[i]->isChecked() ? RenderOptions::ManipulatorMode(i) : RenderOptions::ManipulatorMode::SELECT;
|
|
m_plugin->GetRenderOptions()->SetManipulatorMode(mode);
|
|
m_plugin->SetManipulatorMode(mode);
|
|
});
|
|
manipulatorGroup->addAction(m_manipulatorActions[i]);
|
|
}
|
|
addSeparator();
|
|
|
|
// Add the render view options button
|
|
QToolButton* renderOptionsButton = new QToolButton(this);
|
|
{
|
|
QMenu* contextMenu = new QMenu(renderOptionsButton);
|
|
|
|
renderOptionsButton->setText("Render Options");
|
|
renderOptionsButton->setMenu(contextMenu);
|
|
renderOptionsButton->setPopupMode(QToolButton::InstantPopup);
|
|
renderOptionsButton->setVisible(true);
|
|
renderOptionsButton->setIcon(QIcon(":/EMotionFXAtom/Visualization.svg"));
|
|
addWidget(renderOptionsButton);
|
|
|
|
CreateViewOptionEntry(contextMenu, "Solid", EMotionFX::ActorRenderFlagIndex::SOLID);
|
|
CreateViewOptionEntry(contextMenu, "Wireframe", EMotionFX::ActorRenderFlagIndex::WIREFRAME);
|
|
// [EMFX-TODO] Add those option once implemented.
|
|
// CreateViewOptionEntry(contextMenu, "Lighting", EMotionFX::ActorRenderFlagIndex::RENDER_LIGHTING);
|
|
// CreateViewOptionEntry(contextMenu, "Backface Culling", EMotionFX::ActorRenderFlagIndex::RENDER_BACKFACECULLING);
|
|
contextMenu->addSeparator();
|
|
CreateViewOptionEntry(contextMenu, "Vertex Normals", EMotionFX::ActorRenderFlagIndex::VERTEXNORMALS);
|
|
CreateViewOptionEntry(contextMenu, "Face Normals", EMotionFX::ActorRenderFlagIndex::FACENORMALS);
|
|
CreateViewOptionEntry(contextMenu, "Tangents", EMotionFX::ActorRenderFlagIndex::TANGENTS);
|
|
CreateViewOptionEntry(contextMenu, "Actor Bounding Boxes", EMotionFX::ActorRenderFlagIndex::AABB);
|
|
contextMenu->addSeparator();
|
|
CreateViewOptionEntry(contextMenu, "Line Skeleton", EMotionFX::ActorRenderFlagIndex::LINESKELETON);
|
|
CreateViewOptionEntry(contextMenu, "Solid Skeleton", EMotionFX::ActorRenderFlagIndex::SKELETON);
|
|
CreateViewOptionEntry(contextMenu, "Joint Names", EMotionFX::ActorRenderFlagIndex::NODENAMES);
|
|
CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlagIndex::NODEORIENTATION);
|
|
// [EMFX-TODO] Add those option once implemented.
|
|
// CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlagIndex::RENDER_ACTORBINDPOSE);
|
|
contextMenu->addSeparator();
|
|
CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlagIndex::HITDETECTION_COLLIDERS, true,
|
|
":/EMotionFXAtom/HitDetection.svg");
|
|
CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlagIndex::RAGDOLL_COLLIDERS, true,
|
|
":/EMotionFXAtom/RagdollCollider.svg");
|
|
CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlagIndex::RAGDOLL_JOINTLIMITS, true,
|
|
":/EMotionFXAtom/RagdollJointLimit.svg");
|
|
CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlagIndex::CLOTH_COLLIDERS, true,
|
|
":/EMotionFXAtom/Cloth.svg");
|
|
CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlagIndex::SIMULATEDOBJECT_COLLIDERS, true,
|
|
":/EMotionFXAtom/SimulatedObjectCollider.svg");
|
|
CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlagIndex::SIMULATEJOINTS);
|
|
}
|
|
|
|
// Add the camera button
|
|
QToolButton* cameraButton = new QToolButton(this);
|
|
{
|
|
QMenu* cameraMenu = new QMenu(cameraButton);
|
|
|
|
// Add the camera option
|
|
const AZStd::vector<AZStd::pair<RenderOptions::CameraViewMode, AZStd::string>> cameraOptionNames = {
|
|
{ RenderOptions::CameraViewMode::FRONT, "Front" },
|
|
{ RenderOptions::CameraViewMode::BACK, "Back" },
|
|
{ RenderOptions::CameraViewMode::TOP, "Top" },
|
|
{ RenderOptions::CameraViewMode::BOTTOM, "Bottom" },
|
|
{ RenderOptions::CameraViewMode::LEFT, "Left" },
|
|
{ RenderOptions::CameraViewMode::RIGHT, "Right" },
|
|
};
|
|
|
|
for (const auto& pair : cameraOptionNames)
|
|
{
|
|
RenderOptions::CameraViewMode mode = pair.first;
|
|
cameraMenu->addAction(
|
|
pair.second.c_str(),
|
|
[this, mode]()
|
|
{
|
|
m_plugin->GetRenderOptions()->SetCameraViewMode(mode);
|
|
AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::UpdateCameraViewMode, mode);
|
|
});
|
|
}
|
|
|
|
cameraMenu->addSeparator();
|
|
cameraMenu->addAction(
|
|
"Reset Camera",
|
|
[this]()
|
|
{
|
|
m_plugin->GetRenderOptions()->SetCameraViewMode(RenderOptions::CameraViewMode::DEFAULT);
|
|
AnimViewportRequestBus::Broadcast(
|
|
&AnimViewportRequestBus::Events::UpdateCameraViewMode, RenderOptions::CameraViewMode::DEFAULT);
|
|
});
|
|
|
|
cameraMenu->addSeparator();
|
|
m_followCharacterAction = cameraMenu->addAction("Follow Character");
|
|
m_followCharacterAction->setCheckable(true);
|
|
m_followCharacterAction->setChecked(false);
|
|
connect(m_followCharacterAction, &QAction::triggered, this,
|
|
[this]()
|
|
{
|
|
m_plugin->GetRenderOptions()->SetCameraFollowUp(m_followCharacterAction->isChecked());
|
|
AnimViewportRequestBus::Broadcast(
|
|
&AnimViewportRequestBus::Events::UpdateCameraFollowUp, m_followCharacterAction->isChecked());
|
|
;
|
|
});
|
|
|
|
cameraButton->setMenu(cameraMenu);
|
|
cameraButton->setText("Camera Option");
|
|
cameraButton->setPopupMode(QToolButton::InstantPopup);
|
|
cameraButton->setVisible(true);
|
|
cameraButton->setIcon(QIcon(":/EMotionFXAtom/Camera_category.svg"));
|
|
addWidget(cameraButton);
|
|
}
|
|
|
|
LoadSettings();
|
|
}
|
|
|
|
AnimViewportToolBar::~AnimViewportToolBar()
|
|
{
|
|
}
|
|
|
|
void AnimViewportToolBar::CreateViewOptionEntry(
|
|
QMenu* menu, const char* menuEntryName, AZ::u8 actionIndex, bool visible, const char* iconFileName)
|
|
{
|
|
QAction* action = menu->addAction(
|
|
menuEntryName,
|
|
[this, actionIndex]()
|
|
{
|
|
m_plugin->GetRenderOptions()->ToggerRenderFlag(actionIndex);
|
|
// Send the reset camera event.
|
|
AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::UpdateRenderFlags, m_plugin->GetRenderOptions()->GetRenderFlags());
|
|
});
|
|
action->setCheckable(true);
|
|
action->setVisible(visible);
|
|
|
|
if (iconFileName)
|
|
{
|
|
action->setIcon(QIcon(iconFileName));
|
|
}
|
|
|
|
m_renderActions[actionIndex] = action;
|
|
}
|
|
|
|
void AnimViewportToolBar::LoadSettings()
|
|
{
|
|
const RenderOptions* renderOptions = m_plugin->GetRenderOptions();
|
|
|
|
const bool isChecked = renderOptions->GetCameraFollowUp();
|
|
m_followCharacterAction->setChecked(isChecked);
|
|
AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::UpdateCameraFollowUp, isChecked);
|
|
|
|
RenderOptions::ManipulatorMode mode = renderOptions->GetManipulatorMode();
|
|
m_plugin->SetManipulatorMode(mode);
|
|
if (mode != RenderOptions::ManipulatorMode::SELECT)
|
|
{
|
|
m_manipulatorActions[mode]->setChecked(true);
|
|
}
|
|
|
|
const EMotionFX::ActorRenderFlags renderFlags = renderOptions->GetRenderFlags();
|
|
for (uint8 i = 0; i < EMotionFX::ActorRenderFlagIndex::NUM_RENDERFLAGINDEXES; ++i)
|
|
{
|
|
QAction* action = m_renderActions[i];
|
|
if (action)
|
|
{
|
|
action->setChecked(EMotionFX::ActorRenderFlagUtil::CheckBit(renderFlags, i));
|
|
}
|
|
}
|
|
}
|
|
} // namespace EMStudio
|