Merge branch 'stabilization/2106' of https://github.com/o3de/o3de into carlitosan/scriptcanvas/prefabs
This commit is contained in:
+10
-23
@@ -2302,13 +2302,6 @@ int CCryEditApp::IdleProcessing(bool bBackgroundUpdate)
|
||||
|
||||
m_bPrevActive = bActive;
|
||||
|
||||
AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
|
||||
static AZStd::chrono::system_clock::time_point lastUpdate = now;
|
||||
|
||||
AZStd::chrono::duration<float> delta = now - lastUpdate;
|
||||
|
||||
lastUpdate = now;
|
||||
|
||||
// Don't tick application if we're doing idle processing during an assert.
|
||||
const bool isErrorWindowVisible = (gEnv && gEnv->pSystem->IsAssertDialogVisible());
|
||||
if (isErrorWindowVisible)
|
||||
@@ -2320,30 +2313,24 @@ int CCryEditApp::IdleProcessing(bool bBackgroundUpdate)
|
||||
}
|
||||
else if (bActive || (bBackgroundUpdate && !bIsAppWindow))
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Update Game
|
||||
GetIEditor()->GetGameEngine()->Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
GetIEditor()->GetGameEngine()->Update();
|
||||
// Update Game
|
||||
GetIEditor()->GetGameEngine()->Update();
|
||||
|
||||
if (!GetIEditor()->IsInGameMode())
|
||||
{
|
||||
if (m_pEditor)
|
||||
{
|
||||
m_pEditor->Update();
|
||||
}
|
||||
|
||||
GetIEditor()->Notify(eNotify_OnIdleUpdate);
|
||||
}
|
||||
|
||||
// Since the rendering is done based on the eNotify_OnIdleUpdate, we should trigger a TickSystem as well.
|
||||
// To ensure that there's a system tick for every render done in Idle
|
||||
AZ::ComponentApplication* componentApplication = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(componentApplication, &AZ::ComponentApplicationRequests::GetApplication);
|
||||
if (componentApplication)
|
||||
{
|
||||
componentApplication->TickSystem();
|
||||
}
|
||||
AZ::ComponentApplication* componentApplication = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(componentApplication, &AZ::ComponentApplicationRequests::GetApplication);
|
||||
if (componentApplication)
|
||||
{
|
||||
componentApplication->TickSystem();
|
||||
}
|
||||
}
|
||||
else if (GetIEditor()->GetSystem() && GetIEditor()->GetSystem()->GetILog())
|
||||
|
||||
@@ -489,11 +489,6 @@ void MainWindow::Initialize()
|
||||
ActionOverrideRequestBus::Event(
|
||||
GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, this);
|
||||
|
||||
// This function only happens after we're pretty sure that the engine has successfully started - so now would be a good time to start ticking the message pumps/etc.
|
||||
AzToolsFramework::Ticker* ticker = new AzToolsFramework::Ticker(this);
|
||||
ticker->Start();
|
||||
connect(ticker, &AzToolsFramework::Ticker::Tick, this, &MainWindow::SystemTick);
|
||||
|
||||
AzToolsFramework::EditorEventsBus::Broadcast(&AzToolsFramework::EditorEvents::NotifyMainWindowInitialized, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,28 @@ namespace AzPhysics
|
||||
const CollisionGroup CollisionGroup::All_NoTouchBend = CollisionGroup::All.GetMask() & ~CollisionLayer::TouchBend.GetMask();
|
||||
#endif
|
||||
|
||||
void CollisionGroupScriptConstructor(CollisionGroup* thisPtr, AZ::ScriptDataContext& scriptDataContext)
|
||||
{
|
||||
if (int numArgs = scriptDataContext.GetNumArguments();
|
||||
numArgs != 1)
|
||||
{
|
||||
scriptDataContext.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true,
|
||||
"CollisionGroup() accepts only 1 argument, not %d", numArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scriptDataContext.IsString(0))
|
||||
{
|
||||
scriptDataContext.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true,
|
||||
"Argument to CollisionGroup() should be string");
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::string groupName;
|
||||
scriptDataContext.ReadArg(0, groupName);
|
||||
*thisPtr = CollisionGroup(groupName);
|
||||
}
|
||||
|
||||
void CollisionGroup::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
@@ -50,7 +72,9 @@ namespace AzPhysics
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "AzPhysics")
|
||||
->Constructor<const AZStd::string>()
|
||||
->Constructor<const AZStd::string&>()
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Attribute(AZ::Script::Attributes::ConstructorOverride, &CollisionGroupScriptConstructor)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,19 @@ namespace AzPhysics
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* behaviorContext = azdynamic_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SceneQueryRequest>("SceneQueryRequest")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Property("Collision", BehaviorValueProperty(&SceneQueryRequest::m_collisionGroup))
|
||||
// Until enum class support for behavior context is done, expose this as an int
|
||||
->Property("QueryType", [](const SceneQueryRequest& self) { return static_cast<int>(self.m_queryType); },
|
||||
[](SceneQueryRequest& self, int newQueryType) { self.m_queryType = SceneQuery::QueryType(newQueryType); })
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ void RayCastRequest::Reflect(AZ::ReflectContext* context)
|
||||
@@ -123,10 +136,6 @@ namespace AzPhysics
|
||||
->Property("Distance", BehaviorValueProperty(&RayCastRequest::m_distance))
|
||||
->Property("Start", BehaviorValueProperty(&RayCastRequest::m_start))
|
||||
->Property("Direction", BehaviorValueProperty(&RayCastRequest::m_direction))
|
||||
->Property("Collision", BehaviorValueProperty(&RayCastRequest::m_collisionGroup))
|
||||
// Until enum class support for behavior context is done, expose this as an int
|
||||
->Property("QueryType", [](const RayCastRequest& self) { return static_cast<int>(self.m_queryType); },
|
||||
[](RayCastRequest& self, int newQueryType) { self.m_queryType = SceneQuery::QueryType(newQueryType); })
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,21 +73,22 @@ namespace Physics
|
||||
{
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<Physics::CharacterRequestBus>("CharacterControllerRequestBus", "Character Controller")
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::RuntimeOwn)
|
||||
behaviorContext->EBus<CharacterRequestBus>("CharacterControllerRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "PhysX")
|
||||
->Event("GetBasePosition", &Physics::CharacterRequests::GetBasePosition, "Get Base Position")
|
||||
->Event("SetBasePosition", &Physics::CharacterRequests::SetBasePosition, "Set Base Position")
|
||||
->Event("GetCenterPosition", &Physics::CharacterRequests::GetCenterPosition, "Get Center Position")
|
||||
->Event("GetStepHeight", &Physics::CharacterRequests::GetStepHeight, "Get Step Height")
|
||||
->Event("SetStepHeight", &Physics::CharacterRequests::SetStepHeight, "Set Step Height")
|
||||
->Event("GetUpDirection", &Physics::CharacterRequests::GetUpDirection, "Get Up Direction")
|
||||
->Event("GetSlopeLimitDegrees", &Physics::CharacterRequests::GetSlopeLimitDegrees, "Get Slope Limit (Degrees)")
|
||||
->Event("SetSlopeLimitDegrees", &Physics::CharacterRequests::SetSlopeLimitDegrees, "Set Slope Limit (Degrees)")
|
||||
->Event("GetMaximumSpeed", &Physics::CharacterRequests::GetMaximumSpeed, "Get Maximum Speed")
|
||||
->Event("SetMaximumSpeed", &Physics::CharacterRequests::SetMaximumSpeed, "Set Maximum Speed")
|
||||
->Event("GetVelocity", &Physics::CharacterRequests::GetVelocity, "Get Velocity")
|
||||
->Event("AddVelocity", &Physics::CharacterRequests::AddVelocity, "Add Velocity")
|
||||
->Event("GetBasePosition", &CharacterRequests::GetBasePosition, "Get Base Position")
|
||||
->Event("SetBasePosition", &CharacterRequests::SetBasePosition, "Set Base Position")
|
||||
->Event("GetCenterPosition", &CharacterRequests::GetCenterPosition, "Get Center Position")
|
||||
->Event("GetStepHeight", &CharacterRequests::GetStepHeight, "Get Step Height")
|
||||
->Event("SetStepHeight", &CharacterRequests::SetStepHeight, "Set Step Height")
|
||||
->Event("GetUpDirection", &CharacterRequests::GetUpDirection, "Get Up Direction")
|
||||
->Event("GetSlopeLimitDegrees", &CharacterRequests::GetSlopeLimitDegrees, "Get Slope Limit (Degrees)")
|
||||
->Event("SetSlopeLimitDegrees", &CharacterRequests::SetSlopeLimitDegrees, "Set Slope Limit (Degrees)")
|
||||
->Event("GetMaximumSpeed", &CharacterRequests::GetMaximumSpeed, "Get Maximum Speed")
|
||||
->Event("SetMaximumSpeed", &CharacterRequests::SetMaximumSpeed, "Set Maximum Speed")
|
||||
->Event("GetVelocity", &CharacterRequests::GetVelocity, "Get Velocity")
|
||||
->Event("AddVelocity", &CharacterRequests::AddVelocity, "Add Velocity")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
+22
-5
@@ -488,6 +488,13 @@ namespace AzToolsFramework
|
||||
return worldFromLocal.TransformPoint(CalculateCenterOffset(entityId, pivot));
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::SetAllViewportUiVisible(const bool visible)
|
||||
{
|
||||
SetViewportUiClusterVisible(m_transformModeClusterId, visible);
|
||||
SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, visible);
|
||||
m_viewportUiVisible = visible;
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::UpdateSpaceCluster(const ReferenceFrame referenceFrame)
|
||||
{
|
||||
auto buttonIdFromFrameFn = [this](const ReferenceFrame referenceFrame)
|
||||
@@ -1009,6 +1016,7 @@ namespace AzToolsFramework
|
||||
ToolsApplicationNotificationBus::Handler::BusConnect();
|
||||
Camera::EditorCameraNotificationBus::Handler::BusConnect();
|
||||
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(entityContextId);
|
||||
EditorEntityContextNotificationBus::Handler::BusConnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
|
||||
EditorManipulatorCommandUndoRedoRequestBus::Handler::BusConnect(entityContextId);
|
||||
@@ -1037,6 +1045,7 @@ namespace AzToolsFramework
|
||||
EditorManipulatorCommandUndoRedoRequestBus::Handler::BusDisconnect();
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
|
||||
EditorEntityContextNotificationBus::Handler::BusDisconnect();
|
||||
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
|
||||
Camera::EditorCameraNotificationBus::Handler::BusDisconnect();
|
||||
ToolsApplicationNotificationBus::Handler::BusDisconnect();
|
||||
@@ -2387,9 +2396,7 @@ namespace AzToolsFramework
|
||||
/*ID_VIEWPORTUI_VISIBLE=*/50040, "Toggle Viewport UI", "Hide/Show Viewport UI",
|
||||
[this]()
|
||||
{
|
||||
SetViewportUiClusterVisible(m_transformModeClusterId, !m_viewportUiVisible);
|
||||
SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, !m_viewportUiVisible);
|
||||
m_viewportUiVisible = !m_viewportUiVisible;
|
||||
SetAllViewportUiVisible(!m_viewportUiVisible);
|
||||
});
|
||||
|
||||
EditorMenuRequestBus::Broadcast(&EditorMenuRequests::RestoreEditMenuToDefault);
|
||||
@@ -3560,7 +3567,7 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorTransformComponentSelection::EnteredComponentMode([[maybe_unused]] const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
SetViewportUiClusterVisible(m_transformModeClusterId, false);
|
||||
SetAllViewportUiVisible(false);
|
||||
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
|
||||
@@ -3569,7 +3576,7 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorTransformComponentSelection::LeftComponentMode([[maybe_unused]] const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
SetViewportUiClusterVisible(m_transformModeClusterId, true);
|
||||
SetAllViewportUiVisible(true);
|
||||
|
||||
ToolsApplicationNotificationBus::Handler::BusConnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
|
||||
@@ -3625,6 +3632,16 @@ namespace AzToolsFramework
|
||||
ETCS::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::OnStartPlayInEditor()
|
||||
{
|
||||
SetAllViewportUiVisible(false);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::OnStopPlayInEditor()
|
||||
{
|
||||
SetAllViewportUiVisible(true);
|
||||
}
|
||||
|
||||
namespace ETCS
|
||||
{
|
||||
// little raii wrapper to switch a value from true to false and back
|
||||
|
||||
+9
-1
@@ -128,6 +128,7 @@ namespace AzToolsFramework
|
||||
, private ToolsApplicationNotificationBus::Handler
|
||||
, private Camera::EditorCameraNotificationBus::Handler
|
||||
, private ComponentModeFramework::EditorComponentModeNotificationBus::Handler
|
||||
, private EditorEntityContextNotificationBus::Handler
|
||||
, private EditorEntityVisibilityNotificationBus::Router
|
||||
, private EditorEntityLockComponentNotificationBus::Router
|
||||
, private EditorManipulatorCommandUndoRedoRequestBus::Handler
|
||||
@@ -264,6 +265,10 @@ namespace AzToolsFramework
|
||||
void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
|
||||
void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
|
||||
|
||||
// EditorEntityContextNotificationBus overrides ...
|
||||
void OnStartPlayInEditor() override;
|
||||
void OnStopPlayInEditor() override;
|
||||
|
||||
// Helpers to safely interact with the TransformBus (requests).
|
||||
void SetEntityWorldTranslation(AZ::EntityId entityId, const AZ::Vector3& worldTranslation);
|
||||
void SetEntityLocalTranslation(AZ::EntityId entityId, const AZ::Vector3& localTranslation);
|
||||
@@ -271,9 +276,12 @@ namespace AzToolsFramework
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, float localScale);
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation);
|
||||
|
||||
// Responsible for keeping the space cluster in sync with the current reference frame.
|
||||
//! Responsible for keeping the space cluster in sync with the current reference frame.
|
||||
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
|
||||
|
||||
//! Hides/Shows all viewportUi toolbars.
|
||||
void SetAllViewportUiVisible(bool visible);
|
||||
|
||||
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
|
||||
AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display.
|
||||
AZ::EntityId m_editorCameraComponentEntityId; //!< The EditorCameraComponent EntityId if it is set.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <NewProjectSettingsScreen.h>
|
||||
#include <ScreenHeaderWidget.h>
|
||||
#include <GemCatalog/GemModel.h>
|
||||
#include <GemCatalog/GemCatalogScreen.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
@@ -46,6 +47,40 @@ namespace O3DE::ProjectManager
|
||||
m_stack->addWidget(m_gemCatalogScreen);
|
||||
vLayout->addWidget(m_stack);
|
||||
|
||||
// When there are multiple project templates present, we re-gather the gems when changing the selected the project template.
|
||||
connect(m_newProjectSettingsScreen, &NewProjectSettingsScreen::OnTemplateSelectionChanged, this, [=](int oldIndex, [[maybe_unused]] int newIndex)
|
||||
{
|
||||
const GemModel* gemModel = m_gemCatalogScreen->GetGemModel();
|
||||
const QVector<QModelIndex> toBeAdded = gemModel->GatherGemsToBeAdded();
|
||||
const QVector<QModelIndex> toBeRemoved = gemModel->GatherGemsToBeRemoved();
|
||||
if (!toBeAdded.isEmpty() || !toBeRemoved.isEmpty())
|
||||
{
|
||||
// In case the user enabled or disabled any gem and the current selection does not match the default from the
|
||||
// // project template anymore, we need to ask the user if they want to proceed as their modifications will be lost.
|
||||
const QString title = tr("Modifications will be lost");
|
||||
const QString text = tr("You selected a new project template after modifying the enabled gems.\n\n"
|
||||
"All modifications will be lost and the default from the new project template will be used.\n\n"
|
||||
"Do you want to proceed?");
|
||||
if (QMessageBox::warning(this, title, text, QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||
{
|
||||
// The users wants to proceed. Reinitialize based on the newly selected project template.
|
||||
ReinitGemCatalogForSelectedTemplate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Roll-back to the previously selected project template and
|
||||
// block signals so that we don't end up in this same callback again.
|
||||
m_newProjectSettingsScreen->SelectProjectTemplate(oldIndex, /*blockSignals=*/true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In case the user did not enable or disable any gem and the currently enabled gems matches the previously selected
|
||||
// ones from the project template, we can just reinitialize based on the newly selected project template.
|
||||
ReinitGemCatalogForSelectedTemplate();
|
||||
}
|
||||
});
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox();
|
||||
buttons->setObjectName("footer");
|
||||
vLayout->addWidget(buttons);
|
||||
@@ -81,10 +116,8 @@ namespace O3DE::ProjectManager
|
||||
currentScreen->NotifyCurrentScreen();
|
||||
}
|
||||
|
||||
// Gather the gems from the project template. When we will have multiple project templates, we need to re-gather them
|
||||
// on changing the template and let the user know that any further changes on top of the template will be lost.
|
||||
QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath();
|
||||
m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true);
|
||||
// Gather the enabled gems from the default project template when starting the create new project workflow.
|
||||
ReinitGemCatalogForSelectedTemplate();
|
||||
}
|
||||
|
||||
void CreateProjectCtrl::HandleBackButton()
|
||||
@@ -223,4 +256,9 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void CreateProjectCtrl::ReinitGemCatalogForSelectedTemplate()
|
||||
{
|
||||
const QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath();
|
||||
m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true);
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace O3DE::ProjectManager
|
||||
#ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED
|
||||
void OnChangeScreenRequest(ProjectManagerScreen screen);
|
||||
void HandleSecondaryButton();
|
||||
void ReinitGemCatalogForSelectedTemplate();
|
||||
#endif // TEMPLATE_GEM_CONFIGURATION_ENABLED
|
||||
|
||||
private:
|
||||
|
||||
@@ -21,4 +21,9 @@ namespace O3DE::ProjectManager
|
||||
connect(browseButton, &QPushButton::pressed, this, &FormBrowseEditWidget::HandleBrowseButton);
|
||||
m_frameLayout->addWidget(browseButton);
|
||||
}
|
||||
|
||||
FormBrowseEditWidget::FormBrowseEditWidget(const QString& labelText, QWidget* parent)
|
||||
: FormBrowseEditWidget(labelText, "", parent)
|
||||
{
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
public:
|
||||
explicit FormBrowseEditWidget(const QString& labelText, const QString& valueText = "", QWidget* parent = nullptr);
|
||||
explicit FormBrowseEditWidget(const QString& labelText = "", QWidget* parent = nullptr);
|
||||
~FormBrowseEditWidget() = default;
|
||||
|
||||
protected slots:
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
FormFolderBrowseEditWidget::FormFolderBrowseEditWidget(const QString& labelText, const QString& valueText, QWidget* parent)
|
||||
: FormBrowseEditWidget(labelText, valueText, parent)
|
||||
: FormBrowseEditWidget(labelText, parent)
|
||||
{
|
||||
setText(valueText);
|
||||
}
|
||||
|
||||
void FormFolderBrowseEditWidget::HandleBrowseButton()
|
||||
@@ -30,8 +31,14 @@ namespace O3DE::ProjectManager
|
||||
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Browse"), defaultPath));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
m_lineEdit->setText(directory);
|
||||
setText(directory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FormFolderBrowseEditWidget::setText(const QString& text)
|
||||
{
|
||||
QString path = QDir::toNativeSeparators(text);
|
||||
FormBrowseEditWidget::setText(path);
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace O3DE::ProjectManager
|
||||
explicit FormFolderBrowseEditWidget(const QString& labelText, const QString& valueText = "", QWidget* parent = nullptr);
|
||||
~FormFolderBrowseEditWidget() = default;
|
||||
|
||||
void setText(const QString& text) override;
|
||||
|
||||
protected:
|
||||
void HandleBrowseButton() override;
|
||||
};
|
||||
|
||||
@@ -123,4 +123,14 @@ namespace O3DE::ProjectManager
|
||||
child->style()->polish(child);
|
||||
}
|
||||
}
|
||||
|
||||
void FormLineEditWidget::setText(const QString& text)
|
||||
{
|
||||
m_lineEdit->setText(text);
|
||||
}
|
||||
|
||||
void FormLineEditWidget::mousePressEvent([[maybe_unused]] QMouseEvent* event)
|
||||
{
|
||||
m_lineEdit->setFocus();
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -15,6 +15,7 @@ QT_FORWARD_DECLARE_CLASS(QLineEdit)
|
||||
QT_FORWARD_DECLARE_CLASS(QLabel)
|
||||
QT_FORWARD_DECLARE_CLASS(QFrame)
|
||||
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QMouseEvent)
|
||||
|
||||
namespace AzQtComponents
|
||||
{
|
||||
@@ -39,6 +40,8 @@ namespace O3DE::ProjectManager
|
||||
//! Returns a pointer to the underlying LineEdit.
|
||||
QLineEdit* lineEdit() const;
|
||||
|
||||
virtual void setText(const QString& text);
|
||||
|
||||
protected:
|
||||
QLabel* m_errorLabel = nullptr;
|
||||
QFrame* m_frame = nullptr;
|
||||
@@ -51,6 +54,8 @@ namespace O3DE::ProjectManager
|
||||
void onFocusOut();
|
||||
|
||||
private:
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
|
||||
void refreshStyle();
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace O3DE::ProjectManager
|
||||
void ReinitForProject(const QString& projectPath, bool isNewProject);
|
||||
bool EnableDisableGemsForProject(const QString& projectPath);
|
||||
|
||||
GemModel* GetGemModel() const { return m_gemModel; }
|
||||
|
||||
private:
|
||||
void FillModel(const QString& projectPath, bool isNewProject);
|
||||
|
||||
|
||||
@@ -81,8 +81,14 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
if (button && button->property(k_templateIndexProperty).isValid())
|
||||
{
|
||||
int projectIndex = button->property(k_templateIndexProperty).toInt();
|
||||
UpdateTemplateDetails(m_templates.at(projectIndex));
|
||||
int projectTemplateIndex = button->property(k_templateIndexProperty).toInt();
|
||||
if (m_selectedTemplateIndex != projectTemplateIndex)
|
||||
{
|
||||
const int oldIndex = m_selectedTemplateIndex;
|
||||
m_selectedTemplateIndex = projectTemplateIndex;
|
||||
UpdateTemplateDetails(m_templates.at(m_selectedTemplateIndex));
|
||||
emit OnTemplateSelectionChanged(/*oldIndex=*/oldIndex, /*newIndex=*/m_selectedTemplateIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -115,7 +121,8 @@ namespace O3DE::ProjectManager
|
||||
flowLayout->addWidget(templateButton);
|
||||
}
|
||||
|
||||
m_projectTemplateButtonGroup->buttons().first()->setChecked(true);
|
||||
// Select the first project template (default selection).
|
||||
SelectProjectTemplate(0, /*blockSignals=*/true);
|
||||
}
|
||||
containerLayout->addWidget(templatesScrollArea);
|
||||
}
|
||||
@@ -159,8 +166,9 @@ namespace O3DE::ProjectManager
|
||||
|
||||
QString NewProjectSettingsScreen::GetProjectTemplatePath()
|
||||
{
|
||||
const int templateIndex = m_projectTemplateButtonGroup->checkedButton()->property(k_templateIndexProperty).toInt();
|
||||
return m_templates.at(templateIndex).m_path;
|
||||
AZ_Assert(m_selectedTemplateIndex == m_projectTemplateButtonGroup->checkedButton()->property(k_templateIndexProperty).toInt(),
|
||||
"Selected template index not in sync with the currently checked project template button.");
|
||||
return m_templates.at(m_selectedTemplateIndex).m_path;
|
||||
}
|
||||
|
||||
QFrame* NewProjectSettingsScreen::CreateTemplateDetails(int margin)
|
||||
@@ -216,4 +224,27 @@ namespace O3DE::ProjectManager
|
||||
m_templateSummary->setText(templateInfo.m_summary);
|
||||
m_templateIncludedGems->Update(templateInfo.m_includedGems);
|
||||
}
|
||||
|
||||
void NewProjectSettingsScreen::SelectProjectTemplate(int index, bool blockSignals)
|
||||
{
|
||||
const QList<QAbstractButton*> buttons = m_projectTemplateButtonGroup->buttons();
|
||||
if (index >= buttons.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (blockSignals)
|
||||
{
|
||||
m_projectTemplateButtonGroup->blockSignals(true);
|
||||
}
|
||||
|
||||
QAbstractButton* button = buttons.at(index);
|
||||
button->setChecked(true);
|
||||
m_selectedTemplateIndex = button->property(k_templateIndexProperty).toInt();
|
||||
|
||||
if (blockSignals)
|
||||
{
|
||||
m_projectTemplateButtonGroup->blockSignals(false);
|
||||
}
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace O3DE::ProjectManager
|
||||
class NewProjectSettingsScreen
|
||||
: public ProjectSettingsScreen
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewProjectSettingsScreen(QWidget* parent = nullptr);
|
||||
~NewProjectSettingsScreen() = default;
|
||||
@@ -31,6 +33,11 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void NotifyCurrentScreen() override;
|
||||
|
||||
void SelectProjectTemplate(int index, bool blockSignals = false);
|
||||
|
||||
signals:
|
||||
void OnTemplateSelectionChanged(int oldIndex, int newIndex);
|
||||
|
||||
private:
|
||||
QString GetDefaultProjectPath();
|
||||
QFrame* CreateTemplateDetails(int margin);
|
||||
@@ -41,6 +48,7 @@ namespace O3DE::ProjectManager
|
||||
QLabel* m_templateSummary;
|
||||
TagContainerWidget* m_templateIncludedGems;
|
||||
QVector<ProjectTemplateInfo> m_templates;
|
||||
int m_selectedTemplateIndex = -1;
|
||||
|
||||
inline constexpr static int s_spacerSize = 20;
|
||||
inline constexpr static int s_templateDetailsContentMargin = 20;
|
||||
|
||||
@@ -92,8 +92,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
QLabel* introLabel = new QLabel(this);
|
||||
introLabel->setObjectName("introLabel");
|
||||
introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project. Not sure what to create? \nExplore what's "
|
||||
"available by downloading our sample project."));
|
||||
introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project."));
|
||||
layout->addWidget(introLabel);
|
||||
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <QSysInfo>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
|
||||
namespace AWSCore
|
||||
@@ -170,7 +171,7 @@ namespace AWSCore
|
||||
switch (ret)
|
||||
{
|
||||
case QMessageBox::Save:
|
||||
m_settingsRegistry->Set(AWSAttributionEnabledKey, msgBox->checkBox());
|
||||
m_settingsRegistry->Set(AWSAttributionEnabledKey, msgBox->checkBox()->checkState() == Qt::Checked);
|
||||
break;
|
||||
case QMessageBox::Cancel:
|
||||
default:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <RenderCommon.h>
|
||||
|
||||
#include <Atom/RHI/CpuProfiler.h>
|
||||
#include <Atom/RHI/RHIUtils.h>
|
||||
#include <Atom/RHI.Reflect/InputStreamLayoutBuilder.h>
|
||||
#include <Atom/Feature/Mesh/MeshFeatureProcessor.h>
|
||||
#include <Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h>
|
||||
@@ -526,7 +527,10 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("MeshDataInstance::OnAssetReady", false, "Failed to create model instance for '%s'", asset.GetHint().c_str());
|
||||
//when running with null renderer, the RPI::Model::FindOrCreate(...) is expected to return nullptr, so suppress this error.
|
||||
AZ_Error(
|
||||
"MeshDataInstance::OnAssetReady", RHI::IsNullRenderer(), "Failed to create model instance for '%s'",
|
||||
asset.GetHint().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace AZ
|
||||
void MaterialAssetDependenciesComponent::ReportJobDependencies(SceneAPI::JobDependencyList& jobDependencyList, const char* platformIdentifier)
|
||||
{
|
||||
AssetBuilderSDK::SourceFileDependency materialTypeSource;
|
||||
// Right now, FBX importing only supports a single material type, once that changes, this will have to be re-designed, see ATOM-3554
|
||||
// Right now, scene file importing only supports a single material type, once that changes, this will have to be re-designed, see ATOM-3554
|
||||
RPI::MaterialConverterBus::BroadcastResult(materialTypeSource.m_sourceFileDependencyPath, &RPI::MaterialConverterBus::Events::GetMaterialTypePath);
|
||||
|
||||
AssetBuilderSDK::JobDependency jobDependency;
|
||||
@@ -94,7 +94,7 @@ namespace AZ
|
||||
{
|
||||
// [GFX TODO] I am suggesting we use the first two 16bits for different kind of assets generated from a Scene
|
||||
// For example, 0x10000 for mesh, 0x20000 for material, 0x30000 for animation, 0x40000 for scene graph and etc.
|
||||
// so the subid can be evaluated for reference across different assets generate within this fbx.
|
||||
// so the subid can be evaluated for reference across different assets generate within this scene file.
|
||||
/*const uint32_t materialPrefix = 0x20000;
|
||||
AZ_Assert(materialPrefix > materialId, "materialId should be smaller than materialPrefix");
|
||||
return materialPrefix + materialId;*/
|
||||
@@ -148,7 +148,7 @@ namespace AZ
|
||||
// The source data for generating material asset
|
||||
MaterialSourceData sourceData;
|
||||
|
||||
// User hook to create their materials based on the data from Fbx pipeline
|
||||
// User hook to create their materials based on the data from the scene pipeline
|
||||
bool result = false;
|
||||
RPI::MaterialConverterBus::BroadcastResult(result, &RPI::MaterialConverterBus::Events::ConvertMaterial, *materialData, sourceData);
|
||||
if (result)
|
||||
|
||||
@@ -995,7 +995,7 @@ namespace AZ
|
||||
if (numInfluencesExcess > 0)
|
||||
{
|
||||
AZ_Warning(s_builderName, warnedExcessOfSkinInfluences,
|
||||
"Mesh %s has more skin influences (%d) than the maximum (%d). Skinning influences won't be normalized. Maximum number of skin influences can be increased with a Skin Modifier in FBX Settings.",
|
||||
"Mesh %s has more skin influences (%d) than the maximum (%d). Skinning influences won't be normalized. Maximum number of skin influences can be increased with a Skin Modifier in Scene Settings.",
|
||||
sourceMesh.m_name.GetCStr(),
|
||||
m_numSkinJointInfluencesPerVertex + numInfluencesExcess,
|
||||
m_numSkinJointInfluencesPerVertex);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ namespace AZ
|
||||
AZStd::string label;
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
// Material assets that are exported through the FBX pipeline have their filenames generated by adding
|
||||
// Material assets that are exported through the scene pipeline have their filenames generated by adding
|
||||
// the DCC material name as a prefix and a unique number to the end of the source file name.
|
||||
// Rather than storing the DCC material name inside of the material asset we can reproduce it by removing
|
||||
// the prefix and suffix from the product file name.
|
||||
|
||||
+24
-13
@@ -96,8 +96,11 @@ namespace AZ
|
||||
|
||||
bool SaveSourceMaterialFromEditData(const AZStd::string& path, const MaterialEditData& editData)
|
||||
{
|
||||
// Getting the source info for the material type file to make sure that it exists
|
||||
// We also need to watch folder to generate a relative asset path for the material type
|
||||
// Construct the material source data object that will be exported
|
||||
AZ::RPI::MaterialSourceData exportData;
|
||||
exportData.m_propertyLayoutVersion = editData.m_materialTypeSourceData.m_propertyLayout.m_version;
|
||||
|
||||
// Converting absolute material paths to relative paths
|
||||
bool result = false;
|
||||
AZ::Data::AssetInfo info;
|
||||
AZStd::string watchFolder;
|
||||
@@ -106,22 +109,30 @@ namespace AZ
|
||||
editData.m_materialTypeSourcePath.c_str(), info, watchFolder);
|
||||
if (!result)
|
||||
{
|
||||
AZ_Error("AZ::Render::EditorMaterialComponentUtil", false, "Failed to get source file info and asset path while attempting to export: %s", path.c_str());
|
||||
AZ_Error(
|
||||
"AZ::Render::EditorMaterialComponentUtil", false,
|
||||
"Failed to get material type source file info while attempting to export: %s", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct the material source data object that will be exported
|
||||
AZ::RPI::MaterialSourceData exportData;
|
||||
exportData.m_propertyLayoutVersion = editData.m_materialTypeSourceData.m_propertyLayout.m_version;
|
||||
exportData.m_materialType = info.m_relativePath;
|
||||
|
||||
// Converting absolute material paths to asset relative paths
|
||||
exportData.m_materialType = editData.m_materialTypeSourcePath;
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(
|
||||
&AzFramework::ApplicationRequests::Bus::Events::MakePathRelative, exportData.m_materialType, watchFolder.c_str());
|
||||
if (!editData.m_materialParentSourcePath.empty())
|
||||
{
|
||||
result = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath,
|
||||
editData.m_materialParentSourcePath.c_str(), info, watchFolder);
|
||||
if (!result)
|
||||
{
|
||||
AZ_Error(
|
||||
"AZ::Render::EditorMaterialComponentUtil", false,
|
||||
"Failed to get parent material source file info while attempting to export: %s", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
exportData.m_parentMaterial = editData.m_materialParentSourcePath;
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(
|
||||
&AzFramework::ApplicationRequests::Bus::Events::MakePathRelative, exportData.m_parentMaterial, watchFolder.c_str());
|
||||
exportData.m_parentMaterial = info.m_relativePath;
|
||||
}
|
||||
|
||||
// Copy all of the properties from the material asset to the source data that will be exported
|
||||
result = true;
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace AZ
|
||||
{
|
||||
return
|
||||
GetAssetId(key, RPI::MaterialAsset::RTTI_Type()).IsValid() &&
|
||||
// in case it's a source fbx, it will contain both material and model products
|
||||
// in case it's a source scene file, it will contain both material and model products
|
||||
// model thumbnails are handled by MeshThumbnail
|
||||
!GetAssetId(key, RPI::ModelAsset::RTTI_Type()).IsValid();
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace AZ
|
||||
skinnedSubMesh.m_vertexCount = aznumeric_cast<uint32_t>(subMeshVertexCount);
|
||||
lodVertexCount += aznumeric_cast<uint32_t>(subMeshVertexCount);
|
||||
|
||||
// The default material id used by a sub-mesh is the guid of the source .fbx plus the subId which is a unique material ID from the scene API
|
||||
// The default material id used by a sub-mesh is the guid of the source scene file plus the subId which is a unique material ID from the scene API
|
||||
AZ::u32 subId = modelMesh.GetMaterialAsset().GetId().m_subId;
|
||||
AZ::Data::AssetId materialId{ actorAssetId.m_guid, subId };
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Blast
|
||||
}
|
||||
else
|
||||
{
|
||||
// in this case we'll want to extract the physics meshes from the fbx.
|
||||
// in this case we'll want to extract the physics meshes from the scene file.
|
||||
// We don't necessarily have access to the mesh data though, so if we want to support this,
|
||||
// we'll need to come up with a way to associate with the mesh data
|
||||
// See BlastAssetModel in the SDK sample for how to create that data
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace EMotionFX
|
||||
}
|
||||
}
|
||||
|
||||
// Default to the first mesh group until we get a way to choose it via the FBX settings (ATOM-13590).
|
||||
// Default to the first mesh group until we get a way to choose it via the scene settings (ATOM-13590).
|
||||
AZStd::optional<AZ::Data::AssetId> meshAssetId = AZStd::nullopt;
|
||||
AZ_Error("EMotionFX", atomModelAssets.size() <= 1, "Ambigious mesh for actor asset. More than one mesh group found. Defaulting to the first one.");
|
||||
if (!atomModelAssets.empty())
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ namespace EMotionFX
|
||||
const AZ::u32 frameCount = aznumeric_caster(animation->GetKeyFrameCount());
|
||||
if (motionRangeRule->GetStartFrame() == 0 && motionRangeRule->GetEndFrame() == frameCount - 1)
|
||||
{
|
||||
// if the startframe/endframe matches the fbx animation length, remove it.
|
||||
// if the startframe/endframe matches the scene file's animation length, remove it.
|
||||
rules.RemoveRule(motionRangeRule);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace EMotionFX
|
||||
~IMotionGroup() override = default;
|
||||
|
||||
// Ability to specify root bone can be useful if there are multiple skeletons
|
||||
// stored in an fbx file or if the user wants to override the root bone automatically
|
||||
// stored in a scene file or if the user wants to override the root bone automatically
|
||||
// selected by the code.
|
||||
virtual const AZStd::string& GetSelectedRootBone() const = 0;
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace EMotionFX
|
||||
virtual size_t CalcStreamSaveSizeInBytes(const SaveSettings& saveSettings) const = 0;
|
||||
virtual AZ::u32 GetStreamSaveVersion() const = 0;
|
||||
virtual bool GetSupportsOptimizeSettings() const { return true; }
|
||||
virtual const char* GetFbxSettingsName() const = 0;
|
||||
virtual const char* GetSceneSettingsName() const = 0;
|
||||
|
||||
// Sampling
|
||||
virtual Transform SampleJointTransform(const SampleSettings& settings, AZ::u32 jointSkeletonIndex) const = 0;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace EMotionFX
|
||||
return aznew NonUniformMotionData();
|
||||
}
|
||||
|
||||
const char* NonUniformMotionData::GetFbxSettingsName() const
|
||||
const char* NonUniformMotionData::GetSceneSettingsName() const
|
||||
{
|
||||
return "Reduced Keyframes (slower, mostly smaller)";
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace EMotionFX
|
||||
bool Save(MCore::Stream* stream, const SaveSettings& saveSettings) const override;
|
||||
size_t CalcStreamSaveSizeInBytes(const SaveSettings& saveSettings) const override;
|
||||
AZ::u32 GetStreamSaveVersion() const override;
|
||||
const char* GetFbxSettingsName() const override;
|
||||
const char* GetSceneSettingsName() const override;
|
||||
|
||||
Transform SampleJointTransform(const SampleSettings& settings, AZ::u32 jointSkeletonIndex) const override;
|
||||
void SamplePose(const SampleSettings& settings, Pose* outputPose) const override;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace EMotionFX
|
||||
return aznew UniformMotionData();
|
||||
}
|
||||
|
||||
const char* UniformMotionData::GetFbxSettingsName() const
|
||||
const char* UniformMotionData::GetSceneSettingsName() const
|
||||
{
|
||||
return "Evenly Spaced Keyframes (faster, mostly larger)";
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace EMotionFX
|
||||
size_t CalcStreamSaveSizeInBytes(const SaveSettings& saveSettings) const override;
|
||||
AZ::u32 GetStreamSaveVersion() const override;
|
||||
bool GetSupportsOptimizeSettings() const override { return false; }
|
||||
const char* GetFbxSettingsName() const override;
|
||||
const char* GetSceneSettingsName() const override;
|
||||
|
||||
// Overloaded.
|
||||
Transform SampleJointTransform(const SampleSettings& settings, AZ::u32 jointSkeletonIndex) const override;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace EMotionFX
|
||||
const MotionDataFactory& factory = GetEMotionFX().GetMotionManager()->GetMotionDataFactory();
|
||||
for (size_t i = 0; i < factory.GetNumRegistered(); ++i)
|
||||
{
|
||||
GUI->addItem(factory.GetRegistered(i)->GetFbxSettingsName());
|
||||
GUI->addItem(factory.GetRegistered(i)->GetSceneSettingsName());
|
||||
m_typeIds.emplace_back(factory.GetRegistered(i)->RTTI_GetType());
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace EMotionFX
|
||||
bool m_forceUpdateJointsOOV = false;
|
||||
// \todo attachmentTarget node nr
|
||||
|
||||
// Note: LOD work in progress. For now we use one material instead of a list of material, because we don't have the support for LOD with multiple FBXs.
|
||||
// Note: LOD work in progress. For now we use one material instead of a list of material, because we don't have the support for LOD with multiple scene files.
|
||||
// We purposely kept a materialList in actorComponent and actorRenderNode for the flexibility in future.
|
||||
// At the moment, the materialList stores duplicates of the same material.
|
||||
AzFramework::SimpleAssetReference<LmbrCentral::MaterialAsset> m_materialPerActor;
|
||||
|
||||
@@ -485,7 +485,7 @@ namespace EMotionFX
|
||||
|
||||
SetMediaRoot("@assets@");
|
||||
// \todo Right now we're pointing at the @devassets@ location (source) and working from there, because .actor and .motion (motion) aren't yet processed through
|
||||
// the FBX pipeline. Once they are, we'll need to update various segments of the Tool to always read from the @assets@ cache, but write to the @devassets@ data/metadata.
|
||||
// the scene pipeline. Once they are, we'll need to update various segments of the Tool to always read from the @assets@ cache, but write to the @devassets@ data/metadata.
|
||||
EMotionFX::GetEMotionFX().InitAssetFolderPaths();
|
||||
|
||||
// Register EMotionFX event handler
|
||||
|
||||
@@ -770,13 +770,13 @@ namespace EMotionFX
|
||||
|
||||
TEST_F(PerformanceTestFixture, DISABLED_MotionSamplingPerformanceNonUniform)
|
||||
{
|
||||
// Make sure that the motion is set to use NonUniform sampling! Change this in the Fbx settings! Otherwise you get wrong results.
|
||||
// Make sure that the motion is set to use NonUniform sampling! Change this in the scene settings! Otherwise you get wrong results.
|
||||
TestMotionSamplingPerformance("@assets@\\animationsamples\\advanced_rinlocomotion\\motions\\rin_idle.motion");
|
||||
}
|
||||
|
||||
TEST_F(PerformanceTestFixture, DISABLED_MotionSamplingPerformanceUniform)
|
||||
{
|
||||
// Make sure that the motion is set to use Uniform sampling! Change this in the Fbx settings! Otherwise you get wrong results.
|
||||
// Make sure that the motion is set to use Uniform sampling! Change this in the scene settings! Otherwise you get wrong results.
|
||||
TestMotionSamplingPerformance("@assets@\\animationsamples\\advanced_rinlocomotion\\motions\\rin_walk_kick_01.motion");
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace EMotionFX
|
||||
LoadActor(actorFilename.toUtf8().data(), false);
|
||||
ASSERT_EQ(EMotionFX::GetActorManager().GetNumActorInstances(), 2) << "Failed to merge Actor.";
|
||||
|
||||
// We can't test Save Selected Actor as we would it would involve mocking fbx scene handling.
|
||||
// We can't test Save Selected Actor as we would it would involve mocking source scene handling.
|
||||
|
||||
// Add the filename to the recent actorsa anyway, so we can test that functionality.
|
||||
EMStudio::GetMainWindow()->AddRecentActorFile(actorFilename);
|
||||
@@ -634,7 +634,7 @@ namespace EMotionFX
|
||||
motionSet->SetFilename(motionsetFilename.toUtf8().constData());
|
||||
motionSet->SetDirtyFlag(true);
|
||||
|
||||
// Don't create an actor or motion as we can't save that due to fbx scene requirements.
|
||||
// Don't create an actor or motion as we can't save that due to source scene requirements.
|
||||
|
||||
EMStudio::Workspace* workspace = EMStudio::GetManager()->GetWorkspace();
|
||||
const QString workspaceFilename = GenerateTempWorkspaceFilename();
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace LmbrCentral
|
||||
};
|
||||
|
||||
/*!
|
||||
* FBX Material asset type configuration.
|
||||
* Reflect as: AzFramework::SimpleAssetReference<FbxMaterialAsset>
|
||||
* Source scene file Material asset type configuration.
|
||||
* Reflect as: AzFramework::SimpleAssetReference<DccMaterialAsset>
|
||||
*/
|
||||
class DccMaterialAsset
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace NvCloth
|
||||
|
||||
// Mesh Node
|
||||
->DataElement(Editor::MeshNodeSelector, &ClothConfiguration::m_meshNode, "Mesh node",
|
||||
"List of mesh nodes with cloth simulation data. These are the nodes selected inside Cloth Modifiers in FBX Editor Settings.")
|
||||
"List of mesh nodes with cloth simulation data. These are the nodes selected inside Cloth Modifiers in Scene Settings.")
|
||||
->Attribute(AZ::Edit::UIHandlers::EntityId, &ClothConfiguration::GetEntityId)
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &ClothConfiguration::PopulateMeshNodeList)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace NvCloth
|
||||
{
|
||||
widget_t* picker = new widget_t(parent);
|
||||
|
||||
// Set edit button appearance to go to FBX Settings dialog
|
||||
picker->GetEditButton()->setToolTip("Open FBX Settings to setup Cloth Modifiers");
|
||||
// Set edit button appearance to go to Scene Settings dialog
|
||||
picker->GetEditButton()->setToolTip("Open Scene Settings to setup Cloth Modifiers");
|
||||
picker->GetEditButton()->setText("");
|
||||
picker->GetEditButton()->setEnabled(false);
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace NvCloth
|
||||
AZ::Data::Asset<AZ::Data::AssetData> meshAsset = GetMeshAsset(GUI->GetEntityId());
|
||||
if (meshAsset)
|
||||
{
|
||||
// Open the asset with the preferred asset editor, which for Mesh and Actor Assets it's FBX Settings.
|
||||
// Open the asset with the preferred asset editor, which for Mesh and Actor Assets it's Scene Settings.
|
||||
bool handled = false;
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Broadcast(
|
||||
&AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotifications::OpenAssetInAssociatedEditor, meshAsset.GetId(), handled);
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace NvCloth
|
||||
namespace Pipeline
|
||||
{
|
||||
// It's necessary for the rule to specify the system allocator, otherwise
|
||||
// the editor crashes when deleting the cloth modifier from FBX Settings.
|
||||
// the editor crashes when deleting the cloth modifier from Scene Settings.
|
||||
AZ_CLASS_ALLOCATOR_IMPL(ClothRule, AZ::SystemAllocator, 0)
|
||||
|
||||
const char* const ClothRule::DefaultChooseNodeName = "Choose a node";
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace NvCloth
|
||||
[[maybe_unused]] const AZ::SceneAPI::Containers::Scene& scene,
|
||||
AZ::SceneAPI::DataTypes::IManifestObject& target)
|
||||
{
|
||||
// When a cloth rule is created in the FBX Editor Settings...
|
||||
// When a cloth rule is created in the Scene Settings...
|
||||
if (target.RTTI_IsTypeOf(ClothRule::TYPEINFO_Uuid()))
|
||||
{
|
||||
ClothRule* clothRule = azrtti_cast<ClothRule*>(&target);
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace NvCloth
|
||||
//! It specifies the valid Scene Groups that are allowed to have
|
||||
//! cloth rules (aka cloth modifiers), these are Mesh and Actor groups.
|
||||
//! It also validates the cloth rules data for the manifest (asset containing
|
||||
//! all the Scene information from the FBX Editor Settings).
|
||||
//! all the Scene information from the Scene Settings).
|
||||
class ClothRuleBehavior
|
||||
: public AZ::SceneAPI::SceneCore::BehaviorComponent
|
||||
, public AZ::SceneAPI::Events::ManifestMetaInfoBus::Handler
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace PhysX
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorProxyAssetShapeConfig::m_pxAsset, "PhysX Mesh", "PhysX mesh collider asset")
|
||||
->Attribute(AZ_CRC_CE("EditButton"), "")
|
||||
->Attribute(AZ_CRC_CE("EditDescription"), "Open in FBX Settings")
|
||||
->Attribute(AZ_CRC_CE("EditDescription"), "Open in Scene Settings")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorProxyAssetShapeConfig::m_configuration, "Configuration", "Configuration of asset shape")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace PhysX
|
||||
;
|
||||
|
||||
// Note: This class needs to have edit context reflection so PropertyAssetCtrl::OnEditButtonClicked
|
||||
// can open the asset with the preferred asset editor (FBX Settings).
|
||||
// can open the asset with the preferred asset editor (Scene Settings).
|
||||
if (auto* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<MeshAsset>("PhysX Mesh Asset", "")
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace PhysX
|
||||
}
|
||||
} pxDefaultErrorCallback;
|
||||
|
||||
// A struct to store the geometry data per FBX node
|
||||
// A struct to store the geometry data per scene node
|
||||
struct NodeCollisionGeomExportData
|
||||
{
|
||||
AZStd::vector<Vec3> m_vertices;
|
||||
@@ -500,10 +500,10 @@ namespace PhysX
|
||||
assetData.m_materialNames = meshGroup.GetMaterialSlots();
|
||||
assetData.m_physicsMaterialNames = meshGroup.GetPhysicsMaterials();
|
||||
|
||||
// Updating materials lists from new materials gathered from fbx
|
||||
// because this exporter runs when the FBX is being processed, which
|
||||
// Updating materials lists from new materials gathered from the source scene file
|
||||
// because this exporter runs when the source scene is being processed, which
|
||||
// could have a different content from when the mesh group info was
|
||||
// entered in FBX Settings Editor.
|
||||
// entered in Scene Settings Editor.
|
||||
if (!Utils::UpdateAssetPhysicsMaterials(assetMaterialsData.m_fbxMaterialNames, assetData.m_materialNames, assetData.m_physicsMaterialNames))
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Failure;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace PhysX
|
||||
//! A struct to store the materials of the mesh nodes selected in a mesh group.
|
||||
struct AssetMaterialsData
|
||||
{
|
||||
//! Material names coming from FBX.
|
||||
//! Material names coming from the source scene file.
|
||||
AZStd::vector<AZStd::string> m_fbxMaterialNames;
|
||||
|
||||
//! Look-up table for fbxMaterialNames.
|
||||
|
||||
@@ -326,6 +326,12 @@ namespace PhysX
|
||||
|
||||
AzPhysics::SceneQueryHit Shape::RayCastInternal(const AzPhysics::RayCastRequest& worldSpaceRequest, const physx::PxTransform& pose)
|
||||
{
|
||||
if (const bool shouldCollide = worldSpaceRequest.m_collisionGroup.GetMask() & m_collisionLayer.GetMask();
|
||||
!shouldCollide)
|
||||
{
|
||||
return AzPhysics::SceneQueryHit();
|
||||
}
|
||||
|
||||
const physx::PxVec3 start = PxMathConvert(worldSpaceRequest.m_start);
|
||||
const physx::PxVec3 unitDir = PxMathConvert(worldSpaceRequest.m_direction);
|
||||
const physx::PxU32 maxHits = 1;
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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 <PhysX_precompiled.h>
|
||||
#include "PhysXTestFixtures.h"
|
||||
#include "PhysXTestUtil.h"
|
||||
#include "PhysXTestCommon.h"
|
||||
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/Script/lua/lua.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Math/MathReflection.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzFramework/Physics/Utils.h>
|
||||
#include <AzCore/Math/MathReflection.h>
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
|
||||
namespace PhysX
|
||||
{
|
||||
static AZStd::map<AZStd::string, EntityPtr> s_testEntities;
|
||||
|
||||
AZ::EntityId GetTestEntityId(const char* name)
|
||||
{
|
||||
if (auto it = s_testEntities.find(name);
|
||||
it != s_testEntities.end())
|
||||
{
|
||||
return it->second->GetId();
|
||||
}
|
||||
|
||||
return AZ::EntityId();
|
||||
}
|
||||
|
||||
// this allows EXPECT_TRUE to be exposed to the behavior context and used inside blocks of lua code which
|
||||
// are executed in tests
|
||||
void ExpectTrue(bool check)
|
||||
{
|
||||
EXPECT_TRUE(check);
|
||||
}
|
||||
|
||||
class PhysXScriptTest
|
||||
: public PhysXDefaultWorldTest
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(PhysXScriptTest, "{337A9DB4-ACF7-42A7-92E5-48A9FF14B49C}");
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
PhysXDefaultWorldTest::SetUp();
|
||||
|
||||
m_behaviorContext = AZStd::make_unique<AZ::BehaviorContext>();
|
||||
AZ::Entity::Reflect(m_behaviorContext.get());
|
||||
AZ::MathReflect(m_behaviorContext.get());
|
||||
AzFramework::EntityContext::Reflect(m_behaviorContext.get());
|
||||
Physics::ReflectionUtils::ReflectPhysicsApi(m_behaviorContext.get());
|
||||
m_behaviorContext->Method("ExpectTrue", &ExpectTrue);
|
||||
m_behaviorContext->Method("GetTestEntityId", &GetTestEntityId);
|
||||
m_scriptContext = AZStd::make_unique<AZ::ScriptContext>();
|
||||
m_scriptContext->BindTo(m_behaviorContext.get());
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
s_testEntities.clear();
|
||||
|
||||
m_scriptContext.reset();
|
||||
m_behaviorContext.reset();
|
||||
|
||||
PhysXDefaultWorldTest::TearDown();
|
||||
}
|
||||
|
||||
AZ::BehaviorContext* GetBehaviorContext()
|
||||
{
|
||||
return m_behaviorContext.get();
|
||||
}
|
||||
|
||||
AZ::ScriptContext* GetScriptContext()
|
||||
{
|
||||
return m_scriptContext.get();
|
||||
}
|
||||
|
||||
private:
|
||||
AZStd::unique_ptr<AZ::BehaviorContext> m_behaviorContext;
|
||||
AZStd::unique_ptr<AZ::ScriptContext> m_scriptContext;
|
||||
};
|
||||
|
||||
TEST_F(PhysXScriptTest, ScriptedRaycast_RaycastNotIntersectingBox_ReturnsNoHits)
|
||||
{
|
||||
s_testEntities.insert(
|
||||
{
|
||||
"Box",
|
||||
TestUtils::AddStaticUnitTestObject<BoxColliderComponent>(GetDefaultSceneHandle(), AZ::Vector3::CreateZero(), "Box")
|
||||
});
|
||||
|
||||
const char luaCode[] =
|
||||
R"(
|
||||
boxId = GetTestEntityId("Box")
|
||||
request = RayCastRequest()
|
||||
request.Start = Vector3(5.0, 0.0, 5.0)
|
||||
request.Direction = Vector3(0.0, 0.0, -1.0)
|
||||
request.Distance = 10.0
|
||||
hit = SimulatedBodyComponentRequestBus.Event.RayCast(boxId, request)
|
||||
ExpectTrue(hit.EntityId == EntityId())
|
||||
)";
|
||||
|
||||
EXPECT_TRUE(GetScriptContext()->Execute(luaCode));
|
||||
}
|
||||
|
||||
TEST_F(PhysXScriptTest, ScriptedRaycast_RaycastIntersectingBox_ReturnsHitOnBox)
|
||||
{
|
||||
s_testEntities.insert(
|
||||
{
|
||||
"Box",
|
||||
TestUtils::AddStaticUnitTestObject<BoxColliderComponent>(GetDefaultSceneHandle(), AZ::Vector3::CreateZero(), "Box")
|
||||
});
|
||||
|
||||
const char luaCode[] =
|
||||
R"(
|
||||
boxId = GetTestEntityId("Box")
|
||||
request = RayCastRequest()
|
||||
request.Start = Vector3(0.0, 0.0, 5.0)
|
||||
request.Direction = Vector3(0.0, 0.0, -1.0)
|
||||
request.Distance = 10.0
|
||||
hit = SimulatedBodyComponentRequestBus.Event.RayCast(boxId, request)
|
||||
ExpectTrue(hit.EntityId == boxId)
|
||||
)";
|
||||
|
||||
EXPECT_TRUE(GetScriptContext()->Execute(luaCode));
|
||||
}
|
||||
|
||||
TEST_F(PhysXScriptTest, ScriptedRaycast_RaycastNotInteractingCollisionFilters_ReturnsNoHit)
|
||||
{
|
||||
s_testEntities.insert(
|
||||
{
|
||||
"Box",
|
||||
TestUtils::AddStaticUnitTestObject<BoxColliderComponent>(GetDefaultSceneHandle(), AZ::Vector3::CreateZero(), "Box")
|
||||
});
|
||||
|
||||
const char luaCode[] =
|
||||
R"(
|
||||
boxId = GetTestEntityId("Box")
|
||||
request = RayCastRequest()
|
||||
request.Start = Vector3(0.0, 0.0, 5.0)
|
||||
request.Direction = Vector3(0.0, 0.0, -1.0)
|
||||
request.Distance = 10.0
|
||||
request.Collision = CollisionGroup("None")
|
||||
hit = SimulatedBodyComponentRequestBus.Event.RayCast(boxId, request)
|
||||
ExpectTrue(hit.EntityId == EntityId())
|
||||
)";
|
||||
|
||||
EXPECT_TRUE(GetScriptContext()->Execute(luaCode));
|
||||
}
|
||||
} // namespace PhysX
|
||||
@@ -29,6 +29,7 @@ set(FILES
|
||||
Tests/PhysXTestUtil.h
|
||||
Tests/PhysXTestUtil.cpp
|
||||
Tests/PhysXMultithreadingTest.cpp
|
||||
Tests/PhysXScriptTest.cpp
|
||||
Tests/CharacterControllerTests.cpp
|
||||
Tests/RagdollConfiguration.xml
|
||||
Tests/RagdollTestData.h
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace AZ
|
||||
* AddFileSoftName("_anim", PatternMatcher::MatchApproach::PostFix, "Ignore", false,
|
||||
* SceneAPI::DataTypes::IAnimationData::TYPEINFO_Name())
|
||||
* If the filename ends with "_anim" this will mark all nodes as "Ignore" unless they're derived from IAnimationData.
|
||||
* This will cause only animations to be exported from the .fbx file even if there's other data available.
|
||||
* This will cause only animations to be exported from the source scene file even if there's other data available.
|
||||
*/
|
||||
virtual bool AddFileSoftName(const char* pattern, SceneAPI::SceneCore::PatternMatcher::MatchApproach approach,
|
||||
const char* virtualType, bool inclusive, const AZStd::string& graphObjectTypeName) = 0;
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@ namespace AZ
|
||||
m_softNames.push_back(aznew NodeSoftNameSetting("^.*_[Pp][Hh][Yy][Ss](_optimized)?$", PatternMatcher::MatchApproach::Regex, "PhysicsMesh", true));
|
||||
m_softNames.push_back(aznew NodeSoftNameSetting("_ignore", PatternMatcher::MatchApproach::PostFix, "Ignore", false));
|
||||
// If the filename ends with "_anim" this will mark all nodes as "Ignore" unless they're derived from IAnimationData. This will
|
||||
// cause only animations to be exported from the .fbx file even if there's other data available.
|
||||
// cause only animations to be exported from the source scene file even if there's other data available.
|
||||
m_softNames.push_back(aznew FileSoftNameSetting("_anim", PatternMatcher::MatchApproach::PostFix, "Ignore", false,
|
||||
{ FileSoftNameSetting::GraphType(SceneAPI::DataTypes::IAnimationData::TYPEINFO_Name()) }));
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace AZ
|
||||
"Soft naming conventions", "Update the naming conventions to suit your project.")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, false)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SceneProcessingConfigSystemComponent::m_UseCustomNormals,
|
||||
"Use Custom Normals", "When enabled, Open 3D Engine will use the DCC assets custom or tangent space normals. When disabled, the normals will be averaged. This setting can be overridden on individual FBX asset settings.")
|
||||
"Use Custom Normals", "When enabled, Open 3D Engine will use the DCC assets custom or tangent space normals. When disabled, the normals will be averaged. This setting can be overridden on an individual scene file's asset settings.")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, false);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -107,7 +107,7 @@ namespace AZ::SceneGenerationComponents
|
||||
return AZ::SceneAPI::Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
// Now that we have the tangents and bitangents, calculate the tangent w values for the ones that we imported from Fbx, as they only have xyz.
|
||||
// Now that we have the tangents and bitangents, calculate the tangent w values for the ones that we imported from the scene file, as they only have xyz.
|
||||
UpdateFbxTangentWValues(graph, nodeIndex, mesh);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace AZ::SceneGenerationComponents
|
||||
size_t uvSetIndex = 0;
|
||||
while (uvData)
|
||||
{
|
||||
// Get the tangents and bitangents from Fbx.
|
||||
// Get the tangents and bitangents from the source scene.
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace AZ::SceneGenerationComponents
|
||||
return true; // No fatal error
|
||||
}
|
||||
|
||||
// Check if we had tangents inside the Fbx file.
|
||||
// Check if we had tangents inside the source scene file.
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
|
||||
@@ -211,7 +211,7 @@ namespace AZ::SceneGenerationComponents
|
||||
requiredSpaces.emplace_back(AZ::SceneAPI::DataTypes::TangentSpace::MikkT);
|
||||
}
|
||||
|
||||
// If all we need is import from FBX, and we have tangent data from Fbx already, then skip generating.
|
||||
// If all we need is import from the source scene, and we have tangent data from the source scene already, then skip generating.
|
||||
if ((requiredSpaces.size() == 1 && requiredSpaces[0] == AZ::SceneAPI::DataTypes::TangentSpace::FromFbx) && fbxTangentData && fbxBitangentData)
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace SceneBuilder
|
||||
if (m_cachedFingerprint.empty())
|
||||
{
|
||||
// put them in an ORDERED set so that changing the reflection
|
||||
// or the gems loaded does not invalidate FBX files due to order of reflection changing.
|
||||
// or the gems loaded does not invalidate scene files due to order of reflection changing.
|
||||
AZStd::set<AZStd::string> fragments;
|
||||
|
||||
AZ::SerializeContext* context = nullptr;
|
||||
@@ -350,7 +350,7 @@ namespace SceneBuilder
|
||||
AZ::u32 SceneBuilderWorker::BuildSubId(const AZ::SceneAPI::Events::ExportProduct& product) const
|
||||
{
|
||||
// Instead of the just the lower 16-bits, use the full 32-bits that are available. There are production examples of
|
||||
// uber-fbx files that contain hundreds of meshes that need to be split into individual mesh objects as an example.
|
||||
// uber-scene files that contain hundreds of meshes that need to be split into individual mesh objects as an example.
|
||||
AZ::u32 id = static_cast<AZ::u32>(product.m_id.GetHash());
|
||||
|
||||
if (product.m_lod.has_value())
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION": "profile",
|
||||
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
|
||||
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_DISABLE_TEST_MODULES=TRUE -DCPACK_WIX_ROOT=\"!WIX! \"",
|
||||
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DCPACK_WIX_ROOT=\"!WIX! \"",
|
||||
"EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=https://dkb1uj4hs9ikv.cloudfront.net -DLY_INSTALLER_LICENSE_URL=https://www.o3debinaries.org/license -DLY_INSTALLER_3RD_PARTY_LICENSE_URL=https://dkb1uj4hs9ikv.cloudfront.net/SPDX-Licenses.txt",
|
||||
"CPACK_BUCKET": "spectra-prism-staging-us-west-2",
|
||||
"CMAKE_LY_PROJECTS": "",
|
||||
|
||||
Reference in New Issue
Block a user