Merge branch 'stabilization/2106' into LYN-4507
This commit is contained in:
+11
-7
@@ -2,10 +2,14 @@
|
||||
# Default LFS endpoint for this repository
|
||||
url=https://d3df09qsjufr6g.cloudfront.net/api/v1
|
||||
|
||||
# To use the endpoint with your fork:
|
||||
# 1. uncomment the url line below by removing the '#'
|
||||
# 2. replace 'owner' with the username or organization that owns the fork
|
||||
# 3. have git ignore your local modification of this file by running
|
||||
# git update-index --skip-worktree .lfsconfig
|
||||
|
||||
# url=https://d3df09qsjufr6g.cloudfront.net/api/v1/fork/owner
|
||||
# To use the endpoint with your fork, run the following git command
|
||||
# in your local repository (without the '#'), replacing 'owner' with
|
||||
# the username or organization that owns the fork.
|
||||
#
|
||||
# git config lfs.url "https://d3df09qsjufr6g.cloudfront.net/api/v1/fork/owner"
|
||||
#
|
||||
# For example, if your fork is https://github.com/octocat/o3de use
|
||||
# git config lfs.url "https://d3df09qsjufr6g.cloudfront.net/api/v1/fork/octocat"
|
||||
#
|
||||
# IMPORTANT: authenticate with your GitHub username and personal access token
|
||||
# not your GitHub password
|
||||
|
||||
@@ -51,7 +51,7 @@ set(ENABLED_GEMS
|
||||
)
|
||||
|
||||
# TODO remove conditional add once AWSNativeSDK libs are fixed for Android and Linux Monolithic release.
|
||||
set(aws_excluded_platforms Linux Android)
|
||||
set(aws_excluded_platforms Android)
|
||||
if (NOT (LY_MONOLITHIC_GAME AND ${PAL_PLATFORM_NAME} IN_LIST aws_excluded_platforms))
|
||||
list(APPEND ENABLED_GEMS
|
||||
AWSCore
|
||||
|
||||
@@ -22,7 +22,9 @@ AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option")
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/JSON/document.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
|
||||
@@ -195,8 +197,15 @@ CEditorImpl::CEditorImpl()
|
||||
m_pAssetBrowserRequestHandler = nullptr;
|
||||
m_assetEditorRequestsHandler = nullptr;
|
||||
|
||||
AZ::IO::SystemFile::CreateDir("SessionStatus");
|
||||
QFile::setPermissions(m_crashLogFileName, QFileDevice::ReadOther | QFileDevice::WriteOther);
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if (AZ::IO::FixedMaxPath crashLogPath; settingsRegistry->Get(crashLogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath))
|
||||
{
|
||||
crashLogPath /= m_crashLogFileName;
|
||||
AZ::IO::SystemFile::CreateDir(crashLogPath.ParentPath().FixedMaxPathString().c_str());
|
||||
QFile::setPermissions(crashLogPath.c_str(), QFileDevice::ReadOther | QFileDevice::WriteOther);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEditorImpl::Initialize()
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:263e95489560dac6e5944ef3caba13e598f83ddead324b943ad7735ba015e1a9
|
||||
size 70727
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1cf8339fb51f82a68d2ab475c0476960e75a79d96d239c5b7cd272fbe4990ffe
|
||||
size 2770
|
||||
@@ -75,6 +75,21 @@ WelcomeScreenDialog::WelcomeScreenDialog(QWidget* pParent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// Set the project preview image
|
||||
QString projectPreviewPath = QDir(AZ::Utils::GetProjectPath().c_str()).filePath("preview.png");
|
||||
QFileInfo projectPreviewPathInfo(projectPreviewPath);
|
||||
if (!projectPreviewPathInfo.exists() || !projectPreviewPathInfo.isFile())
|
||||
{
|
||||
projectPreviewPath = ":/WelcomeScreenDialog/DefaultProjectImage.png";
|
||||
}
|
||||
ui->activeProjectIcon->setPixmap(
|
||||
QPixmap(projectPreviewPath).scaled(
|
||||
ui->activeProjectIcon->size(),
|
||||
Qt::KeepAspectRatioByExpanding,
|
||||
Qt::SmoothTransformation
|
||||
)
|
||||
);
|
||||
|
||||
ui->recentLevelTable->setColumnCount(3);
|
||||
ui->recentLevelTable->setMouseTracking(true);
|
||||
ui->recentLevelTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="WelcomeScreenDialog">
|
||||
<file>DefaultActiveProject.png</file>
|
||||
<file>DefaultProjectImage.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -158,11 +158,8 @@
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="WelcomeScreenDialog.qrc">:/WelcomeScreenDialog/DefaultActiveProject.png</pixmap>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignHCenter | Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -229,7 +229,6 @@ set(FILES
|
||||
res/warning16x16.ico
|
||||
res/water.bmp
|
||||
res/work_in_progress_icon.ico
|
||||
res/LegacyLogo.bmp
|
||||
res/MannFileManagerImageList.bmp
|
||||
res/infobar/CameraCollision-default.svg
|
||||
res/infobar/GotoLocation-default.svg
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:97f4004da6ec1bf07d522d6675f814e53e36923a45084ff5d7e4113e293d4fec
|
||||
size 117656
|
||||
@@ -41,7 +41,7 @@ ly_add_target(
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
NAME AmazonQtControlGallery APPLICATION
|
||||
NAME O3DEQtControlGallery APPLICATION
|
||||
NAMESPACE AZ
|
||||
AUTOMOC
|
||||
AUTOUIC
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <AzToolsFramework/UI/UICore/QTreeViewStateSaver.hxx>
|
||||
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
|
||||
#include <AzToolsFramework/UI/UICore/ProgressShield.hxx>
|
||||
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
|
||||
#include <AzToolsFramework/Slice/SliceUtilities.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponent.h>
|
||||
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
|
||||
@@ -1589,7 +1590,13 @@ namespace AzToolsFramework
|
||||
// Multiple changes to the same entity are just split between different undo nodes.
|
||||
for (AZ::EntityId entityId : m_dirtyEntities)
|
||||
{
|
||||
prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityId, m_currentBatchUndo);
|
||||
auto outcome = prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityId, m_currentBatchUndo);
|
||||
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
QMessageBox::warning(
|
||||
AzToolsFramework::GetActiveWindow(), QString("Error"), QString(outcome.GetError().c_str()), QMessageBox::Ok, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,21 +587,21 @@ namespace AzToolsFramework
|
||||
return AZ::Success(entityId);
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache(
|
||||
PrefabOperationResult PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache(
|
||||
AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch)
|
||||
{
|
||||
// Create Undo node on entities if they belong to an instance
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
if (!owningInstance.has_value())
|
||||
{
|
||||
return;
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
AZ::Entity* entity = GetEntityById(entityId);
|
||||
if (!entity)
|
||||
{
|
||||
m_prefabUndoCache.PurgeCache(entityId);
|
||||
return;
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PrefabDom beforeState;
|
||||
@@ -633,6 +633,41 @@ namespace AzToolsFramework
|
||||
(&beforeOwningInstance->get() != &afterOwningInstance->get()))
|
||||
{
|
||||
isNewParentOwnedByDifferentInstance = true;
|
||||
|
||||
// Detect loops. Assert if an instance has been reparented in such a way to generate circular dependencies.
|
||||
AZStd::vector<Instance*> instancesInvolved;
|
||||
|
||||
if (isInstanceContainerEntity)
|
||||
{
|
||||
instancesInvolved.push_back(&owningInstance->get());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Retrieve all nested instances that are part of the subtree under the current entity.
|
||||
EntityList entities;
|
||||
RetrieveAndSortPrefabEntitiesAndInstances({ entity }, beforeOwningInstance->get(), entities, instancesInvolved);
|
||||
}
|
||||
|
||||
for (Instance* instance : instancesInvolved)
|
||||
{
|
||||
const PrefabDom& templateDom =
|
||||
m_prefabSystemComponentInterface->FindTemplateDom(instance->GetTemplateId());
|
||||
AZStd::unordered_set<AZ::IO::Path> templatePaths;
|
||||
PrefabDomUtils::GetTemplateSourcePaths(templateDom, templatePaths);
|
||||
|
||||
if (IsCyclicalDependencyFound(afterOwningInstance->get(), templatePaths))
|
||||
{
|
||||
// Cancel the operation by restoring the previous parent
|
||||
AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetParent, beforeParentId);
|
||||
m_prefabUndoCache.UpdateCache(entityId);
|
||||
|
||||
// Skip the creation of an undo node
|
||||
return AZ::Failure(AZStd::string::format(
|
||||
"Reparent Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
|
||||
instance->GetTemplateSourcePath().Native().c_str(),
|
||||
afterOwningInstance->get().GetTemplateSourcePath().Native().c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,6 +708,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
m_prefabUndoCache.UpdateCache(entityId);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::Internal_HandleContainerOverride(
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AzToolsFramework
|
||||
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
|
||||
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
|
||||
|
||||
void GenerateUndoNodesForEntityChangeAndUpdateCache(AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) override;
|
||||
PrefabOperationResult GenerateUndoNodesForEntityChangeAndUpdateCache(AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) override;
|
||||
|
||||
bool IsInstanceContainerEntity(AZ::EntityId entityId) const override;
|
||||
bool IsLevelInstanceContainerEntity(AZ::EntityId entityId) const override;
|
||||
|
||||
@@ -79,8 +79,9 @@ namespace AzToolsFramework
|
||||
*
|
||||
* @param entityId The entity to patch.
|
||||
* @param parentUndoBatch The undo batch the undo nodes should be parented to.
|
||||
* @return Returns Success if the node was generated correctly, or an error message otherwise.
|
||||
*/
|
||||
virtual void GenerateUndoNodesForEntityChangeAndUpdateCache(
|
||||
virtual PrefabOperationResult GenerateUndoNodesForEntityChangeAndUpdateCache(
|
||||
AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,7 +84,10 @@ namespace AssetProcessor
|
||||
AssetProcessorTest::TearDown();
|
||||
}
|
||||
|
||||
void OnError([[maybe_unused]] const AZ::IO::SystemFile* file, const char* fileName, int errorCode) override
|
||||
void OnError(
|
||||
[[maybe_unused]] const AZ::IO::SystemFile* file,
|
||||
[[maybe_unused]] const char* fileName,
|
||||
[[maybe_unused]] int errorCode) override
|
||||
{
|
||||
AZ_Error("LegacyTestAdapter", false, "File error detected with %s with code %d", fileName, errorCode);
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
|
||||
set(FILES
|
||||
Python_linux.cpp
|
||||
ProjectBuilderWorker_linux.cpp
|
||||
)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 <ProjectBuilderWorker.h>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
AZ::Outcome<void, QString> ProjectBuilderWorker::BuildProjectForPlatform()
|
||||
{
|
||||
QString error = tr("Automatic building on Linux not currently supported!");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -7,4 +7,5 @@
|
||||
|
||||
set(FILES
|
||||
Python_mac.cpp
|
||||
ProjectBuilderWorker_mac.cpp
|
||||
)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 <ProjectBuilderWorker.h>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
AZ::Outcome<void, QString> ProjectBuilderWorker::BuildProjectForPlatform()
|
||||
{
|
||||
QString error = tr("Automatic building on MacOS not currently supported!");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -7,4 +7,5 @@
|
||||
|
||||
set(FILES
|
||||
Python_windows.cpp
|
||||
ProjectBuilderWorker_windows.cpp
|
||||
)
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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 <ProjectBuilderWorker.h>
|
||||
#include <ProjectManagerDefs.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QTextStream>
|
||||
#include <QThread>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
AZ::Outcome<void, QString> ProjectBuilderWorker::BuildProjectForPlatform()
|
||||
{
|
||||
// Check if we are trying to cancel task
|
||||
if (QThread::currentThread()->isInterruptionRequested())
|
||||
{
|
||||
QStringToAZTracePrint(BuildCancelled);
|
||||
return AZ::Failure(BuildCancelled);
|
||||
}
|
||||
|
||||
QFile logFile(GetLogFilePath());
|
||||
if (!logFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
|
||||
{
|
||||
QString error = tr("Failed to open log file.");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
EngineInfo engineInfo;
|
||||
|
||||
AZ::Outcome<EngineInfo> engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo();
|
||||
if (engineInfoResult.IsSuccess())
|
||||
{
|
||||
engineInfo = engineInfoResult.GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString error = tr("Failed to get engine info.");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
QTextStream logStream(&logFile);
|
||||
if (QThread::currentThread()->isInterruptionRequested())
|
||||
{
|
||||
logFile.close();
|
||||
QStringToAZTracePrint(BuildCancelled);
|
||||
return AZ::Failure(BuildCancelled);
|
||||
}
|
||||
|
||||
// Show some kind of progress with very approximate estimates
|
||||
UpdateProgress(++m_progressEstimate);
|
||||
|
||||
QProcessEnvironment currentEnvironment(QProcessEnvironment::systemEnvironment());
|
||||
// Append cmake path to PATH incase it is missing
|
||||
QDir cmakePath(engineInfo.m_path);
|
||||
cmakePath.cd("cmake/runtime/bin");
|
||||
QString pathValue = currentEnvironment.value("PATH");
|
||||
pathValue += ";" + cmakePath.path();
|
||||
currentEnvironment.insert("PATH", pathValue);
|
||||
|
||||
m_configProjectProcess = new QProcess(this);
|
||||
m_configProjectProcess->setProcessChannelMode(QProcess::MergedChannels);
|
||||
m_configProjectProcess->setWorkingDirectory(m_projectInfo.m_path);
|
||||
m_configProjectProcess->setProcessEnvironment(currentEnvironment);
|
||||
|
||||
m_configProjectProcess->start(
|
||||
"cmake",
|
||||
QStringList{ "-B", QDir(m_projectInfo.m_path).filePath(ProjectBuildPathPostfix), "-S", m_projectInfo.m_path, "-G",
|
||||
"Visual Studio 16", "-DLY_3RDPARTY_PATH=" + engineInfo.m_thirdPartyPath });
|
||||
|
||||
if (!m_configProjectProcess->waitForStarted())
|
||||
{
|
||||
QString error = tr("Configuring project failed to start.");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
bool containsGeneratingDone = false;
|
||||
while (m_configProjectProcess->waitForReadyRead(MaxBuildTimeMSecs))
|
||||
{
|
||||
QString configOutput = m_configProjectProcess->readAllStandardOutput();
|
||||
|
||||
if (configOutput.contains("Generating done"))
|
||||
{
|
||||
containsGeneratingDone = true;
|
||||
}
|
||||
|
||||
logStream << configOutput;
|
||||
logStream.flush();
|
||||
|
||||
UpdateProgress(qMin(++m_progressEstimate, 19));
|
||||
|
||||
if (QThread::currentThread()->isInterruptionRequested())
|
||||
{
|
||||
logFile.close();
|
||||
m_configProjectProcess->close();
|
||||
QStringToAZTracePrint(BuildCancelled);
|
||||
return AZ::Failure(BuildCancelled);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_configProjectProcess->exitCode() != 0 || !containsGeneratingDone)
|
||||
{
|
||||
QString error = tr("Configuring project failed. See log for details.");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
UpdateProgress(++m_progressEstimate);
|
||||
|
||||
m_buildProjectProcess = new QProcess(this);
|
||||
m_buildProjectProcess->setProcessChannelMode(QProcess::MergedChannels);
|
||||
m_buildProjectProcess->setWorkingDirectory(m_projectInfo.m_path);
|
||||
m_buildProjectProcess->setProcessEnvironment(currentEnvironment);
|
||||
|
||||
m_buildProjectProcess->start(
|
||||
"cmake",
|
||||
QStringList{ "--build", QDir(m_projectInfo.m_path).filePath(ProjectBuildPathPostfix), "--target",
|
||||
m_projectInfo.m_projectName + ".GameLauncher", "Editor", "--config", "profile" });
|
||||
|
||||
if (!m_buildProjectProcess->waitForStarted())
|
||||
{
|
||||
QString error = tr("Building project failed to start.");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
// There are a lot of steps when building so estimate around 800 more steps ((100 - 20) * 10) remaining
|
||||
m_progressEstimate = 200;
|
||||
while (m_buildProjectProcess->waitForReadyRead(MaxBuildTimeMSecs))
|
||||
{
|
||||
logStream << m_buildProjectProcess->readAllStandardOutput();
|
||||
logStream.flush();
|
||||
|
||||
// Show 1% progress for every 10 steps completed
|
||||
UpdateProgress(qMin(++m_progressEstimate / 10, 99));
|
||||
|
||||
if (QThread::currentThread()->isInterruptionRequested())
|
||||
{
|
||||
// QProcess is unable to kill its child processes so we need to ask the operating system to do that for us
|
||||
QProcess killBuildProcess;
|
||||
killBuildProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
killBuildProcess.start(
|
||||
"cmd.exe", QStringList{ "/C", "taskkill", "/pid", QString::number(m_buildProjectProcess->processId()), "/f", "/t" });
|
||||
killBuildProcess.waitForFinished();
|
||||
|
||||
logStream << "Killing Project Build.";
|
||||
logStream << killBuildProcess.readAllStandardOutput();
|
||||
m_buildProjectProcess->kill();
|
||||
logFile.close();
|
||||
QStringToAZTracePrint(BuildCancelled);
|
||||
return AZ::Failure(BuildCancelled);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_configProjectProcess->exitCode() != 0)
|
||||
{
|
||||
QString error = tr("Building project failed. See log for details.");
|
||||
QStringToAZTracePrint(error);
|
||||
return AZ::Failure(error);
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -131,6 +131,17 @@ namespace O3DE::ProjectManager
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
auto keyEvent = static_cast<const QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Space)
|
||||
{
|
||||
const bool isAdded = GemModel::IsAdded(modelIndex);
|
||||
GemModel::SetIsAdded(*model, modelIndex, !isAdded);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* 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 <ProjectBuilder.h>
|
||||
#include <ProjectManagerDefs.h>
|
||||
#include <ProjectButtonWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
|
||||
//#define MOCK_BUILD_PROJECT true
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
// QProcess::waitForFinished uses -1 to indicate that the process should not timeout
|
||||
constexpr int MaxBuildTimeMSecs = -1;
|
||||
|
||||
ProjectBuilderWorker::ProjectBuilderWorker(const ProjectInfo& projectInfo)
|
||||
: QObject()
|
||||
, m_projectInfo(projectInfo)
|
||||
{
|
||||
}
|
||||
|
||||
void ProjectBuilderWorker::BuildProject()
|
||||
{
|
||||
#ifdef MOCK_BUILD_PROJECT
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
QThread::sleep(1);
|
||||
UpdateProgress(i * 10);
|
||||
}
|
||||
Done(m_projectPath);
|
||||
#else
|
||||
EngineInfo engineInfo;
|
||||
|
||||
AZ::Outcome<EngineInfo> engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo();
|
||||
if (engineInfoResult.IsSuccess())
|
||||
{
|
||||
engineInfo = engineInfoResult.GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
emit Done(tr("Failed to get engine info."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Show some kind of progress with very approximate estimates
|
||||
UpdateProgress(1);
|
||||
|
||||
QProcessEnvironment currentEnvironment(QProcessEnvironment::systemEnvironment());
|
||||
// Append cmake path to PATH incase it is missing
|
||||
QDir cmakePath(engineInfo.m_path);
|
||||
cmakePath.cd("cmake/runtime/bin");
|
||||
QString pathValue = currentEnvironment.value("PATH");
|
||||
pathValue += ";" + cmakePath.path();
|
||||
currentEnvironment.insert("PATH", pathValue);
|
||||
|
||||
QProcess configProjectProcess;
|
||||
configProjectProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
configProjectProcess.setWorkingDirectory(m_projectInfo.m_path);
|
||||
configProjectProcess.setProcessEnvironment(currentEnvironment);
|
||||
|
||||
configProjectProcess.start(
|
||||
"cmake",
|
||||
QStringList
|
||||
{
|
||||
"-B",
|
||||
QDir(m_projectInfo.m_path).filePath(ProjectBuildPathPostfix),
|
||||
"-S",
|
||||
m_projectInfo.m_path,
|
||||
"-G",
|
||||
"Visual Studio 16",
|
||||
"-DLY_3RDPARTY_PATH=" + engineInfo.m_thirdPartyPath
|
||||
});
|
||||
|
||||
if (!configProjectProcess.waitForStarted())
|
||||
{
|
||||
emit Done(tr("Configuring project failed to start."));
|
||||
return;
|
||||
}
|
||||
if (!configProjectProcess.waitForFinished(MaxBuildTimeMSecs))
|
||||
{
|
||||
WriteErrorLog(configProjectProcess.readAllStandardOutput());
|
||||
emit Done(tr("Configuring project timed out. See log for details"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString configProjectOutput(configProjectProcess.readAllStandardOutput());
|
||||
if (configProjectProcess.exitCode() != 0 || !configProjectOutput.contains("Generating done"))
|
||||
{
|
||||
WriteErrorLog(configProjectOutput);
|
||||
emit Done(tr("Configuring project failed. See log for details."));
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateProgress(20);
|
||||
|
||||
QProcess buildProjectProcess;
|
||||
buildProjectProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
buildProjectProcess.setWorkingDirectory(m_projectInfo.m_path);
|
||||
buildProjectProcess.setProcessEnvironment(currentEnvironment);
|
||||
|
||||
buildProjectProcess.start(
|
||||
"cmake",
|
||||
QStringList
|
||||
{
|
||||
"--build",
|
||||
QDir(m_projectInfo.m_path).filePath(ProjectBuildPathPostfix),
|
||||
"--target",
|
||||
m_projectInfo.m_projectName + ".GameLauncher",
|
||||
"Editor",
|
||||
"--config",
|
||||
"profile"
|
||||
});
|
||||
|
||||
if (!buildProjectProcess.waitForStarted())
|
||||
{
|
||||
emit Done(tr("Building project failed to start."));
|
||||
return;
|
||||
}
|
||||
if (!buildProjectProcess.waitForFinished(MaxBuildTimeMSecs))
|
||||
{
|
||||
WriteErrorLog(configProjectProcess.readAllStandardOutput());
|
||||
emit Done(tr("Building project timed out. See log for details"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString buildProjectOutput(buildProjectProcess.readAllStandardOutput());
|
||||
if (configProjectProcess.exitCode() != 0)
|
||||
{
|
||||
WriteErrorLog(buildProjectOutput);
|
||||
emit Done(tr("Building project failed. See log for details."));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit Done("");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QString ProjectBuilderWorker::LogFilePath() const
|
||||
{
|
||||
QDir logFilePath(m_projectInfo.m_path);
|
||||
logFilePath.cd(ProjectBuildPathPostfix);
|
||||
return logFilePath.filePath(ProjectBuildErrorLogPathPostfix);
|
||||
}
|
||||
|
||||
void ProjectBuilderWorker::WriteErrorLog(const QString& log)
|
||||
{
|
||||
QFile logFile(LogFilePath());
|
||||
// Overwrite file with truncate
|
||||
if (logFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
|
||||
{
|
||||
QTextStream output(&logFile);
|
||||
output << log;
|
||||
logFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
ProjectBuilderController::ProjectBuilderController(const ProjectInfo& projectInfo, ProjectButton* projectButton, QWidget* parent)
|
||||
: QObject()
|
||||
, m_projectInfo(projectInfo)
|
||||
, m_projectButton(projectButton)
|
||||
, m_parent(parent)
|
||||
{
|
||||
m_worker = new ProjectBuilderWorker(m_projectInfo);
|
||||
m_worker->moveToThread(&m_workerThread);
|
||||
|
||||
connect(&m_workerThread, &QThread::finished, m_worker, &ProjectBuilderWorker::deleteLater);
|
||||
connect(&m_workerThread, &QThread::started, m_worker, &ProjectBuilderWorker::BuildProject);
|
||||
connect(m_worker, &ProjectBuilderWorker::Done, this, &ProjectBuilderController::HandleResults);
|
||||
connect(m_worker, &ProjectBuilderWorker::UpdateProgress, this, &ProjectBuilderController::UpdateUIProgress);
|
||||
}
|
||||
|
||||
ProjectBuilderController::~ProjectBuilderController()
|
||||
{
|
||||
m_workerThread.quit();
|
||||
m_workerThread.wait();
|
||||
}
|
||||
|
||||
void ProjectBuilderController::Start()
|
||||
{
|
||||
m_workerThread.start();
|
||||
UpdateUIProgress(0);
|
||||
}
|
||||
|
||||
void ProjectBuilderController::SetProjectButton(ProjectButton* projectButton)
|
||||
{
|
||||
m_projectButton = projectButton;
|
||||
}
|
||||
|
||||
QString ProjectBuilderController::GetProjectPath() const
|
||||
{
|
||||
return m_projectInfo.m_path;
|
||||
}
|
||||
|
||||
void ProjectBuilderController::UpdateUIProgress(int progress)
|
||||
{
|
||||
if (m_projectButton)
|
||||
{
|
||||
m_projectButton->SetButtonOverlayText(QString("%1 (%2%)\n\n").arg(tr("Building Project..."), QString::number(progress)));
|
||||
m_projectButton->SetProgressBarValue(progress);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectBuilderController::HandleResults(const QString& result)
|
||||
{
|
||||
if (!result.isEmpty())
|
||||
{
|
||||
if (result.contains(tr("log")))
|
||||
{
|
||||
QMessageBox::StandardButton openLog = QMessageBox::critical(
|
||||
m_parent,
|
||||
tr("Project Failed to Build!"),
|
||||
result + tr("\n\nWould you like to view log?"),
|
||||
QMessageBox::No | QMessageBox::Yes);
|
||||
|
||||
if (openLog == QMessageBox::Yes)
|
||||
{
|
||||
// Open application assigned to this file type
|
||||
QDesktopServices::openUrl(QUrl("file:///" + m_worker->LogFilePath()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(m_parent, tr("Project Failed to Build!"), result);
|
||||
}
|
||||
}
|
||||
|
||||
emit Done();
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 <ProjectBuilderController.h>
|
||||
#include <ProjectBuilderWorker.h>
|
||||
#include <ProjectButtonWidget.h>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
ProjectBuilderController::ProjectBuilderController(const ProjectInfo& projectInfo, ProjectButton* projectButton, QWidget* parent)
|
||||
: QObject()
|
||||
, m_projectInfo(projectInfo)
|
||||
, m_projectButton(projectButton)
|
||||
, m_lastProgress(0)
|
||||
, m_parent(parent)
|
||||
{
|
||||
m_worker = new ProjectBuilderWorker(m_projectInfo);
|
||||
m_worker->moveToThread(&m_workerThread);
|
||||
|
||||
connect(&m_workerThread, &QThread::finished, m_worker, &ProjectBuilderWorker::deleteLater);
|
||||
connect(&m_workerThread, &QThread::started, m_worker, &ProjectBuilderWorker::BuildProject);
|
||||
connect(m_worker, &ProjectBuilderWorker::Done, this, &ProjectBuilderController::HandleResults);
|
||||
connect(m_worker, &ProjectBuilderWorker::UpdateProgress, this, &ProjectBuilderController::UpdateUIProgress);
|
||||
}
|
||||
|
||||
ProjectBuilderController::~ProjectBuilderController()
|
||||
{
|
||||
m_workerThread.requestInterruption();
|
||||
m_workerThread.quit();
|
||||
m_workerThread.wait();
|
||||
}
|
||||
|
||||
void ProjectBuilderController::Start()
|
||||
{
|
||||
m_workerThread.start();
|
||||
UpdateUIProgress(0);
|
||||
}
|
||||
|
||||
void ProjectBuilderController::SetProjectButton(ProjectButton* projectButton)
|
||||
{
|
||||
m_projectButton = projectButton;
|
||||
|
||||
if (projectButton)
|
||||
{
|
||||
projectButton->SetProjectButtonAction(tr("Cancel Build"), [this] { HandleCancel(); });
|
||||
|
||||
if (m_lastProgress != 0)
|
||||
{
|
||||
UpdateUIProgress(m_lastProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ProjectInfo& ProjectBuilderController::GetProjectInfo() const
|
||||
{
|
||||
return m_projectInfo;
|
||||
}
|
||||
|
||||
void ProjectBuilderController::UpdateUIProgress(int progress)
|
||||
{
|
||||
m_lastProgress = progress;
|
||||
if (m_projectButton)
|
||||
{
|
||||
m_projectButton->SetButtonOverlayText(QString("%1 (%2%)\n\n").arg(tr("Building Project..."), QString::number(progress)));
|
||||
m_projectButton->SetProgressBarValue(progress);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectBuilderController::HandleResults(const QString& result)
|
||||
{
|
||||
if (!result.isEmpty())
|
||||
{
|
||||
if (result.contains(tr("log")))
|
||||
{
|
||||
QMessageBox::StandardButton openLog = QMessageBox::critical(
|
||||
m_parent,
|
||||
tr("Project Failed to Build!"),
|
||||
result + tr("\n\nWould you like to view log?"),
|
||||
QMessageBox::No | QMessageBox::Yes);
|
||||
|
||||
if (openLog == QMessageBox::Yes)
|
||||
{
|
||||
// Open application assigned to this file type
|
||||
QDesktopServices::openUrl(QUrl("file:///" + m_worker->GetLogFilePath()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(m_parent, tr("Project Failed to Build!"), result);
|
||||
}
|
||||
|
||||
emit Done(false);
|
||||
return;
|
||||
}
|
||||
|
||||
emit Done(true);
|
||||
}
|
||||
|
||||
void ProjectBuilderController::HandleCancel()
|
||||
{
|
||||
m_workerThread.quit();
|
||||
emit Done(false);
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
+8
-25
@@ -12,32 +12,12 @@
|
||||
#include <QThread>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QProcess)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
QT_FORWARD_DECLARE_CLASS(ProjectButton)
|
||||
|
||||
class ProjectBuilderWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProjectBuilderWorker(const ProjectInfo& projectInfo);
|
||||
~ProjectBuilderWorker() = default;
|
||||
|
||||
QString LogFilePath() const;
|
||||
|
||||
public slots:
|
||||
void BuildProject();
|
||||
|
||||
signals:
|
||||
void UpdateProgress(int progress);
|
||||
void Done(QString result);
|
||||
|
||||
private:
|
||||
void WriteErrorLog(const QString& log);
|
||||
|
||||
ProjectInfo m_projectInfo;
|
||||
};
|
||||
QT_FORWARD_DECLARE_CLASS(ProjectBuilderWorker)
|
||||
|
||||
class ProjectBuilderController : public QObject
|
||||
{
|
||||
@@ -48,15 +28,16 @@ namespace O3DE::ProjectManager
|
||||
~ProjectBuilderController();
|
||||
|
||||
void SetProjectButton(ProjectButton* projectButton);
|
||||
QString GetProjectPath() const;
|
||||
const ProjectInfo& GetProjectInfo() const;
|
||||
|
||||
public slots:
|
||||
void Start();
|
||||
void UpdateUIProgress(int progress);
|
||||
void HandleResults(const QString& result);
|
||||
void HandleCancel();
|
||||
|
||||
signals:
|
||||
void Done();
|
||||
void Done(bool success = true);
|
||||
|
||||
private:
|
||||
ProjectInfo m_projectInfo;
|
||||
@@ -64,5 +45,7 @@ namespace O3DE::ProjectManager
|
||||
QThread m_workerThread;
|
||||
ProjectButton* m_projectButton;
|
||||
QWidget* m_parent;
|
||||
|
||||
int m_lastProgress;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <ProjectBuilderWorker.h>
|
||||
#include <ProjectManagerDefs.h>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
//#define MOCK_BUILD_PROJECT true
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
const QString ProjectBuilderWorker::BuildCancelled = ProjectBuilderWorker::tr("Build Cancelled.");
|
||||
|
||||
ProjectBuilderWorker::ProjectBuilderWorker(const ProjectInfo& projectInfo)
|
||||
: QObject()
|
||||
, m_projectInfo(projectInfo)
|
||||
, m_progressEstimate(0)
|
||||
{
|
||||
}
|
||||
|
||||
void ProjectBuilderWorker::BuildProject()
|
||||
{
|
||||
#ifdef MOCK_BUILD_PROJECT
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
QThread::sleep(1);
|
||||
UpdateProgress(i * 10);
|
||||
}
|
||||
Done("");
|
||||
#else
|
||||
auto result = BuildProjectForPlatform();
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
emit Done();
|
||||
}
|
||||
else
|
||||
{
|
||||
emit Done(result.GetError());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QString ProjectBuilderWorker::GetLogFilePath() const
|
||||
{
|
||||
QDir logFilePath(m_projectInfo.m_path);
|
||||
// Make directories if they aren't on disk
|
||||
if (!logFilePath.cd(ProjectBuildPathPostfix))
|
||||
{
|
||||
logFilePath.mkpath(ProjectBuildPathPostfix);
|
||||
logFilePath.cd(ProjectBuildPathPostfix);
|
||||
|
||||
}
|
||||
if (!logFilePath.cd(ProjectBuildPathCmakeFiles))
|
||||
{
|
||||
logFilePath.mkpath(ProjectBuildPathCmakeFiles);
|
||||
logFilePath.cd(ProjectBuildPathCmakeFiles);
|
||||
}
|
||||
return logFilePath.filePath(ProjectBuildErrorLogName);
|
||||
}
|
||||
|
||||
void ProjectBuilderWorker::QStringToAZTracePrint([[maybe_unused]] const QString& error)
|
||||
{
|
||||
AZ_TracePrintf("Project Manager", error.toStdString().c_str());
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <ProjectInfo.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
|
||||
#include <QObject>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QProcess)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
class ProjectBuilderWorker : public QObject
|
||||
{
|
||||
// QProcess::waitForFinished uses -1 to indicate that the process should not timeout
|
||||
static constexpr int MaxBuildTimeMSecs = -1;
|
||||
// Build was cancelled
|
||||
static const QString BuildCancelled;
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProjectBuilderWorker(const ProjectInfo& projectInfo);
|
||||
~ProjectBuilderWorker() = default;
|
||||
|
||||
QString GetLogFilePath() const;
|
||||
|
||||
public slots:
|
||||
void BuildProject();
|
||||
|
||||
signals:
|
||||
void UpdateProgress(int progress);
|
||||
void Done(QString result = "");
|
||||
|
||||
private:
|
||||
AZ::Outcome<void, QString> BuildProjectForPlatform();
|
||||
void QStringToAZTracePrint(const QString& error);
|
||||
|
||||
QProcess* m_configProjectProcess = nullptr;
|
||||
QProcess* m_buildProjectProcess = nullptr;
|
||||
ProjectInfo m_projectInfo;
|
||||
|
||||
int m_progressEstimate;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -40,8 +40,8 @@ namespace O3DE::ProjectManager
|
||||
m_overlayLabel->setVisible(false);
|
||||
vLayout->addWidget(m_overlayLabel);
|
||||
|
||||
m_buildButton = new QPushButton(tr("Build Project"), this);
|
||||
m_buildButton->setVisible(false);
|
||||
m_actionButton = new QPushButton(tr("Project Action"), this);
|
||||
m_actionButton->setVisible(false);
|
||||
|
||||
m_progressBar = new QProgressBar(this);
|
||||
m_progressBar->setObjectName("labelButtonProgressBar");
|
||||
@@ -78,9 +78,9 @@ namespace O3DE::ProjectManager
|
||||
return m_progressBar;
|
||||
}
|
||||
|
||||
QPushButton* LabelButton::GetBuildButton()
|
||||
QPushButton* LabelButton::GetActionButton()
|
||||
{
|
||||
return m_buildButton;
|
||||
return m_actionButton;
|
||||
}
|
||||
|
||||
ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent, bool processing)
|
||||
@@ -135,7 +135,6 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void ProjectButton::ProcessingSetup()
|
||||
{
|
||||
m_projectImageLabel->GetOverlayLabel()->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
m_projectImageLabel->SetEnabled(false);
|
||||
m_projectImageLabel->SetOverlayText(tr("Processing...\n\n"));
|
||||
|
||||
@@ -146,8 +145,6 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void ProjectButton::ReadySetup()
|
||||
{
|
||||
connect(m_projectImageLabel->GetBuildButton(), &QPushButton::clicked, [this](){ emit BuildProject(m_projectInfo); });
|
||||
|
||||
QMenu* menu = new QMenu(this);
|
||||
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
|
||||
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
|
||||
@@ -168,20 +165,40 @@ namespace O3DE::ProjectManager
|
||||
m_projectFooter->layout()->addWidget(projectMenuButton);
|
||||
}
|
||||
|
||||
void ProjectButton::SetProjectButtonAction(const QString& text, AZStd::function<void()> lambda)
|
||||
{
|
||||
QPushButton* projectActionButton = m_projectImageLabel->GetActionButton();
|
||||
if (!m_actionButtonConnection)
|
||||
{
|
||||
QSpacerItem* buttonSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
m_projectImageLabel->layout()->addItem(buttonSpacer);
|
||||
m_projectImageLabel->layout()->addWidget(projectActionButton);
|
||||
projectActionButton->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(m_actionButtonConnection);
|
||||
}
|
||||
|
||||
projectActionButton->setText(text);
|
||||
m_actionButtonConnection = connect(projectActionButton, &QPushButton::clicked, lambda);
|
||||
}
|
||||
|
||||
void ProjectButton::SetProjectBuildButtonAction()
|
||||
{
|
||||
SetProjectButtonAction(tr("Build Project"), [this]() { emit BuildProject(m_projectInfo); });
|
||||
}
|
||||
|
||||
void ProjectButton::BuildThisProject()
|
||||
{
|
||||
emit BuildProject(m_projectInfo);
|
||||
}
|
||||
|
||||
void ProjectButton::SetLaunchButtonEnabled(bool enabled)
|
||||
{
|
||||
m_projectImageLabel->SetEnabled(enabled);
|
||||
}
|
||||
|
||||
void ProjectButton::ShowBuildButton(bool show)
|
||||
{
|
||||
QSpacerItem* buttonSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
m_projectImageLabel->layout()->addItem(buttonSpacer);
|
||||
m_projectImageLabel->layout()->addWidget(m_projectImageLabel->GetBuildButton());
|
||||
m_projectImageLabel->GetBuildButton()->setVisible(show);
|
||||
}
|
||||
|
||||
void ProjectButton::SetButtonOverlayText(const QString& text)
|
||||
{
|
||||
m_projectImageLabel->SetOverlayText(text);
|
||||
@@ -191,4 +208,9 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
m_projectImageLabel->GetProgressBar()->setValue(progress);
|
||||
}
|
||||
|
||||
LabelButton* ProjectButton::GetLabelButton()
|
||||
{
|
||||
return m_projectImageLabel;
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <ProjectInfo.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QSpacerItem>
|
||||
#include <QLayout>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QPixmap)
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
QT_FORWARD_DECLARE_CLASS(QAction)
|
||||
QT_FORWARD_DECLARE_CLASS(QProgressBar)
|
||||
|
||||
@@ -34,7 +37,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
QLabel* GetOverlayLabel();
|
||||
QProgressBar* GetProgressBar();
|
||||
QPushButton* GetBuildButton();
|
||||
QPushButton* GetActionButton();
|
||||
|
||||
signals:
|
||||
void triggered();
|
||||
@@ -45,7 +48,7 @@ namespace O3DE::ProjectManager
|
||||
private:
|
||||
QLabel* m_overlayLabel;
|
||||
QProgressBar* m_progressBar;
|
||||
QPushButton* m_buildButton;
|
||||
QPushButton* m_actionButton;
|
||||
bool m_enabled = true;
|
||||
};
|
||||
|
||||
@@ -58,10 +61,13 @@ namespace O3DE::ProjectManager
|
||||
explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr, bool processing = false);
|
||||
~ProjectButton() = default;
|
||||
|
||||
void SetProjectButtonAction(const QString& text, AZStd::function<void()> lambda);
|
||||
void SetProjectBuildButtonAction();
|
||||
|
||||
void SetLaunchButtonEnabled(bool enabled);
|
||||
void ShowBuildButton(bool show);
|
||||
void SetButtonOverlayText(const QString& text);
|
||||
void SetProgressBarValue(int progress);
|
||||
LabelButton* GetLabelButton();
|
||||
|
||||
signals:
|
||||
void OpenProject(const QString& projectName);
|
||||
@@ -75,9 +81,12 @@ namespace O3DE::ProjectManager
|
||||
void BaseSetup();
|
||||
void ProcessingSetup();
|
||||
void ReadySetup();
|
||||
void BuildThisProject();
|
||||
|
||||
ProjectInfo m_projectInfo;
|
||||
LabelButton* m_projectImageLabel;
|
||||
QFrame* m_projectFooter;
|
||||
|
||||
QMetaObject::Connection m_actionButtonConnection;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace O3DE::ProjectManager
|
||||
inline constexpr static int ProjectPreviewImageHeight = 280;
|
||||
|
||||
static const QString ProjectBuildPathPostfix = "build/windows_vs2019";
|
||||
static const QString ProjectBuildErrorLogPathPostfix = "CMakeFiles/CMakeProjectBuildError.log";
|
||||
static const QString ProjectBuildPathCmakeFiles = "CMakeFiles";
|
||||
static const QString ProjectBuildErrorLogName = "CMakeProjectBuildError.log";
|
||||
static const QString ProjectPreviewImagePath = "preview.png";
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <ProjectButtonWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <ProjectUtils.h>
|
||||
#include <ProjectBuilder.h>
|
||||
#include <ProjectBuilderController.h>
|
||||
#include <ScreensCtrl.h>
|
||||
|
||||
#include <AzQtComponents/Components/FlowLayout.h>
|
||||
@@ -43,8 +43,6 @@
|
||||
#include <QDir>
|
||||
#include <QGuiApplication>
|
||||
|
||||
//#define DISPLAY_PROJECT_DEV_DATA true
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
ProjectsScreen::ProjectsScreen(QWidget* parent)
|
||||
@@ -86,7 +84,7 @@ namespace O3DE::ProjectManager
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
frame->setLayout(layout);
|
||||
|
||||
QLabel* titleLabel = new QLabel(tr("Ready. Set. Create."), this);
|
||||
QLabel* titleLabel = new QLabel(tr("Ready? Set. Create!"), this);
|
||||
titleLabel->setObjectName("titleLabel");
|
||||
layout->addWidget(titleLabel);
|
||||
|
||||
@@ -166,43 +164,38 @@ namespace O3DE::ProjectManager
|
||||
projectsScrollArea->setWidget(scrollWidget);
|
||||
projectsScrollArea->setWidgetResizable(true);
|
||||
|
||||
#ifndef DISPLAY_PROJECT_DEV_DATA
|
||||
// Iterate once to insert building project first
|
||||
if (!buildProjectPath.isEmpty())
|
||||
QVector<ProjectInfo> nonProcessingProjects;
|
||||
buildProjectPath = QDir::fromNativeSeparators(buildProjectPath);
|
||||
for (auto& project : projectsResult.GetValue())
|
||||
{
|
||||
buildProjectPath = QDir::fromNativeSeparators(buildProjectPath);
|
||||
for (auto project : projectsResult.GetValue())
|
||||
if (projectButton && !*projectButton)
|
||||
{
|
||||
if (QDir::fromNativeSeparators(project.m_path) == buildProjectPath)
|
||||
{
|
||||
ProjectButton* buildingProjectButton = CreateProjectButton(project, flowLayout, true);
|
||||
|
||||
if (projectButton)
|
||||
{
|
||||
*projectButton = buildingProjectButton;
|
||||
}
|
||||
|
||||
break;
|
||||
*projectButton = CreateProjectButton(project, flowLayout, true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nonProcessingProjects.append(project);
|
||||
}
|
||||
|
||||
for (auto project : projectsResult.GetValue())
|
||||
#else
|
||||
ProjectInfo project = projectsResult.GetValue().at(0);
|
||||
for (int i = 0; i < 15; i++)
|
||||
#endif
|
||||
for (auto& project : nonProcessingProjects)
|
||||
{
|
||||
// Add all other projects skipping building project
|
||||
// Safe if no building project because it is just an empty string
|
||||
if (project.m_path != buildProjectPath)
|
||||
{
|
||||
ProjectButton* projectButtonWidget = CreateProjectButton(project, flowLayout);
|
||||
ProjectButton* projectButtonWidget = CreateProjectButton(project, flowLayout);
|
||||
|
||||
if (RequiresBuildProjectIterator(project.m_path) != m_requiresBuild.end())
|
||||
{
|
||||
projectButtonWidget->ShowBuildButton(true);
|
||||
}
|
||||
if (BuildQueueContainsProject(project.m_path))
|
||||
{
|
||||
projectButtonWidget->SetProjectButtonAction(tr("Cancel Queued Build"),
|
||||
[this, project]
|
||||
{
|
||||
UnqueueBuildProject(project);
|
||||
SuggestBuildProjectMsg(project, false);
|
||||
});
|
||||
}
|
||||
else if (RequiresBuildProjectIterator(project.m_path) != m_requiresBuild.end())
|
||||
{
|
||||
projectButtonWidget->SetProjectBuildButtonAction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,9 +237,9 @@ namespace O3DE::ProjectManager
|
||||
// Make sure to update builder with latest Project Button
|
||||
if (m_currentBuilder)
|
||||
{
|
||||
ProjectButton* projectButtonPtr;
|
||||
ProjectButton* projectButtonPtr = nullptr;
|
||||
|
||||
m_projectsContent = CreateProjectsContent(m_currentBuilder->GetProjectPath(), &projectButtonPtr);
|
||||
m_projectsContent = CreateProjectsContent(m_currentBuilder->GetProjectInfo().m_path, &projectButtonPtr);
|
||||
m_currentBuilder->SetProjectButton(projectButtonPtr);
|
||||
}
|
||||
else
|
||||
@@ -414,17 +407,15 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectsScreen::SuggestBuildProject(const ProjectInfo& projectInfo)
|
||||
void ProjectsScreen::SuggestBuildProjectMsg(const ProjectInfo& projectInfo, bool showMessage)
|
||||
{
|
||||
if (projectInfo.m_needsBuild)
|
||||
if (RequiresBuildProjectIterator(projectInfo.m_path) == m_requiresBuild.end())
|
||||
{
|
||||
if (RequiresBuildProjectIterator(projectInfo.m_path) == m_requiresBuild.end())
|
||||
{
|
||||
m_requiresBuild.append(projectInfo);
|
||||
}
|
||||
ResetProjectsContent();
|
||||
m_requiresBuild.append(projectInfo);
|
||||
}
|
||||
else
|
||||
ResetProjectsContent();
|
||||
|
||||
if (showMessage)
|
||||
{
|
||||
QMessageBox::information(this,
|
||||
tr("Project Should be rebuilt."),
|
||||
@@ -432,6 +423,11 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectsScreen::SuggestBuildProject(const ProjectInfo& projectInfo)
|
||||
{
|
||||
SuggestBuildProjectMsg(projectInfo, true);
|
||||
}
|
||||
|
||||
void ProjectsScreen::QueueBuildProject(const ProjectInfo& projectInfo)
|
||||
{
|
||||
auto requiredIter = RequiresBuildProjectIterator(projectInfo.m_path);
|
||||
@@ -445,14 +441,22 @@ namespace O3DE::ProjectManager
|
||||
if (m_buildQueue.empty() && !m_currentBuilder)
|
||||
{
|
||||
StartProjectBuild(projectInfo);
|
||||
// Projects Content is already reset in fuction
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buildQueue.append(projectInfo);
|
||||
ResetProjectsContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectsScreen::UnqueueBuildProject(const ProjectInfo& projectInfo)
|
||||
{
|
||||
m_buildQueue.removeAll(projectInfo);
|
||||
ResetProjectsContent();
|
||||
}
|
||||
|
||||
void ProjectsScreen::NotifyCurrentScreen()
|
||||
{
|
||||
if (ShouldDisplayFirstTimeContent())
|
||||
@@ -488,7 +492,7 @@ namespace O3DE::ProjectManager
|
||||
return PythonBindingsInterface::Get()->RemoveInvalidProjects();
|
||||
}
|
||||
|
||||
void ProjectsScreen::StartProjectBuild(const ProjectInfo& projectInfo)
|
||||
bool ProjectsScreen::StartProjectBuild(const ProjectInfo& projectInfo)
|
||||
{
|
||||
if (ProjectUtils::IsVS2019Installed())
|
||||
{
|
||||
@@ -508,25 +512,42 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
else
|
||||
{
|
||||
ProjectBuildDone();
|
||||
SuggestBuildProjectMsg(projectInfo, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProjectsScreen::ProjectBuildDone()
|
||||
void ProjectsScreen::ProjectBuildDone(bool success)
|
||||
{
|
||||
ProjectInfo currentBuilderProject;
|
||||
if (!success)
|
||||
{
|
||||
currentBuilderProject = m_currentBuilder->GetProjectInfo();
|
||||
}
|
||||
|
||||
delete m_currentBuilder;
|
||||
m_currentBuilder = nullptr;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
SuggestBuildProjectMsg(currentBuilderProject, false);
|
||||
}
|
||||
|
||||
if (!m_buildQueue.empty())
|
||||
{
|
||||
StartProjectBuild(m_buildQueue.front());
|
||||
while (!StartProjectBuild(m_buildQueue.front()) && m_buildQueue.size() > 1)
|
||||
{
|
||||
m_buildQueue.pop_front();
|
||||
}
|
||||
m_buildQueue.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetProjectsContent();
|
||||
}
|
||||
|
||||
ResetProjectsContent();
|
||||
}
|
||||
|
||||
QList<ProjectInfo>::iterator ProjectsScreen::RequiresBuildProjectIterator(const QString& projectPath)
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
protected:
|
||||
void NotifyCurrentScreen() override;
|
||||
void ProjectBuildDone();
|
||||
void SuggestBuildProjectMsg(const ProjectInfo& projectInfo, bool showMessage);
|
||||
|
||||
protected slots:
|
||||
void HandleNewProjectButton();
|
||||
@@ -50,6 +50,9 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void SuggestBuildProject(const ProjectInfo& projectInfo);
|
||||
void QueueBuildProject(const ProjectInfo& projectInfo);
|
||||
void UnqueueBuildProject(const ProjectInfo& projectInfo);
|
||||
|
||||
void ProjectBuildDone(bool success = true);
|
||||
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
@@ -61,7 +64,7 @@ namespace O3DE::ProjectManager
|
||||
bool ShouldDisplayFirstTimeContent();
|
||||
bool RemoveInvalidProjects();
|
||||
|
||||
void StartProjectBuild(const ProjectInfo& projectInfo);
|
||||
bool StartProjectBuild(const ProjectInfo& projectInfo);
|
||||
QList<ProjectInfo>::iterator RequiresBuildProjectIterator(const QString& projectPath);
|
||||
bool BuildQueueContainsProject(const QString& projectPath);
|
||||
bool WarnIfInBuildQueue(const QString& projectPath);
|
||||
|
||||
@@ -39,8 +39,10 @@ set(FILES
|
||||
Source/ProjectInfo.cpp
|
||||
Source/ProjectUtils.h
|
||||
Source/ProjectUtils.cpp
|
||||
Source/ProjectBuilder.h
|
||||
Source/ProjectBuilder.cpp
|
||||
Source/ProjectBuilderWorker.h
|
||||
Source/ProjectBuilderWorker.cpp
|
||||
Source/ProjectBuilderController.h
|
||||
Source/ProjectBuilderController.cpp
|
||||
Source/UpdateProjectSettingsScreen.h
|
||||
Source/UpdateProjectSettingsScreen.cpp
|
||||
Source/NewProjectSettingsScreen.h
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace AZ
|
||||
// AssImp only has one bitangentStream per mesh.
|
||||
bitangentStream->SetBitangentSetIndex(0);
|
||||
|
||||
bitangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
bitangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
bitangentStream->ReserveContainerSpace(vertexCount);
|
||||
for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace AZ
|
||||
// AssImp only has one tangentStream per mesh.
|
||||
tangentStream->SetTangentSetIndex(0);
|
||||
|
||||
tangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
tangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
tangentStream->ReserveContainerSpace(vertexCount);
|
||||
for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
|
||||
{
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace AZ
|
||||
{
|
||||
enum class TangentSpace
|
||||
{
|
||||
FromFbx = 0,
|
||||
MikkT = 1,
|
||||
EMotionFX = 2
|
||||
FromSourceScene = 0,
|
||||
MikkT = 1,
|
||||
EMotionFX = 2
|
||||
};
|
||||
|
||||
enum class BitangentMethod
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<MeshVertexBitangentData>()->Version(1);
|
||||
serializeContext->Class<MeshVertexBitangentData>()->Version(2);
|
||||
}
|
||||
|
||||
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
|
||||
@@ -34,7 +34,7 @@ namespace AZ
|
||||
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
|
||||
->Method("GetTangentSpace", &MeshVertexBitangentData::GetTangentSpace)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::EMotionFX>("EMotionFX")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromFbx>("FromFbx")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace AZ
|
||||
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
|
||||
protected:
|
||||
AZStd::vector<AZ::Vector3> m_bitangents;
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromFbx;
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
|
||||
size_t m_setIndex = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<MeshVertexTangentData>()->Version(1);
|
||||
serializeContext->Class<MeshVertexTangentData>()->Version(2);
|
||||
}
|
||||
|
||||
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
|
||||
@@ -34,7 +34,7 @@ namespace AZ
|
||||
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
|
||||
->Method("GetTangentSpace", &MeshVertexTangentData::GetTangentSpace)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::EMotionFX>("EMotionFX")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromFbx>("FromFbx")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace AZ
|
||||
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
|
||||
protected:
|
||||
AZStd::vector<AZ::Vector4> m_tangents;
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromFbx;
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
|
||||
size_t m_setIndex = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(1)
|
||||
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(2)
|
||||
->Field("tangentSpace", &TangentsRule::m_tangentSpace)
|
||||
->Field("bitangentMethod", &TangentsRule::m_bitangentMethod)
|
||||
->Field("normalize", &TangentsRule::m_normalize)
|
||||
@@ -156,7 +156,7 @@ namespace AZ
|
||||
->Attribute("AutoExpand", true)
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tangentSpace, "Tangent space", "Specify the tangent space used for normal map baking. Choose 'From Fbx' to extract the tangents and bitangents directly from the Fbx file. When there is no tangents rule or the Fbx has no tangents stored inside it, the 'MikkT' option will be used with orthogonal tangents of unit length, so with the normalize option enabled, using the first UV set.")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx, "From Fbx")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene, "From Source Scene")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX, "EMotion FX")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace AZ
|
||||
auto* bitangentData = AZStd::any_cast<AZ::SceneData::GraphData::MeshVertexBitangentData>(&data);
|
||||
bitangentData->AppendBitangent(AZ::Vector3{0.12f, 0.34f, 0.56f});
|
||||
bitangentData->AppendBitangent(AZ::Vector3{0.77f, 0.88f, 0.99f});
|
||||
bitangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
bitangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
bitangentData->SetBitangentSetIndex(1);
|
||||
return true;
|
||||
}
|
||||
@@ -317,7 +317,7 @@ namespace AZ
|
||||
ExpectExecute("TestExpectFloatEquals(bitangentData.y, 0.88)");
|
||||
ExpectExecute("TestExpectFloatEquals(bitangentData.z, 0.99)");
|
||||
ExpectExecute("TestExpectIntegerEquals(meshVertexBitangentData:GetBitangentSetIndex(), 1)");
|
||||
ExpectExecute("TestExpectTrue(meshVertexBitangentData:GetTangentSpace(), MeshVertexBitangentData.FromFbx)");
|
||||
ExpectExecute("TestExpectTrue(meshVertexBitangentData:GetTangentSpace(), MeshVertexBitangentData.FromSourceScene)");
|
||||
}
|
||||
|
||||
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_MeshVertexTangentData_AccessWorks)
|
||||
|
||||
@@ -21,6 +21,7 @@ ly_add_target(
|
||||
AZ::AzFramework
|
||||
PUBLIC
|
||||
Gem::AWSCore
|
||||
3rdParty::AWSNativeSDK::Core
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lig
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight, lightingData.diffuseResponse);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lig
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight, lightingData.diffuseResponse);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
// Then define the Diffuse and Specular lighting functions
|
||||
float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight)
|
||||
{
|
||||
float3 diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
float3 diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight, lightingData.diffuseResponse);
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
// ------- Diffuse Lighting -------
|
||||
|
||||
//! Simple Lambertian BRDF.
|
||||
float3 DiffuseLambertian(float3 albedo, float3 normal, float3 dirToLight)
|
||||
float3 DiffuseLambertian(float3 albedo, float3 normal, float3 dirToLight, float diffuseResponse)
|
||||
{
|
||||
float NdotL = saturate(dot(normal, dirToLight));
|
||||
return albedo * NdotL * INV_PI;
|
||||
return albedo * NdotL * INV_PI * diffuseResponse;
|
||||
}
|
||||
|
||||
// Normalized Disney diffuse function taken from Frostbite's PBR course notes (page 10):
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace EMotionFX
|
||||
return;
|
||||
}
|
||||
|
||||
serializeContext->Class<MotionSamplingRule, IRule>()->Version(3)
|
||||
serializeContext->Class<MotionSamplingRule, IRule>()->Version(4)
|
||||
->Field("motionDataType", &MotionSamplingRule::m_motionDataType)
|
||||
->Field("sampleRateMethod", &MotionSamplingRule::m_sampleRateMethod)
|
||||
->Field("customSampleRate", &MotionSamplingRule::m_customSampleRate)
|
||||
@@ -151,7 +151,7 @@ namespace EMotionFX
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &MotionSamplingRule::m_sampleRateMethod, "Sample rate", "Either use the Fbx sample rate or use a custom sample rate. The sample rate is automatically limited to the rate from Fbx.")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
->EnumAttribute(SampleRateMethod::FromFbx, "From Fbx")
|
||||
->EnumAttribute(SampleRateMethod::FromSourceScene, "From Source Scene")
|
||||
->EnumAttribute(SampleRateMethod::Custom, "Custom sample rate")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MotionSamplingRule::m_keepDuration, "Keep duration", "When enabled this keep the duration the same as the Fbx motion duration, even if no joints are animated. "
|
||||
"When this option is disabled and the motion doesn't animate any joints then the resulting motion will have a duration of zero seconds.")
|
||||
@@ -199,7 +199,7 @@ namespace EMotionFX
|
||||
|
||||
AZ::Crc32 MotionSamplingRule::GetVisibilityCustomSampleRate() const
|
||||
{
|
||||
return m_sampleRateMethod == SampleRateMethod::FromFbx ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
|
||||
return m_sampleRateMethod == SampleRateMethod::FromSourceScene ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
|
||||
}
|
||||
|
||||
AZ::Crc32 MotionSamplingRule::GetVisibilityAllowedSizePercentage() const
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace EMotionFX
|
||||
|
||||
enum class SampleRateMethod : AZ::u8
|
||||
{
|
||||
FromFbx = 0,
|
||||
FromSourceScene = 0,
|
||||
Custom = 1
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace EMotionFX
|
||||
AZ::Crc32 GetVisibilityAllowedSizePercentage() const;
|
||||
|
||||
float m_customSampleRate = 60.0f;
|
||||
SampleRateMethod m_sampleRateMethod = SampleRateMethod::FromFbx;
|
||||
SampleRateMethod m_sampleRateMethod = SampleRateMethod::FromSourceScene;
|
||||
AZ::TypeId m_motionDataType = AZ::TypeId::CreateNull();
|
||||
bool m_keepDuration = true;
|
||||
|
||||
|
||||
@@ -107,7 +107,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_target(
|
||||
NAME Multiplayer.Builders GEM_MODULE
|
||||
NAMESPACE Gem
|
||||
OUTPUT_NAME Gem.Multiplayer.Builders
|
||||
FILES_CMAKE
|
||||
multiplayer_tools_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
|
||||
+6
-6
@@ -123,8 +123,8 @@ namespace AZ::SceneGenerationComponents
|
||||
while (uvData)
|
||||
{
|
||||
// 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);
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
|
||||
if (fbxTangentData && fbxBitangentData)
|
||||
{
|
||||
@@ -198,8 +198,8 @@ namespace AZ::SceneGenerationComponents
|
||||
}
|
||||
|
||||
// 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);
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
|
||||
// Check what tangent spaces we need.
|
||||
AZStd::vector<AZ::SceneAPI::DataTypes::TangentSpace> requiredSpaces = CollectRequiredTangentSpaces(scene);
|
||||
@@ -212,7 +212,7 @@ namespace AZ::SceneGenerationComponents
|
||||
}
|
||||
|
||||
// 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)
|
||||
if ((requiredSpaces.size() == 1 && requiredSpaces[0] == AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene) && fbxTangentData && fbxBitangentData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -232,7 +232,7 @@ namespace AZ::SceneGenerationComponents
|
||||
switch (space)
|
||||
{
|
||||
// If we want Fbx tangents, we don't need to do anything for that.
|
||||
case AZ::SceneAPI::DataTypes::TangentSpace::FromFbx:
|
||||
case AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene:
|
||||
{
|
||||
allSuccess &= true;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:61efd8df621780af995fc1250918df5e00364ff00f849bef67702cd4b0a152e1
|
||||
size 65537
|
||||
oid sha256:41239f8345fa91fe546442208461ad3cd17c7a7a7047af45018b97363bfea204
|
||||
size 109783
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cf6d56fe4c367d39bd78500dd34332fcad57ad41241768b52781dbdb60ddd972
|
||||
size 347568
|
||||
oid sha256:7c8433178baebafe984ca23d9325d3c71b5a177fc3b3b869afbb01a583542fbe
|
||||
size 462842
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e38257b6917cdf5d73e90e6009f10c8736d62b20c4e785085305075c7e6320e2
|
||||
size 32037
|
||||
oid sha256:094620c172320b062f9a1f8cc758ef4bbee11bc0a6049f46ad6b42f9bf613c92
|
||||
size 9679
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9f41a37d2347a617e93bd97adaf6d4c161c471ca3ef7e04b98c65ddda52396dc
|
||||
size 27833
|
||||
oid sha256:f3c651ca45a83d0f68bdaa466826a29b2ca6f674e225d90e68b7dbadc2ba582d
|
||||
size 6620
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b07984494059bf827bc485cbea06d12e0283811face1a18799495f9ba7ae8af1
|
||||
size 20779
|
||||
oid sha256:f7d5b15add5104d91a03df7d86898f4bc415d095d11c23555b24440497371948
|
||||
size 1061
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e645142d284de40aafb7a4a858f3df92b6a5ba9b03fa5f1a2d3cb25211597926
|
||||
size 21857
|
||||
oid sha256:148fdae6493d7b7e1bb6cc6aae1861e0469838f54dcb3c15cc157a548c707fec
|
||||
size 1910
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:07631f41b8dea80713d2463f81a713a9a93798975b6fb50afbeeb13d26c57fa2
|
||||
size 48899
|
||||
oid sha256:934502e242ff7a2e34e21eed1424b5e0953e701761d158520b3297944132328e
|
||||
size 18716
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e38257b6917cdf5d73e90e6009f10c8736d62b20c4e785085305075c7e6320e2
|
||||
size 32037
|
||||
oid sha256:094620c172320b062f9a1f8cc758ef4bbee11bc0a6049f46ad6b42f9bf613c92
|
||||
size 9679
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e645142d284de40aafb7a4a858f3df92b6a5ba9b03fa5f1a2d3cb25211597926
|
||||
size 21857
|
||||
oid sha256:148fdae6493d7b7e1bb6cc6aae1861e0469838f54dcb3c15cc157a548c707fec
|
||||
size 1910
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ad83faf98b49f4e37112baedeae726f4f8d71bcdd1961d9cdad31f043f8ca666
|
||||
size 24003
|
||||
oid sha256:749bcd29d73e5ef2d1ef8b2d878626d0bca09c6b0d5f1c9dc6cefe7b9082c8cc
|
||||
size 3758
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:68529a6c11d5ffa7ecd9d5bbb11ceea28e6852bd45946b525af09602c9a1e1bf
|
||||
size 48899
|
||||
oid sha256:934502e242ff7a2e34e21eed1424b5e0953e701761d158520b3297944132328e
|
||||
size 18716
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8a70003840b418848b2ce6c18ed7cbbfcd6fcf76598a6601dca8b98d9b6c1a2f
|
||||
size 114706
|
||||
oid sha256:5719043940db268dccd2e20bd9d6aa13131890d43edf002a173714ae33890422
|
||||
size 29510
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:31afa7ed44c5d9844c8d6ce08beccac482c3f43590869a3d190d06e2df377ccc
|
||||
size 137472
|
||||
oid sha256:a4018d9df45b4a04d4cf24a40fe01aa7e30e44a9fdd8ad9a41b0d87791786c12
|
||||
size 30442
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0aac8ef9899442820bec0df8bf6434a46cc787d57c5d6d38a04727b8dc310048
|
||||
size 338281
|
||||
oid sha256:2eea06cb8ad05acefe9664551af5645d52d9763b82473b1fd4a2b2b6f62e96d3
|
||||
size 53550
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c07495891f15b138ba09f142777b0f43217bf8be05cbb74ba938319f3425980c
|
||||
size 321125
|
||||
oid sha256:90991aca91ab7222fdb85c03947cff38f549a6492551e7447e0c8f55022aae48
|
||||
size 52467
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d6bf6acb92421a453a36fc143ab6cefda14d631ea5e6dbf95c6e252a445fcbac
|
||||
size 144797
|
||||
oid sha256:6c8439a64d18dbff17dd67f6405bf49f99695e9b22fc2cc541dc72c6e3167307
|
||||
size 30564
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e9ad650fda925b1c076a67d1ef70315fe4f14db888c9fd36ee4eba1d18c1e7d1
|
||||
size 166749
|
||||
oid sha256:f752615184160d7a78f28d9eef354c86e544f11eb1dde9f651d7acd315b3f2e6
|
||||
size 35934
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:16f6e9d7bd15fc528d934c252213de8792812e708b1810191c5f1767f7165852
|
||||
size 142331
|
||||
oid sha256:1a43f1d893e85aa99d335a657ec0f6c13a741db976c033451ab9a2328b8a5970
|
||||
size 35559
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e4901093fa6190bf37291b0fb6de23fba1be8ebbd742775a8565a4106722fbb6
|
||||
size 31942
|
||||
oid sha256:ebfc95bd4c0cbcc53d0ef9d314d26e09a347a22dabbf210597f405d9ed8646bf
|
||||
size 7729
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e4ae97c4f44910121a61686862c8342ce598db4cdf9d46b29e96d3cb9e43bd06
|
||||
size 22158
|
||||
oid sha256:99cb7da9282cfcfa64598455827f27ca6791d45ca0d2c3c2dc090d82468dac03
|
||||
size 4447
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:061e2d0ce8dc852dd298c80f2aed5fee8ea4b87511c00662aa2d00922c0ba3c2
|
||||
size 30162
|
||||
oid sha256:101568e946f1d4cea86d666187bbf71116bbf62e6eaf6d80bc3c5e2e184bdb15
|
||||
size 7938
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0fb4b4b77620d99dae7473b7bd8affe14630419835bd5719167ed200e657fa4f
|
||||
size 17504
|
||||
oid sha256:cf930ffd4efb0b7b627e05aac6e0f56252ea206623e8b5d097d803aa315cdfb8
|
||||
size 1812
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8aa9b1194f3244025578225a6a87cbc2dd12c70955ff615c8af640ea7f1334f1
|
||||
size 19619
|
||||
oid sha256:ba5fea53b349e254b4625035a308d5731cb06f6d0adc278874d14db2627962cb
|
||||
size 3424
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0c25ffb1af8160b3202977de8c32aaa235e22c643ffd8004e4546c96868ef3b9
|
||||
size 18317
|
||||
oid sha256:cf087f357cd439d14651073ac079542c60f0648a30dced2a8d19912124b3f8b6
|
||||
size 2310
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2db961b8f922a552d8ad374fdb56029efd4049a6cde10399b3d961242c82ce53
|
||||
size 22571
|
||||
oid sha256:421ad4db14c28ed18666158f9ec30747c5b8c757405c1efb32442978911b0c06
|
||||
size 4437
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f39d897a57d4da0a70ede7c91339660b28e9d8c57b3e7d749807b13baa4b85f3
|
||||
size 28559
|
||||
oid sha256:0d0044ebf7e0a5dd23ed64a1289c705d8f6c3c41a62d65e5a1371058855b8cec
|
||||
size 6546
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:263b75d58328499eef1f8fa2e64c30706f546badcc0c4464a043b231da93cd0d
|
||||
size 34969
|
||||
oid sha256:3b8717c5f2109dfce1bf7b017278059d4915b524a6eb7e83cfb1926e54ed6869
|
||||
size 7383
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:33522ad8a8e826b22dd9ad214f56e63e24bf55c00bd8c845925d848b855dfb48
|
||||
size 19619
|
||||
oid sha256:ba5fea53b349e254b4625035a308d5731cb06f6d0adc278874d14db2627962cb
|
||||
size 3424
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f405c9f3d908d038aea26049e533b0d10955adfac370c7b3b80209997ea706d0
|
||||
size 24407
|
||||
oid sha256:a32908a839a6cb0ca2a76d6aa60376ba8a14b4428f06c13149ec277514eb5676
|
||||
size 4533
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d110f6e151799a2327bcdf5ef94d6fc82b114783a8cc973a8915896679ba4a80
|
||||
size 28559
|
||||
oid sha256:0d0044ebf7e0a5dd23ed64a1289c705d8f6c3c41a62d65e5a1371058855b8cec
|
||||
size 6546
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:db8f00568fad4e49b05249aaa7a48c9fbf85c8b7a78489c83dc9b8161778bcef
|
||||
size 22571
|
||||
oid sha256:421ad4db14c28ed18666158f9ec30747c5b8c757405c1efb32442978911b0c06
|
||||
size 4437
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"restricted_platform_relative_path": "Templates",
|
||||
"origin": "The primary repo for DefaultProject goes here: i.e. http://www.mydomain.com",
|
||||
"license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT",
|
||||
"display_name": "Default",
|
||||
"summary": "A short description of DefaultProject.",
|
||||
"display_name": "Standard",
|
||||
"summary": "This template has everything you need to build a full online 3D game or application.",
|
||||
"included_gems": ["Atom","Camera","EMotionFX","UI","Maestro","Input","ImGui"],
|
||||
"canonical_tags": [],
|
||||
"user_tags": [
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:61efd8df621780af995fc1250918df5e00364ff00f849bef67702cd4b0a152e1
|
||||
size 65537
|
||||
oid sha256:41239f8345fa91fe546442208461ad3cd17c7a7a7047af45018b97363bfea204
|
||||
size 109783
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cf6d56fe4c367d39bd78500dd34332fcad57ad41241768b52781dbdb60ddd972
|
||||
size 347568
|
||||
oid sha256:7c8433178baebafe984ca23d9325d3c71b5a177fc3b3b869afbb01a583542fbe
|
||||
size 462842
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e38257b6917cdf5d73e90e6009f10c8736d62b20c4e785085305075c7e6320e2
|
||||
size 32037
|
||||
oid sha256:094620c172320b062f9a1f8cc758ef4bbee11bc0a6049f46ad6b42f9bf613c92
|
||||
size 9679
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9f41a37d2347a617e93bd97adaf6d4c161c471ca3ef7e04b98c65ddda52396dc
|
||||
size 27833
|
||||
oid sha256:f3c651ca45a83d0f68bdaa466826a29b2ca6f674e225d90e68b7dbadc2ba582d
|
||||
size 6620
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b07984494059bf827bc485cbea06d12e0283811face1a18799495f9ba7ae8af1
|
||||
size 20779
|
||||
oid sha256:f7d5b15add5104d91a03df7d86898f4bc415d095d11c23555b24440497371948
|
||||
size 1061
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e645142d284de40aafb7a4a858f3df92b6a5ba9b03fa5f1a2d3cb25211597926
|
||||
size 21857
|
||||
oid sha256:148fdae6493d7b7e1bb6cc6aae1861e0469838f54dcb3c15cc157a548c707fec
|
||||
size 1910
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:07631f41b8dea80713d2463f81a713a9a93798975b6fb50afbeeb13d26c57fa2
|
||||
size 48899
|
||||
oid sha256:934502e242ff7a2e34e21eed1424b5e0953e701761d158520b3297944132328e
|
||||
size 18716
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e38257b6917cdf5d73e90e6009f10c8736d62b20c4e785085305075c7e6320e2
|
||||
size 32037
|
||||
oid sha256:094620c172320b062f9a1f8cc758ef4bbee11bc0a6049f46ad6b42f9bf613c92
|
||||
size 9679
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e645142d284de40aafb7a4a858f3df92b6a5ba9b03fa5f1a2d3cb25211597926
|
||||
size 21857
|
||||
oid sha256:148fdae6493d7b7e1bb6cc6aae1861e0469838f54dcb3c15cc157a548c707fec
|
||||
size 1910
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ad83faf98b49f4e37112baedeae726f4f8d71bcdd1961d9cdad31f043f8ca666
|
||||
size 24003
|
||||
oid sha256:749bcd29d73e5ef2d1ef8b2d878626d0bca09c6b0d5f1c9dc6cefe7b9082c8cc
|
||||
size 3758
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:68529a6c11d5ffa7ecd9d5bbb11ceea28e6852bd45946b525af09602c9a1e1bf
|
||||
size 48899
|
||||
oid sha256:934502e242ff7a2e34e21eed1424b5e0953e701761d158520b3297944132328e
|
||||
size 18716
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8a70003840b418848b2ce6c18ed7cbbfcd6fcf76598a6601dca8b98d9b6c1a2f
|
||||
size 114706
|
||||
oid sha256:5719043940db268dccd2e20bd9d6aa13131890d43edf002a173714ae33890422
|
||||
size 29510
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:31afa7ed44c5d9844c8d6ce08beccac482c3f43590869a3d190d06e2df377ccc
|
||||
size 137472
|
||||
oid sha256:a4018d9df45b4a04d4cf24a40fe01aa7e30e44a9fdd8ad9a41b0d87791786c12
|
||||
size 30442
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0aac8ef9899442820bec0df8bf6434a46cc787d57c5d6d38a04727b8dc310048
|
||||
size 338281
|
||||
oid sha256:2eea06cb8ad05acefe9664551af5645d52d9763b82473b1fd4a2b2b6f62e96d3
|
||||
size 53550
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c07495891f15b138ba09f142777b0f43217bf8be05cbb74ba938319f3425980c
|
||||
size 321125
|
||||
oid sha256:90991aca91ab7222fdb85c03947cff38f549a6492551e7447e0c8f55022aae48
|
||||
size 52467
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d6bf6acb92421a453a36fc143ab6cefda14d631ea5e6dbf95c6e252a445fcbac
|
||||
size 144797
|
||||
oid sha256:6c8439a64d18dbff17dd67f6405bf49f99695e9b22fc2cc541dc72c6e3167307
|
||||
size 30564
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user