Integrating latest 47acbe8
This commit is contained in:
@@ -21,9 +21,6 @@ ly_add_target(
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
.
|
||||
COMPILE_DEFINITIONS
|
||||
PRIVATE
|
||||
METRICS_ENABLED
|
||||
BUILD_DEPENDENCIES
|
||||
PUBLIC
|
||||
AZ::AzToolsFramework
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <AzFramework/Input/System/InputSystemComponent.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/Components/AzFrameworkConfigurationSystemComponent.h>
|
||||
|
||||
#include <AzToolsFramework/Archive/ArchiveComponent.h>
|
||||
#include <AzToolsFramework/Asset/AssetDebugInfo.h>
|
||||
@@ -192,6 +193,7 @@ namespace AssetBundler
|
||||
for (auto iter = components.begin(); iter != components.end();)
|
||||
{
|
||||
if (*iter == azrtti_typeid<AzFramework::GameEntityContextComponent>() ||
|
||||
*iter == azrtti_typeid<AzFramework::AzFrameworkConfigurationSystemComponent>() ||
|
||||
*iter == azrtti_typeid<AzFramework::InputSystemComponent>() ||
|
||||
*iter == azrtti_typeid<AzFramework::DrillerNetworkAgentComponent>() ||
|
||||
*iter == azrtti_typeid<AZ::SliceSystemComponent>())
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace AssetBundler
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
const AZ::u32 PlatformFlags_RESTRICTED = aznumeric_cast<AZ::u32>(AzFramework::PlatformFlags::Platform_JASPER | AzFramework::PlatformFlags::Platform_PROVO | AzFramework::PlatformFlags::Platform_SALEM | AzFramework::PlatformFlags::Platform_XENIA);
|
||||
const AZ::u32 PlatformFlags_RESTRICTED = aznumeric_cast<AZ::u32>(AzFramework::PlatformFlags::Platform_JASPER | AzFramework::PlatformFlags::Platform_PROVO | AzFramework::PlatformFlags::Platform_SALEM);
|
||||
|
||||
void AddPlatformSeeds(
|
||||
AZStd::string rootFolder,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
es3=enabled
|
||||
;ios=enabled
|
||||
;osx_gl=enabled
|
||||
;xenia=enabled
|
||||
;provo=enabled
|
||||
;server=enabled
|
||||
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
;es3=enabled
|
||||
ios=enabled
|
||||
;osx_gl=enabled
|
||||
;xenia=enabled
|
||||
;provo=enabled
|
||||
;server=enabled
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
;es3=enabled
|
||||
;ios=enabled
|
||||
;osx_gl=enabled
|
||||
;xenia=enabled
|
||||
provo=enabled
|
||||
;server=enabled
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityModelComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntitySearchComponent.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponent.h>
|
||||
#include <AzToolsFramework/Slice/SliceMetadataEntityContextComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ToolsAssetCatalogComponent.h>
|
||||
|
||||
@@ -81,6 +82,7 @@ AZ::ComponentTypeList AssetBuilderApplication::GetRequiredSystemComponents() con
|
||||
azrtti_typeid<AzToolsFramework::Components::EditorEntitySearchComponent>(),
|
||||
azrtti_typeid<AzToolsFramework::Components::EditorEntityModelComponent>(),
|
||||
azrtti_typeid<AzToolsFramework::EditorEntityContextComponent>(),
|
||||
azrtti_typeid<AzToolsFramework::Prefab::PrefabSystemComponent>(),
|
||||
});
|
||||
|
||||
return components;
|
||||
|
||||
@@ -90,17 +90,10 @@ namespace AssetBuilderSDK
|
||||
{
|
||||
return AssetBuilderSDK::Platform_OSX;
|
||||
}
|
||||
if (azstricmp(newPlatformName, "xenia") == 0)
|
||||
{
|
||||
return AssetBuilderSDK::Platform_XENIA;
|
||||
}
|
||||
if (azstricmp(newPlatformName, "provo") == 0)
|
||||
{
|
||||
return AssetBuilderSDK::Platform_PROVO;
|
||||
}
|
||||
#if defined(AZ_PLATFORM_XENIA) || defined(TOOLS_SUPPORT_XENIA)
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(AssetBuilderSDK_cpp, xenia)
|
||||
#endif
|
||||
#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER)
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(AssetBuilderSDK_cpp, jasper)
|
||||
#endif
|
||||
@@ -128,8 +121,6 @@ namespace AssetBuilderSDK
|
||||
return "ios";
|
||||
case AssetBuilderSDK::Platform_OSX:
|
||||
return "osx_gl";
|
||||
case AssetBuilderSDK::Platform_XENIA:
|
||||
return "xenia";
|
||||
case AssetBuilderSDK::Platform_PROVO:
|
||||
return "provo";
|
||||
case AssetBuilderSDK::Platform_SALEM:
|
||||
|
||||
@@ -151,13 +151,12 @@ namespace AssetBuilderSDK
|
||||
Platform_ES3 = 0x02,
|
||||
Platform_IOS = 0x04,
|
||||
Platform_OSX = 0x08,
|
||||
Platform_XENIA = 0x10,
|
||||
Platform_PROVO = 0x20,
|
||||
Platform_SALEM = 0x40,
|
||||
Platform_JASPER = 0x80,
|
||||
|
||||
//! if you add a new platform entry to this enum, you must add it to allplatforms as well otherwise that platform would not be considered valid.
|
||||
AllPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_XENIA | Platform_PROVO | Platform_SALEM | Platform_JASPER
|
||||
AllPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER
|
||||
};
|
||||
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
||||
//! Map data structure to holder parameters that are passed into a job for ProcessJob requests.
|
||||
|
||||
@@ -41,7 +41,7 @@ ly_add_target(
|
||||
3rdParty::Qt::Network
|
||||
3rdParty::RapidJSON
|
||||
3rdParty::SQLite
|
||||
3rdParty::XXHash
|
||||
3rdParty::xxhash
|
||||
AZ::AzCore
|
||||
AZ::AzFramework
|
||||
AZ::AzQtComponents
|
||||
@@ -82,11 +82,6 @@ ly_add_target(
|
||||
PRIVATE
|
||||
AZ::AssetProcessor.Static
|
||||
)
|
||||
ly_add_source_properties(
|
||||
SOURCES native/utilities/BatchApplicationManager.cpp
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
VALUES LY_METRICS_BUILD_TIME=${LY_METRICS_BUILD_TIME}
|
||||
)
|
||||
|
||||
# Adds the AssetProcessor target as a C preprocessor define so that it can be used as a Settings Registry
|
||||
# specialization in order to look up the generated .setreg which contains the dependencies
|
||||
|
||||
@@ -86,8 +86,8 @@ Connection::Connection(bool isUserCreatedConnection, qintptr socketDescriptor, Q
|
||||
connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ConnectionEstablished, this, &Connection::OnConnectionEstablished, Qt::BlockingQueuedConnection);
|
||||
connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ErrorMessage, this, &Connection::ErrorMessage);
|
||||
|
||||
connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::IsAddressWhiteListed, this, &Connection::IsAddressWhiteListed);
|
||||
connect(this, &Connection::AddressIsWhiteListed, m_connectionWorker, &AssetProcessor::ConnectionWorker::AddressIsWhiteListed);
|
||||
connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::IsAddressInAllowedList, this, &Connection::IsAddressInAllowedList);
|
||||
connect(this, &Connection::AddressIsInAllowedList, m_connectionWorker, &AssetProcessor::ConnectionWorker::AddressIsInAllowedList);
|
||||
}
|
||||
|
||||
void Connection::Activate(qintptr socketDescriptor)
|
||||
|
||||
@@ -202,9 +202,9 @@ Q_SIGNALS:
|
||||
void Error(unsigned int connId, QString errorString);
|
||||
|
||||
// the token is just any identifier to identify a particular connection, potentially from the same host.
|
||||
// the response (AddressIsWhiteListed) will have the same token as was sent.
|
||||
void IsAddressWhiteListed(QHostAddress hostAddress, void* token);
|
||||
void AddressIsWhiteListed(void* token, bool result);
|
||||
// the response (AddressIsInAllowedList) will have the same token as was sent.
|
||||
void IsAddressInAllowedList(QHostAddress hostAddress, void* token);
|
||||
void AddressIsInAllowedList(void* token, bool result);
|
||||
|
||||
//metrics
|
||||
void NumOpenRequestsChanged();
|
||||
|
||||
@@ -51,20 +51,20 @@ ConnectionManager::ConnectionManager(QObject* parent)
|
||||
|
||||
ConnectionManagerRequestBus::Handler::BusConnect();
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(UpdateWhiteListFromBootStrap()));
|
||||
QTimer::singleShot(0, this, SLOT(UpdateAllowedListFromBootStrap()));
|
||||
}
|
||||
|
||||
void ConnectionManager::UpdateWhiteListFromBootStrap()
|
||||
void ConnectionManager::UpdateAllowedListFromBootStrap()
|
||||
{
|
||||
m_whiteListedAddresses.clear();
|
||||
QString whitelist = AssetUtilities::ReadWhitelistFromSettingsRegistry();
|
||||
AZStd::vector<AZStd::string> whitelistaddressList;
|
||||
AzFramework::StringFunc::Tokenize(whitelist.toUtf8().constData(), whitelistaddressList, ", \t\n\r");
|
||||
for (const AZStd::string& whitelistaddress : whitelistaddressList)
|
||||
m_allowedListAddresses.clear();
|
||||
QString allowedlist = AssetUtilities::ReadAllowedlistFromSettingsRegistry();
|
||||
AZStd::vector<AZStd::string> allowedlistaddressList;
|
||||
AzFramework::StringFunc::Tokenize(allowedlist.toUtf8().constData(), allowedlistaddressList, ", \t\n\r");
|
||||
for (const AZStd::string& allowedlistaddress : allowedlistaddressList)
|
||||
{
|
||||
m_whiteListedAddresses << whitelistaddress.c_str();
|
||||
m_allowedListAddresses << allowedlistaddress.c_str();
|
||||
}
|
||||
Q_EMIT SyncWhiteListAndRejectedList(m_whiteListedAddresses, m_rejectedAddresses);
|
||||
Q_EMIT SyncAllowedListAndRejectedList(m_allowedListAddresses, m_rejectedAddresses);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,8 +121,8 @@ unsigned int ConnectionManager::internalAddConnection(bool isUserConnection, qin
|
||||
}
|
||||
|
||||
Connection* connection = new Connection(isUserConnection, socketDescriptor, this);
|
||||
connect(connection, &Connection::IsAddressWhiteListed, this, &ConnectionManager::IsAddressWhiteListed);
|
||||
connect(this, &ConnectionManager::AddressIsWhiteListed, connection, &Connection::AddressIsWhiteListed);
|
||||
connect(connection, &Connection::IsAddressInAllowedList, this, &ConnectionManager::IsAddressInAllowedList);
|
||||
connect(this, &ConnectionManager::AddressIsInAllowedList, connection, &Connection::AddressIsInAllowedList);
|
||||
|
||||
connection->SetConnectionId(connectionId);
|
||||
connect(connection, &Connection::StatusChanged, this, &ConnectionManager::OnStatusChanged);
|
||||
@@ -496,31 +496,31 @@ void ConnectionManager::NewConnection(qintptr socketDescriptor)
|
||||
addConnection(socketDescriptor);
|
||||
}
|
||||
|
||||
void ConnectionManager::WhiteListingEnabled(bool enabled)
|
||||
void ConnectionManager::AllowedListingEnabled(bool enabled)
|
||||
{
|
||||
m_whiteListingEnabled = enabled;
|
||||
m_allowedListingEnabled = enabled;
|
||||
}
|
||||
|
||||
void ConnectionManager::AddWhiteListedAddress(QString address)
|
||||
void ConnectionManager::AddAddressToAllowedList(QString address)
|
||||
{
|
||||
UpdateWhiteListFromBootStrap();
|
||||
while (m_whiteListedAddresses.removeOne(address)) {}
|
||||
m_whiteListedAddresses << address;
|
||||
AssetUtilities::WriteWhitelistToBootstrap(m_whiteListedAddresses);
|
||||
Q_EMIT SyncWhiteListAndRejectedList(m_whiteListedAddresses, m_rejectedAddresses);
|
||||
UpdateAllowedListFromBootStrap();
|
||||
while (m_allowedListAddresses.removeOne(address)) {}
|
||||
m_allowedListAddresses << address;
|
||||
AssetUtilities::WriteAllowedlistToBootstrap(m_allowedListAddresses);
|
||||
Q_EMIT SyncAllowedListAndRejectedList(m_allowedListAddresses, m_rejectedAddresses);
|
||||
}
|
||||
|
||||
void ConnectionManager::RemoveWhiteListedAddress(QString address)
|
||||
void ConnectionManager::RemoveAddressFromAllowedList(QString address)
|
||||
{
|
||||
UpdateWhiteListFromBootStrap();
|
||||
while (m_whiteListedAddresses.removeOne(address)) {}
|
||||
AssetUtilities::WriteWhitelistToBootstrap(m_whiteListedAddresses);
|
||||
Q_EMIT SyncWhiteListAndRejectedList(m_whiteListedAddresses, m_rejectedAddresses);
|
||||
UpdateAllowedListFromBootStrap();
|
||||
while (m_allowedListAddresses.removeOne(address)) {}
|
||||
AssetUtilities::WriteAllowedlistToBootstrap(m_allowedListAddresses);
|
||||
Q_EMIT SyncAllowedListAndRejectedList(m_allowedListAddresses, m_rejectedAddresses);
|
||||
}
|
||||
|
||||
void ConnectionManager::AddRejectedAddress(QString address, bool surpressWarning)
|
||||
{
|
||||
UpdateWhiteListFromBootStrap();
|
||||
UpdateAllowedListFromBootStrap();
|
||||
bool alreadyRejected = false;
|
||||
while (m_rejectedAddresses.removeOne(address)) { alreadyRejected = true; }
|
||||
m_rejectedAddresses << address;
|
||||
@@ -528,21 +528,21 @@ void ConnectionManager::AddRejectedAddress(QString address, bool surpressWarning
|
||||
{
|
||||
Q_EMIT FirstTimeAddedToRejctedList(address);
|
||||
}
|
||||
Q_EMIT SyncWhiteListAndRejectedList(m_whiteListedAddresses, m_rejectedAddresses);
|
||||
Q_EMIT SyncAllowedListAndRejectedList(m_allowedListAddresses, m_rejectedAddresses);
|
||||
}
|
||||
|
||||
void ConnectionManager::RemoveRejectedAddress(QString address)
|
||||
{
|
||||
UpdateWhiteListFromBootStrap();
|
||||
UpdateAllowedListFromBootStrap();
|
||||
while (m_rejectedAddresses.removeOne(address)) {}
|
||||
Q_EMIT SyncWhiteListAndRejectedList(m_whiteListedAddresses, m_rejectedAddresses);
|
||||
Q_EMIT SyncAllowedListAndRejectedList(m_allowedListAddresses, m_rejectedAddresses);
|
||||
}
|
||||
|
||||
void ConnectionManager::IsAddressWhiteListed(QHostAddress incominghostaddr, void* token)
|
||||
void ConnectionManager::IsAddressInAllowedList(QHostAddress incominghostaddr, void* token)
|
||||
{
|
||||
if (!m_whiteListingEnabled)
|
||||
if (!m_allowedListingEnabled)
|
||||
{
|
||||
Q_EMIT AddressIsWhiteListed(token, true);
|
||||
Q_EMIT AddressIsInAllowedList(token, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -550,9 +550,9 @@ void ConnectionManager::IsAddressWhiteListed(QHostAddress incominghostaddr, void
|
||||
|
||||
if (incominghostaddr != QHostAddress::Null)
|
||||
{
|
||||
// any ipv4 address will be like ::ffff:A.B.C.D, we have to retrieve A.B.C.D for comparision with the whitelisted addresses.
|
||||
// any ipv4 address will be like ::ffff:A.B.C.D, we have to retrieve A.B.C.D for comparision with the allowedlisted addresses.
|
||||
// for example Qt will tell us the ipv6 (::ffff:127.0.0.1) for 127.0.0.1,
|
||||
// but the whitelist below will report ipv4 (127.0.0.1) and ipv6 (::1), and they both won't match to ipv6 (::ffff:127.0.0.1).
|
||||
// but the allowedlist below will report ipv4 (127.0.0.1) and ipv6 (::1), and they both won't match to ipv6 (::ffff:127.0.0.1).
|
||||
bool wasConverted = false;
|
||||
quint32 incomingIPv4 = incominghostaddr.toIPv4Address(&wasConverted);
|
||||
if (wasConverted)
|
||||
@@ -567,29 +567,29 @@ void ConnectionManager::IsAddressWhiteListed(QHostAddress incominghostaddr, void
|
||||
|
||||
QHostInfo incomingInfo = QHostInfo::fromName(incomingIpAddress);
|
||||
|
||||
QString whitelist = AssetUtilities::ReadWhitelistFromSettingsRegistry();
|
||||
QString allowedlist = AssetUtilities::ReadAllowedlistFromSettingsRegistry();
|
||||
|
||||
AZStd::vector<AZStd::string> whitelistaddressList;
|
||||
AzFramework::StringFunc::Tokenize(whitelist.toUtf8().constData(), whitelistaddressList, ", \t\n\r");
|
||||
AZStd::vector<AZStd::string> allowedlistaddressList;
|
||||
AzFramework::StringFunc::Tokenize(allowedlist.toUtf8().constData(), allowedlistaddressList, ", \t\n\r");
|
||||
|
||||
// allow localhost, loopback regardless, there's no good reason to accidentally lock yourself out your own computer.
|
||||
for (const auto& address : QNetworkInterface::allAddresses()) // allAdresses returns the ip address of all local interfaces.
|
||||
{
|
||||
whitelistaddressList.push_back(address.toString().toUtf8().constData());
|
||||
allowedlistaddressList.push_back(address.toString().toUtf8().constData());
|
||||
}
|
||||
|
||||
// does the incoming connection match any entries?
|
||||
for (const AZStd::string& whitelistaddress : whitelistaddressList)
|
||||
for (const AZStd::string& allowedListaddress : allowedlistaddressList)
|
||||
{
|
||||
//address range matching
|
||||
size_t maskLocation = whitelistaddress.find('/');
|
||||
size_t maskLocation = allowedListaddress.find('/');
|
||||
if (maskLocation != AZStd::string::npos)
|
||||
{
|
||||
//x.x.x.x/0 is all addresses
|
||||
int mask = atoi(whitelistaddress.substr(maskLocation + 1).c_str());
|
||||
int mask = atoi(allowedListaddress.substr(maskLocation + 1).c_str());
|
||||
if (mask == 0)
|
||||
{
|
||||
Q_EMIT AddressIsWhiteListed(token, true);
|
||||
Q_EMIT AddressIsInAllowedList(token, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -602,35 +602,35 @@ void ConnectionManager::IsAddressWhiteListed(QHostAddress incominghostaddr, void
|
||||
//QT should first do a check and see if we are comparing convertible protocols before just early outing.
|
||||
//If it wasn't convertible to ipv4 then we know it is ipv6 in which case the protocols will match which make this unnecessary, but still correct.
|
||||
QHostAddress ha(incomingIpAddress);
|
||||
if (ha.isInSubnet(QHostAddress::parseSubnet(whitelistaddress.c_str())))
|
||||
if (ha.isInSubnet(QHostAddress::parseSubnet(allowedListaddress.c_str())))
|
||||
{
|
||||
Q_EMIT AddressIsWhiteListed(token, true);
|
||||
Q_EMIT AddressIsInAllowedList(token, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else//direct address matching
|
||||
{
|
||||
QHostInfo whiteInfo;
|
||||
QHostAddress whiteHostAddress(whitelistaddress.c_str());
|
||||
if ((whiteHostAddress.isNull()))
|
||||
QHostInfo allowedInfo;
|
||||
QHostAddress allowedHostAddress(allowedListaddress.c_str());
|
||||
if ((allowedHostAddress.isNull()))
|
||||
{
|
||||
whiteInfo = QHostInfo::fromName(QString::fromUtf8(whitelistaddress.c_str()));
|
||||
allowedInfo = QHostInfo::fromName(QString::fromUtf8(allowedListaddress.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QList<QHostAddress> addresses;
|
||||
addresses << whiteHostAddress;
|
||||
whiteInfo.setAddresses(addresses);
|
||||
addresses << allowedHostAddress;
|
||||
allowedInfo.setAddresses(addresses);
|
||||
}
|
||||
|
||||
for (const auto& whiteAddress : whiteInfo.addresses())
|
||||
for (const auto& allowedAddress : allowedInfo.addresses())
|
||||
{
|
||||
for (const auto& address : incomingInfo.addresses())
|
||||
{
|
||||
if (address == whiteAddress)
|
||||
if (address == allowedAddress)
|
||||
{
|
||||
Q_EMIT AddressIsWhiteListed(token, true);
|
||||
Q_EMIT AddressIsInAllowedList(token, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -639,7 +639,7 @@ void ConnectionManager::IsAddressWhiteListed(QHostAddress incominghostaddr, void
|
||||
}
|
||||
|
||||
AddRejectedAddress(incomingIpAddress);
|
||||
Q_EMIT AddressIsWhiteListed(token, false);
|
||||
Q_EMIT AddressIsInAllowedList(token, false);
|
||||
}
|
||||
|
||||
void ConnectionManager::AddBytesReceived(unsigned int connId, qint64 add, bool update)
|
||||
|
||||
@@ -109,10 +109,10 @@ Q_SIGNALS:
|
||||
|
||||
void ReadyToQuit(QObject* source);
|
||||
|
||||
void SyncWhiteListAndRejectedList(QStringList whiteList, QStringList rejectedList);
|
||||
void SyncAllowedListAndRejectedList(QStringList allowedList, QStringList rejectedList);
|
||||
|
||||
// this is a response to the whitelist request with that same token.
|
||||
void AddressIsWhiteListed(void* token, bool result);
|
||||
// this is a response to the allowedlist request with that same token.
|
||||
void AddressIsInAllowedList(void* token, bool result);
|
||||
|
||||
void FirstTimeAddedToRejctedList(QString ipAddress);
|
||||
|
||||
@@ -123,10 +123,10 @@ public Q_SLOTS:
|
||||
void MakeSureConnectionMapEmpty();
|
||||
void NewConnection(qintptr socketDescriptor);
|
||||
|
||||
void WhiteListingEnabled(bool enabled);
|
||||
void IsAddressWhiteListed(QHostAddress hostAddress, void* token);
|
||||
void AddWhiteListedAddress(QString address);
|
||||
void RemoveWhiteListedAddress(QString address);
|
||||
void AllowedListingEnabled(bool enabled);
|
||||
void IsAddressInAllowedList(QHostAddress hostAddress, void* token);
|
||||
void AddAddressToAllowedList(QString address);
|
||||
void RemoveAddressFromAllowedList(QString address);
|
||||
void AddRejectedAddress(QString address, bool surpressWarning = false);
|
||||
void RemoveRejectedAddress(QString address);
|
||||
|
||||
@@ -185,7 +185,7 @@ public Q_SLOTS:
|
||||
|
||||
void OnStatusChanged(unsigned int connId);
|
||||
|
||||
void UpdateWhiteListFromBootStrap();
|
||||
void UpdateAllowedListFromBootStrap();
|
||||
|
||||
private:
|
||||
|
||||
@@ -205,11 +205,11 @@ private:
|
||||
// the key is the name of the platform, and the value is the number of those kind of platforms.
|
||||
QHash<QString, int> m_platformsConnected;
|
||||
|
||||
//white listing
|
||||
bool m_whiteListingEnabled = true;
|
||||
//allowed listing
|
||||
bool m_allowedListingEnabled = true;
|
||||
|
||||
//these lists are just caches, only used for updating
|
||||
QStringList m_whiteListedAddresses;
|
||||
QStringList m_allowedListAddresses;
|
||||
QStringList m_rejectedAddresses;
|
||||
};
|
||||
|
||||
|
||||
@@ -378,11 +378,11 @@ void ConnectionWorker::ConnectSocket(qintptr socketDescriptor)
|
||||
disconnect(&m_engineSocket, &QTcpSocket::stateChanged, this, &ConnectionWorker::EngineSocketStateChanged);
|
||||
m_engineSocket.setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState, QIODevice::ReadWrite);
|
||||
|
||||
Q_EMIT IsAddressWhiteListed(m_engineSocket.peerAddress(), reinterpret_cast<void*>(this));
|
||||
Q_EMIT IsAddressInAllowedList(m_engineSocket.peerAddress(), reinterpret_cast<void*>(this));
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionWorker::AddressIsWhiteListed(void* token, bool result)
|
||||
void ConnectionWorker::AddressIsInAllowedList(void* token, bool result)
|
||||
{
|
||||
if (reinterpret_cast<void*>(this) == token)
|
||||
{
|
||||
@@ -395,7 +395,7 @@ void ConnectionWorker::AddressIsWhiteListed(void* token, bool result)
|
||||
else
|
||||
{
|
||||
// this address has been rejected, disconnect immediately!!!
|
||||
AZ_TracePrintf(AssetProcessor::ConsoleChannel, " A connection attempt was ignored because it is not whitelisted. Please consider adding white_list=(IP ADDRESS),localhost to the bootstrap.cfg");
|
||||
AZ_TracePrintf(AssetProcessor::ConsoleChannel, " A connection attempt was ignored because it is not in the allowed list. Please consider adding allowed_list=(IP ADDRESS),localhost to the bootstrap.cfg");
|
||||
|
||||
disconnect(&m_engineSocket, &QTcpSocket::readyRead, this, &ConnectionWorker::EngineSocketHasData);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Q_SIGNALS:
|
||||
void ErrorMessage(QString msg);
|
||||
|
||||
// the token identifies the unique connection instance, since multiple may have the same address
|
||||
void IsAddressWhiteListed(QHostAddress hostAddress, void* token);
|
||||
void IsAddressInAllowedList(QHostAddress hostAddress, void* token);
|
||||
|
||||
public Q_SLOTS:
|
||||
void ConnectSocket(qintptr socketDescriptor);
|
||||
@@ -70,8 +70,8 @@ Q_SIGNALS:
|
||||
void RequestTerminate();
|
||||
bool NegotiateDirect(bool initiate);
|
||||
|
||||
// the token will be the same token sent in the whitelisting request.
|
||||
void AddressIsWhiteListed(void* token, bool result);
|
||||
// the token will be the same token sent in the allowedlisting request.
|
||||
void AddressIsInAllowedList(void* token, bool result);
|
||||
|
||||
private Q_SLOTS:
|
||||
void TerminateConnection();
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace AssetProcessorMessagesTests
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
AssetUtilities::ResetGameName();
|
||||
|
||||
m_temporarySourceDir = QDir(m_temporaryDir.path());
|
||||
@@ -165,10 +166,12 @@ namespace AssetProcessorMessagesTests
|
||||
});
|
||||
|
||||
|
||||
#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
QEventLoop eventLoop;
|
||||
|
||||
QObject::connect(m_batchApplicationManager->m_connectionManager, &ConnectionManager::ReadyToQuit, &eventLoop, &QEventLoop::quit);
|
||||
@@ -179,6 +182,7 @@ namespace AssetProcessorMessagesTests
|
||||
|
||||
m_assetSystemComponent->Deactivate();
|
||||
m_batchApplicationManager->Destroy();
|
||||
#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
}
|
||||
|
||||
void RunNetworkRequest(AZStd::function<void()> func) const
|
||||
@@ -222,7 +226,11 @@ namespace AssetProcessorMessagesTests
|
||||
AZStd::unique_ptr<AzFramework::AssetSystem::BaseAssetProcessorMessage> m_response;
|
||||
};
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(AssetProcessorMessages, DISABLED_All)
|
||||
#else
|
||||
TEST_F(AssetProcessorMessages, All)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
// Test that we can successfully send network messages and have them arrive for processing
|
||||
// For messages that have a response, it also verifies the response comes back
|
||||
@@ -300,7 +308,11 @@ namespace AssetProcessorMessagesTests
|
||||
});
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(AssetProcessorMessages, DISABLED_GetUnresolvedProductReferences_Succeeds)
|
||||
#else
|
||||
TEST_F(AssetProcessorMessages, GetUnresolvedProductReferences_Succeeds)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
using namespace AzToolsFramework::AssetDatabase;
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
//using namespace testing;
|
||||
@@ -478,12 +480,20 @@ namespace UnitTests
|
||||
TestGetSourcesByPath("dev/", { }, false);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(SourceFileRelocatorTest, DISABLED_GetSources_MultipleScanFolders_Fails)
|
||||
#else
|
||||
TEST_F(SourceFileRelocatorTest, GetSources_MultipleScanFolders_Fails)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
TestGetSourcesByPath("*", { }, false);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(SourceFileRelocatorTest, DISABLED_GetSources_PartialPath_FailsWithNoResults)
|
||||
#else
|
||||
TEST_F(SourceFileRelocatorTest, GetSources_PartialPath_FailsWithNoResults)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
TestGetSourcesByPath("older/*", { }, false);
|
||||
}
|
||||
@@ -530,7 +540,11 @@ namespace UnitTests
|
||||
TestGetSourcesByPath(filePath.toUtf8().constData(), { "folder/file.foo" }, true, true);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(SourceFileRelocatorTest, DISABLED_GetSources_HaveMetadataDifferentFileCase_AbsolutePath_Succeeds)
|
||||
#else
|
||||
TEST_F(SourceFileRelocatorTest, GetSources_HaveMetadataDifferentFileCase_AbsolutePath_Succeeds)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
QDir tempPath(m_tempDir.path());
|
||||
|
||||
@@ -900,7 +914,11 @@ namespace UnitTests
|
||||
ASSERT_FALSE(AZ::IO::FileIOBase::GetInstance()->Exists(filePath.toUtf8().constData()));
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(SourceFileRelocatorTest, DISABLED_Delete_Real_Readonly_Fails)
|
||||
#else
|
||||
TEST_F(SourceFileRelocatorTest, Delete_Real_Readonly_Fails)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
QDir tempPath(m_tempDir.path());
|
||||
|
||||
|
||||
@@ -83,15 +83,6 @@ namespace AssetProcessor
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(3), AssetBuilderSDK::Platform_OSX);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(4), AssetBuilderSDK::Platform_NONE);
|
||||
|
||||
#if defined(TOOLS_SUPPORT_XENIA)
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "xenia", {}
|
||||
}
|
||||
};
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(0), AssetBuilderSDK::Platform_XENIA);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_NONE);
|
||||
#endif
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
@@ -145,7 +136,6 @@ namespace AssetProcessor
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_ES3));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_IOS));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_OSX));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_XENIA));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_PROVO));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_SALEM));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_JASPER));
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "native/AssetManager/PathDependencyManager.h"
|
||||
#include <AzToolsFramework/ToolsFileUtils/ToolsFileUtils.h>
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
@@ -27,7 +28,13 @@ public:
|
||||
|
||||
friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies);
|
||||
friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_DeferredResolution);
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, DISABLED_AssetProcessed_Impl_MultiplatformDependencies_SourcePath);
|
||||
#else
|
||||
friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_SourcePath);
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, DeleteFolder_SignalsDeleteOfContainedFiles);
|
||||
|
||||
friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, QueryAbsolutePathDependenciesRecursive_BasicTest);
|
||||
@@ -69,9 +76,20 @@ public:
|
||||
friend class GTEST_TEST_CLASS_NAME_(AbsolutePathProductDependencyTest, UnresolvedProductPathDependency_AssetProcessedTwice_ValidatePathDependenciesMap);
|
||||
friend class GTEST_TEST_CLASS_NAME_(AbsolutePathProductDependencyTest, UnresolvedSourceFileTypeProductPathDependency_DependencyHasNoProductOutput_ValidatePathDependenciesMap);
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, DISABLED_ModtimeSkipping_FileUnchanged_WithoutModtimeSkipping);
|
||||
#else
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, ModtimeSkipping_FileUnchanged_WithoutModtimeSkipping);
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, ModtimeSkipping_FileUnchanged);
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, DISABLED_ModtimeSkipping_EnablePlatform_ShouldProcessFilesForPlatform);
|
||||
#else
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, ModtimeSkipping_EnablePlatform_ShouldProcessFilesForPlatform);
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, ModtimeSkipping_ModifyFile);
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, ModtimeSkipping_ModifyFile_AndThenRevert_ProcessesAgain);
|
||||
friend class GTEST_TEST_CLASS_NAME_(ModtimeScanningTest, ModtimeSkipping_ModifyFilesSameHash_BothProcess);
|
||||
@@ -2413,7 +2431,11 @@ TEST_F(PathDependencyTest, ChangeDependencies_Existing_ResolveCorrectly)
|
||||
);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(PathDependencyTest, DISABLED_MixedPathDependencies_Existing_ResolveCorrectly)
|
||||
#else
|
||||
TEST_F(PathDependencyTest, MixedPathDependencies_Existing_ResolveCorrectly)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
using namespace AssetProcessor;
|
||||
using namespace AssetBuilderSDK;
|
||||
@@ -2712,7 +2734,11 @@ TEST_F(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDepende
|
||||
ASSERT_NE(SearchDependencies(dependencyContainer, asset1.m_products[0]), SearchDependencies(dependencyContainer, asset1.m_products[1]));
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(MultiplatformPathDependencyTest, DISABLED_AssetProcessed_Impl_MultiplatformDependencies_SourcePath)
|
||||
#else
|
||||
TEST_F(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_SourcePath)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
// One product will be pc, one will be console (order is non-deterministic)
|
||||
TestAsset asset1("testAsset1");
|
||||
@@ -4585,7 +4611,11 @@ void ModtimeScanningTest::SetFileContents(QString filePath, QString contents)
|
||||
file.close();
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(ModtimeScanningTest, DISABLED_ModtimeSkipping_FileUnchanged_WithoutModtimeSkipping)
|
||||
#else
|
||||
TEST_F(ModtimeScanningTest, ModtimeSkipping_FileUnchanged_WithoutModtimeSkipping)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
using namespace AzToolsFramework::AssetSystem;
|
||||
|
||||
@@ -4614,7 +4644,11 @@ TEST_F(ModtimeScanningTest, ModtimeSkipping_FileUnchanged)
|
||||
ExpectNoWork();
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(ModtimeScanningTest, DISABLED_ModtimeSkipping_EnablePlatform_ShouldProcessFilesForPlatform)
|
||||
#else
|
||||
TEST_F(ModtimeScanningTest, ModtimeSkipping_EnablePlatform_ShouldProcessFilesForPlatform)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
using namespace AzToolsFramework::AssetSystem;
|
||||
|
||||
@@ -5118,7 +5152,11 @@ TEST_F(AssetProcessorManagerTest, UpdateSourceFileDependenciesDatabase_WildcardM
|
||||
dependList.clear();
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(AssetProcessorManagerTest, DISABLED_RemoveSource_RemoveCacheFolderIfEmpty_Ok)
|
||||
#else
|
||||
TEST_F(AssetProcessorManagerTest, RemoveSource_RemoveCacheFolderIfEmpty_Ok)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
using namespace AssetProcessor;
|
||||
using namespace AssetBuilderSDK;
|
||||
|
||||
+6
-2
@@ -13,6 +13,8 @@
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include "native/tests/platformconfiguration/platformconfigurationtests.h"
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
const char TestAppRoot[] = ":/testdata";
|
||||
const char EmptyDummyProjectName[] = "EmptyDummyProject";
|
||||
const char DummyProjectName[] = "DummyProject";
|
||||
@@ -111,7 +113,6 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Regular_Platforms)
|
||||
ASSERT_NE(config.GetPlatformByIdentifier(AzToolsFramework::AssetSystem::GetHostAssetPlatform()), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("es3"), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("server"), nullptr);
|
||||
ASSERT_EQ(config.GetPlatformByIdentifier("xenia"), nullptr);
|
||||
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("es3")->HasTag("mobile"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("es3")->HasTag("renderer"));
|
||||
@@ -431,7 +432,11 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_RegularExcludes)
|
||||
ASSERT_FALSE(config.IsFileExcluded("blahblah/Levels/blahblahhold/whatever.test"));
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(PlatformConfigurationUnitTests, DISABLED_TestFailReadConfigFile_Recognizers)
|
||||
#else
|
||||
TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Recognizers)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
using namespace AzToolsFramework::AssetSystem;
|
||||
using namespace AssetProcessor;
|
||||
@@ -530,7 +535,6 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Overrides)
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("es3"), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("provo"), nullptr);
|
||||
// this override swaps server with provo in that it turns ON provo, turns off server
|
||||
ASSERT_EQ(config.GetPlatformByIdentifier("xenia"), nullptr);
|
||||
ASSERT_EQ(config.GetPlatformByIdentifier("server"), nullptr); // this should be off due to overrides
|
||||
|
||||
// there is a rule which only output on server, so that rule should be omitted
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include <QHash>
|
||||
|
||||
#include "native/tests/AssetProcessorTest.h"
|
||||
|
||||
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
|
||||
using namespace AssetUtilities;
|
||||
|
||||
@@ -119,7 +119,11 @@ TEST_F(AssetUtilitiesTest, UpdateToCorrectCase_MissingFile_ReturnsFalse)
|
||||
EXPECT_FALSE(AssetUtilities::UpdateToCorrectCase(canonicalTempDirPath, fileName));
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
TEST_F(AssetUtilitiesTest, DISABLED_UpdateToCorrectCase_ExistingFile_ReturnsTrue_CorrectsCase)
|
||||
#else
|
||||
TEST_F(AssetUtilitiesTest, UpdateToCorrectCase_ExistingFile_ReturnsTrue_CorrectsCase)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
{
|
||||
QTemporaryDir dir;
|
||||
QDir tempPath(dir.path());
|
||||
|
||||
@@ -187,31 +187,31 @@ void MainWindow::Activate()
|
||||
ui->connectionTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->connectionTreeView, &QTreeView::customContextMenuRequested, this, &MainWindow::OnConnectionContextMenu);
|
||||
|
||||
//white list connections
|
||||
//allowed list connections
|
||||
connect(m_guiApplicationManager->GetConnectionManager(), &ConnectionManager::FirstTimeAddedToRejctedList, this, &MainWindow::FirstTimeAddedToRejctedList);
|
||||
connect(m_guiApplicationManager->GetConnectionManager(), &ConnectionManager::SyncWhiteListAndRejectedList, this, &MainWindow::SyncWhiteListAndRejectedList);
|
||||
connect(ui->whiteListWhiteListedConnectionsListView, &QListView::clicked, this, &MainWindow::OnWhiteListedConnectionsListViewClicked);
|
||||
ui->whiteListWhiteListedConnectionsListView->setModel(&m_whitelistedAddresses);
|
||||
connect(ui->whiteListRejectedConnectionsListView, &QListView::clicked, this, &MainWindow::OnRejectedConnectionsListViewClicked);
|
||||
ui->whiteListRejectedConnectionsListView->setModel(&m_rejectedAddresses);
|
||||
connect(m_guiApplicationManager->GetConnectionManager(), &ConnectionManager::SyncAllowedListAndRejectedList, this, &MainWindow::SyncAllowedListAndRejectedList);
|
||||
connect(ui->allowListAllowedListConnectionsListView, &QListView::clicked, this, &MainWindow::OnAllowedListConnectionsListViewClicked);
|
||||
ui->allowListAllowedListConnectionsListView->setModel(&m_allowedListAddresses);
|
||||
connect(ui->allowedListRejectedConnectionsListView, &QListView::clicked, this, &MainWindow::OnRejectedConnectionsListViewClicked);
|
||||
ui->allowedListRejectedConnectionsListView->setModel(&m_rejectedAddresses);
|
||||
|
||||
connect(ui->whiteListEnableCheckBox, &QCheckBox::toggled, this, &MainWindow::OnWhiteListCheckBoxToggled);
|
||||
connect(ui->allowedListEnableCheckBox, &QCheckBox::toggled, this, &MainWindow::OnAllowedListCheckBoxToggled);
|
||||
|
||||
connect(ui->whiteListAddHostNameToolButton, &QToolButton::clicked, this, &MainWindow::OnAddHostNameWhiteListButtonClicked);
|
||||
connect(ui->whiteListAddIPToolButton, &QPushButton::clicked, this, &MainWindow::OnAddIPWhiteListButtonClicked);
|
||||
connect(ui->allowedListAddHostNameToolButton, &QToolButton::clicked, this, &MainWindow::OnAddHostNameAllowedListButtonClicked);
|
||||
connect(ui->allowedListAddIPToolButton, &QPushButton::clicked, this, &MainWindow::OnAddIPAllowedListButtonClicked);
|
||||
|
||||
connect(ui->whiteListToWhiteListToolButton, &QPushButton::clicked, this, &MainWindow::OnToWhiteListButtonClicked);
|
||||
connect(ui->whiteListToRejectedListToolButton, &QToolButton::clicked, this, &MainWindow::OnToRejectedListButtonClicked);
|
||||
connect(ui->allowedListToAllowedListToolButton, &QPushButton::clicked, this, &MainWindow::OnToAllowedListButtonClicked);
|
||||
connect(ui->allowedListToRejectedListToolButton, &QToolButton::clicked, this, &MainWindow::OnToRejectedListButtonClicked);
|
||||
|
||||
//set the input validator for ip addresses on the add address line edit
|
||||
QRegExp validHostName("^((?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|\\b-){0,61}[0-9A-Za-z])?(?:\\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|\\b-){0,61}[0-9A-Za-z])?)*\\.?)$");
|
||||
QRegExp validIP("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))?$|^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$");
|
||||
|
||||
QRegExpValidator* hostNameValidator = new QRegExpValidator(validHostName, this);
|
||||
ui->whiteListAddHostNameLineEdit->setValidator(hostNameValidator);
|
||||
ui->allowedListAddHostNameLineEdit->setValidator(hostNameValidator);
|
||||
|
||||
QRegExpValidator* ipValidator = new QRegExpValidator(validIP, this);
|
||||
ui->whiteListAddIPLineEdit->setValidator(ipValidator);
|
||||
ui->allowedListAddIPLineEdit->setValidator(ipValidator);
|
||||
|
||||
//Job view
|
||||
m_jobSortFilterProxy->setSourceModel(m_jobsModel);
|
||||
@@ -555,65 +555,65 @@ void MainWindow::OnAddConnection(bool /*checked*/)
|
||||
m_guiApplicationManager->GetConnectionManager()->addUserConnection();
|
||||
}
|
||||
|
||||
void MainWindow::OnWhiteListedConnectionsListViewClicked()
|
||||
void MainWindow::OnAllowedListConnectionsListViewClicked()
|
||||
{
|
||||
ui->whiteListRejectedConnectionsListView->clearSelection();
|
||||
ui->allowedListRejectedConnectionsListView->clearSelection();
|
||||
}
|
||||
|
||||
void MainWindow::OnRejectedConnectionsListViewClicked()
|
||||
{
|
||||
ui->whiteListWhiteListedConnectionsListView->clearSelection();
|
||||
ui->allowListAllowedListConnectionsListView->clearSelection();
|
||||
}
|
||||
|
||||
void MainWindow::OnWhiteListCheckBoxToggled()
|
||||
void MainWindow::OnAllowedListCheckBoxToggled()
|
||||
{
|
||||
if (!ui->whiteListEnableCheckBox->isChecked())
|
||||
if (!ui->allowedListEnableCheckBox->isChecked())
|
||||
{
|
||||
//warn this is not safe
|
||||
if(QMessageBox::Ok == QMessageBox::warning(this, tr("!!!WARNING!!!"), tr("Turning off white listing poses a significant security risk as it would allow any device to connect to your asset processor and that device will have READ/WRITE access to the Asset Processors file system. Only do this if you sure you know what you are doing and accept the risks."),
|
||||
if(QMessageBox::Ok == QMessageBox::warning(this, tr("!!!WARNING!!!"), tr("Turning off allowed listing poses a significant security risk as it would allow any device to connect to your asset processor and that device will have READ/WRITE access to the Asset Processors file system. Only do this if you sure you know what you are doing and accept the risks."),
|
||||
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel))
|
||||
{
|
||||
ui->whiteListRejectedConnectionsListView->clearSelection();
|
||||
ui->whiteListWhiteListedConnectionsListView->clearSelection();
|
||||
ui->whiteListAddHostNameLineEdit->setEnabled(false);
|
||||
ui->whiteListAddHostNameToolButton->setEnabled(false);
|
||||
ui->whiteListAddIPLineEdit->setEnabled(false);
|
||||
ui->whiteListAddIPToolButton->setEnabled(false);
|
||||
ui->whiteListWhiteListedConnectionsListView->setEnabled(false);
|
||||
ui->whiteListRejectedConnectionsListView->setEnabled(false);
|
||||
ui->whiteListToWhiteListToolButton->setEnabled(false);
|
||||
ui->whiteListToRejectedListToolButton->setEnabled(false);
|
||||
ui->allowedListRejectedConnectionsListView->clearSelection();
|
||||
ui->allowListAllowedListConnectionsListView->clearSelection();
|
||||
ui->allowedListAddHostNameLineEdit->setEnabled(false);
|
||||
ui->allowedListAddHostNameToolButton->setEnabled(false);
|
||||
ui->allowedListAddIPLineEdit->setEnabled(false);
|
||||
ui->allowedListAddIPToolButton->setEnabled(false);
|
||||
ui->allowListAllowedListConnectionsListView->setEnabled(false);
|
||||
ui->allowedListRejectedConnectionsListView->setEnabled(false);
|
||||
ui->allowedListToAllowedListToolButton->setEnabled(false);
|
||||
ui->allowedListToRejectedListToolButton->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->whiteListEnableCheckBox->setChecked(true);
|
||||
ui->allowedListEnableCheckBox->setChecked(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->whiteListAddHostNameLineEdit->setEnabled(true);
|
||||
ui->whiteListAddHostNameToolButton->setEnabled(true);
|
||||
ui->whiteListAddIPLineEdit->setEnabled(true);
|
||||
ui->whiteListAddIPToolButton->setEnabled(true);
|
||||
ui->whiteListWhiteListedConnectionsListView->setEnabled(true);
|
||||
ui->whiteListRejectedConnectionsListView->setEnabled(true);
|
||||
ui->whiteListToWhiteListToolButton->setEnabled(true);
|
||||
ui->whiteListToRejectedListToolButton->setEnabled(true);
|
||||
ui->allowedListAddHostNameLineEdit->setEnabled(true);
|
||||
ui->allowedListAddHostNameToolButton->setEnabled(true);
|
||||
ui->allowedListAddIPLineEdit->setEnabled(true);
|
||||
ui->allowedListAddIPToolButton->setEnabled(true);
|
||||
ui->allowListAllowedListConnectionsListView->setEnabled(true);
|
||||
ui->allowedListRejectedConnectionsListView->setEnabled(true);
|
||||
ui->allowedListToAllowedListToolButton->setEnabled(true);
|
||||
ui->allowedListToRejectedListToolButton->setEnabled(true);
|
||||
}
|
||||
|
||||
m_guiApplicationManager->GetConnectionManager()->WhiteListingEnabled(ui->whiteListEnableCheckBox->isChecked());
|
||||
m_guiApplicationManager->GetConnectionManager()->AllowedListingEnabled(ui->allowedListEnableCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void MainWindow::OnAddHostNameWhiteListButtonClicked()
|
||||
void MainWindow::OnAddHostNameAllowedListButtonClicked()
|
||||
{
|
||||
QString text = ui->whiteListAddHostNameLineEdit->text();
|
||||
const QRegExpValidator *hostnameValidator = static_cast<const QRegExpValidator *>(ui->whiteListAddHostNameLineEdit->validator());
|
||||
QString text = ui->allowedListAddHostNameLineEdit->text();
|
||||
const QRegExpValidator *hostnameValidator = static_cast<const QRegExpValidator *>(ui->allowedListAddHostNameLineEdit->validator());
|
||||
int pos;
|
||||
QValidator::State state = hostnameValidator->validate(text, pos);
|
||||
if (state == QValidator::Acceptable)
|
||||
{
|
||||
auto lineEdit = ui->whiteListAddHostNameLineEdit;
|
||||
m_guiApplicationManager->GetConnectionManager()->AddWhiteListedAddress(text);
|
||||
auto lineEdit = ui->allowedListAddHostNameLineEdit;
|
||||
m_guiApplicationManager->GetConnectionManager()->AddAddressToAllowedList(text);
|
||||
lineEdit->clear();
|
||||
// Clear error state set in LineEdit.
|
||||
lineEdit->setProperty(AzQtComponents::HasError, false);
|
||||
@@ -625,16 +625,16 @@ void MainWindow::OnAddHostNameWhiteListButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::OnAddIPWhiteListButtonClicked()
|
||||
void MainWindow::OnAddIPAllowedListButtonClicked()
|
||||
{
|
||||
QString text = ui->whiteListAddIPLineEdit->text();
|
||||
const QRegExpValidator *ipValidator = static_cast<const QRegExpValidator *>(ui->whiteListAddIPLineEdit->validator());
|
||||
QString text = ui->allowedListAddIPLineEdit->text();
|
||||
const QRegExpValidator *ipValidator = static_cast<const QRegExpValidator *>(ui->allowedListAddIPLineEdit->validator());
|
||||
int pos;
|
||||
QValidator::State state = ipValidator->validate(text, pos);
|
||||
if (state== QValidator::Acceptable)
|
||||
{
|
||||
auto lineEdit = ui->whiteListAddIPLineEdit;
|
||||
m_guiApplicationManager->GetConnectionManager()->AddWhiteListedAddress(text);
|
||||
auto lineEdit = ui->allowedListAddIPLineEdit;
|
||||
m_guiApplicationManager->GetConnectionManager()->AddAddressToAllowedList(text);
|
||||
lineEdit->clear();
|
||||
// Clear error state set in LineEdit.
|
||||
lineEdit->setProperty(AzQtComponents::HasError, false);
|
||||
@@ -648,23 +648,23 @@ void MainWindow::OnAddIPWhiteListButtonClicked()
|
||||
|
||||
void MainWindow::OnToRejectedListButtonClicked()
|
||||
{
|
||||
QModelIndexList indices = ui->whiteListWhiteListedConnectionsListView->selectionModel()->selectedIndexes();
|
||||
QModelIndexList indices = ui->allowListAllowedListConnectionsListView->selectionModel()->selectedIndexes();
|
||||
if(!indices.isEmpty() && indices.first().isValid())
|
||||
{
|
||||
QString itemText = indices.first().data(Qt::DisplayRole).toString();
|
||||
m_guiApplicationManager->GetConnectionManager()->RemoveWhiteListedAddress(itemText);
|
||||
m_guiApplicationManager->GetConnectionManager()->RemoveAddressFromAllowedList(itemText);
|
||||
m_guiApplicationManager->GetConnectionManager()->AddRejectedAddress(itemText, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::OnToWhiteListButtonClicked()
|
||||
void MainWindow::OnToAllowedListButtonClicked()
|
||||
{
|
||||
QModelIndexList indices = ui->whiteListRejectedConnectionsListView->selectionModel()->selectedIndexes();
|
||||
QModelIndexList indices = ui->allowedListRejectedConnectionsListView->selectionModel()->selectedIndexes();
|
||||
if (!indices.isEmpty() && indices.first().isValid())
|
||||
{
|
||||
QString itemText = indices.front().data(Qt::DisplayRole).toString();
|
||||
m_guiApplicationManager->GetConnectionManager()->RemoveRejectedAddress(itemText);
|
||||
m_guiApplicationManager->GetConnectionManager()->AddWhiteListedAddress(itemText);
|
||||
m_guiApplicationManager->GetConnectionManager()->AddAddressToAllowedList(itemText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,9 +715,9 @@ void MainWindow::ShowWindow()
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::SyncWhiteListAndRejectedList(QStringList whiteList, QStringList rejectedList)
|
||||
void MainWindow::SyncAllowedListAndRejectedList(QStringList allowedList, QStringList rejectedList)
|
||||
{
|
||||
m_whitelistedAddresses.setStringList(whiteList);
|
||||
m_allowedListAddresses.setStringList(allowedList);
|
||||
m_rejectedAddresses.setStringList(rejectedList);
|
||||
}
|
||||
|
||||
@@ -725,7 +725,7 @@ void MainWindow::FirstTimeAddedToRejctedList(QString ipAddress)
|
||||
{
|
||||
QMessageBox* msgBox = new QMessageBox(this);
|
||||
msgBox->setText(tr("!!!Rejected Connection!!!"));
|
||||
msgBox->setInformativeText(ipAddress + tr(" tried to connect and was rejected because it was not on the white list. If you want this connection to be allowed go to connections tab and add it to white list."));
|
||||
msgBox->setInformativeText(ipAddress + tr(" tried to connect and was rejected because it was not on the allowed list. If you want this connection to be allowed go to connections tab and add it to allowed list."));
|
||||
msgBox->setStandardButtons(QMessageBox::Ok);
|
||||
msgBox->setDefaultButton(QMessageBox::Ok);
|
||||
msgBox->setWindowModality(Qt::NonModal);
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
public Q_SLOTS:
|
||||
void ShowWindow();
|
||||
|
||||
void SyncWhiteListAndRejectedList(QStringList whiteList, QStringList rejectedList);
|
||||
void SyncAllowedListAndRejectedList(QStringList allowedList, QStringList rejectedList);
|
||||
void FirstTimeAddedToRejctedList(QString ipAddress);
|
||||
void SaveLogPanelState();
|
||||
void OnAssetProcessorStatusChanged(const AssetProcessor::AssetProcessorStatusEntry entry);
|
||||
@@ -163,17 +163,17 @@ private:
|
||||
void OnConnectionSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
|
||||
QStringListModel m_rejectedAddresses;
|
||||
QStringListModel m_whitelistedAddresses;
|
||||
QStringListModel m_allowedListAddresses;
|
||||
|
||||
void OnWhiteListedConnectionsListViewClicked();
|
||||
void OnAllowedListConnectionsListViewClicked();
|
||||
void OnRejectedConnectionsListViewClicked();
|
||||
|
||||
void OnWhiteListCheckBoxToggled();
|
||||
void OnAllowedListCheckBoxToggled();
|
||||
|
||||
void OnAddHostNameWhiteListButtonClicked();
|
||||
void OnAddIPWhiteListButtonClicked();
|
||||
void OnAddHostNameAllowedListButtonClicked();
|
||||
void OnAddIPAllowedListButtonClicked();
|
||||
|
||||
void OnToWhiteListButtonClicked();
|
||||
void OnToAllowedListButtonClicked();
|
||||
void OnToRejectedListButtonClicked();
|
||||
|
||||
void UpdateJobLogView(QModelIndex selectedIndex);
|
||||
|
||||
@@ -917,11 +917,11 @@
|
||||
<widget class="AzQtComponents::TableView" name="connectionTreeView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="whiteListOuterFrame">
|
||||
<widget class="QFrame" name="allowedListOuterFrame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="whiteListVerticalLayout">
|
||||
<layout class="QVBoxLayout" name="allowedListVerticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -938,8 +938,8 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="whiteListTopBarWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="whiteListHorizontalBar">
|
||||
<widget class="QWidget" name="allowedListTopBarWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="allowedListHorizontalBar">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
@@ -956,12 +956,12 @@
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="whiteListEnableCheckBox">
|
||||
<widget class="QCheckBox" name="allowedListEnableCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>Enable or Disable white listing. White listing is a security feature which limits what can connect to the asset processor.</string>
|
||||
<string>Enable or Disable allowed listing. Allowed listing is a security feature which limits what can connect to the asset processor.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable white listing</string>
|
||||
<string>Enable allowed listing</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
@@ -969,7 +969,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="whiteListBarSpacer">
|
||||
<spacer name="allowedListBarSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -982,7 +982,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="whiteListSeparatorLine">
|
||||
<widget class="Line" name="allowedListSeparatorLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -992,8 +992,8 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="whiteListBottomBarWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="whiteListHorizontalBar2">
|
||||
<widget class="QWidget" name="allowedListBottomBarWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="allowedListHorizontalBar2">
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
@@ -1007,9 +1007,9 @@
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="whiteListAddHostNameLabel">
|
||||
<widget class="QLabel" name="allowedListAddHostNameLabel">
|
||||
<property name="toolTip">
|
||||
<string>White list a hostname. EX. MyComputer321</string>
|
||||
<string>Allowed list a hostname. EX. MyComputer321</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Host Name</string>
|
||||
@@ -1017,12 +1017,12 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="whiteListAddHostNameLineEdit"/>
|
||||
<widget class="QLineEdit" name="allowedListAddHostNameLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="whiteListAddHostNameToolButton">
|
||||
<widget class="QToolButton" name="allowedListAddHostNameToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Add the hostname to the white list.</string>
|
||||
<string>Add the hostname to the allowed list.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -1037,7 +1037,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="whiteListHorizontalBar2Spacer">
|
||||
<spacer name="allowedListHorizontalBar2Spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -1050,9 +1050,9 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="whiteListAddIPLabel">
|
||||
<widget class="QLabel" name="allowedListAddIPLabel">
|
||||
<property name="toolTip">
|
||||
<string>White list an ipv4 or ipv6 address with or without a CIDR range. EX. 192.168.0.20 or 192.168.0.0/24 or 2001:db8:85a3:8d3:1319:8a2e:370:7348 or 2001:db8:85a3:8d3:1319:8a2e:370:7348/32</string>
|
||||
<string>Allowed list an ipv4 or ipv6 address with or without a CIDR range. EX. 192.168.0.20 or 192.168.0.0/24 or 2001:db8:85a3:8d3:1319:8a2e:370:7348 or 2001:db8:85a3:8d3:1319:8a2e:370:7348/32</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add IP Address</string>
|
||||
@@ -1060,12 +1060,12 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="whiteListAddIPLineEdit"/>
|
||||
<widget class="QLineEdit" name="allowedListAddIPLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="whiteListAddIPToolButton">
|
||||
<widget class="QToolButton" name="allowedListAddIPToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Add the ip address to the white list.</string>
|
||||
<string>Add the ip address to the allowed list.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -1083,9 +1083,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="whiteListHorizontalBar3">
|
||||
<layout class="QHBoxLayout" name="allowedListHorizontalBar3">
|
||||
<item>
|
||||
<widget class="Line" name="whiteListLine">
|
||||
<widget class="Line" name="allowedListLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -1094,22 +1094,22 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="whiteListHorizontalLabelsLayout">
|
||||
<layout class="QHBoxLayout" name="allowedListHorizontalLabelsLayout">
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="whiteListWhiteListedConnnectionListLabel">
|
||||
<widget class="QLabel" name="allowedListAllowedListedConnnectionListLabel">
|
||||
<property name="toolTip">
|
||||
<string>White listed connection are addresses, ranges and name that will be allowed to connect to the asset processor.</string>
|
||||
<string>Allowed listed connection are addresses, ranges and name that will be allowed to connect to the asset processor.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>White Listed Connections</string>
|
||||
<string>Allowed Listed Connections</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="whiteListHorizontalLabelSpacer1">
|
||||
<spacer name="allowedListHorizontalLabelSpacer1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -1122,7 +1122,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="whiteListRejectedConnectionListLabel">
|
||||
<widget class="QLabel" name="allowedListRejectedConnectionListLabel">
|
||||
<property name="toolTip">
|
||||
<string>Rejected connections are addresses that failed to connect to the asset processor.</string>
|
||||
</property>
|
||||
@@ -1132,7 +1132,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="whiteListHorizontalLabelSpacer2">
|
||||
<spacer name="allowedListHorizontalLabelSpacer2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -1147,7 +1147,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="whiteListHorizontalViewsLayout">
|
||||
<layout class="QHBoxLayout" name="allowedListHorizontalViewsLayout">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
@@ -1164,16 +1164,16 @@
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListView" name="whiteListWhiteListedConnectionsListView">
|
||||
<widget class="QListView" name="allowListAllowedListConnectionsListView">
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="whiteListButtonVerticalLayout">
|
||||
<layout class="QVBoxLayout" name="allowedListButtonVerticalLayout">
|
||||
<item>
|
||||
<spacer name="whiteListVerticalSpacer1">
|
||||
<spacer name="allowedListVerticalSpacer1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@@ -1186,9 +1186,9 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="whiteListToWhiteListToolButton">
|
||||
<widget class="QToolButton" name="allowedListToAllowedListToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Move a entry from rejected to the white list.</string>
|
||||
<string>Move a entry from rejected to the allowed list.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -1203,7 +1203,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="whiteListToRejectedListToolButton">
|
||||
<widget class="QToolButton" name="allowedListToRejectedListToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Remove an entry from the whtie list.</string>
|
||||
</property>
|
||||
@@ -1220,7 +1220,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="whiteListVerticalSpacer2">
|
||||
<spacer name="allowedListVerticalSpacer2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@@ -1235,7 +1235,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="whiteListRejectedConnectionsListView">
|
||||
<widget class="QListView" name="allowedListRejectedConnectionsListView">
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "native/FileWatcher/FileWatcher.h"
|
||||
#include "native/unittests/MockConnectionHandler.h"
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
@@ -39,11 +40,14 @@ namespace AssetProcessor
|
||||
: AssetProcessorManager(config, parent)
|
||||
{}
|
||||
|
||||
friend class AssetProcessorManagerUnitTests;
|
||||
friend class AssetProcessorManagerUnitTests_ScanFolders;
|
||||
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
friend class AssetProcessorManagerUnitTests;
|
||||
friend class AssetProcessorManagerUnitTests_JobKeys;
|
||||
friend class AssetProcessorManagerUnitTests_JobDependencies_Fingerprint;
|
||||
friend class AssetProcessorManagerUnitTests_CheckOutputFolders;
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
public:
|
||||
using GetRelativeProductPathFromFullSourceOrProductPathRequest = AzFramework::AssetSystem::GetRelativeProductPathFromFullSourceOrProductPathRequest;
|
||||
@@ -54,11 +58,15 @@ namespace AssetProcessor
|
||||
|
||||
|
||||
|
||||
REGISTER_UNIT_TEST(AssetProcessorManagerUnitTests)
|
||||
REGISTER_UNIT_TEST(AssetProcessorManagerUnitTests_ScanFolders)
|
||||
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
REGISTER_UNIT_TEST(AssetProcessorManagerUnitTests)
|
||||
REGISTER_UNIT_TEST(AssetProcessorManagerUnitTests_JobKeys)
|
||||
REGISTER_UNIT_TEST(AssetProcessorManagerUnitTests_JobDependencies_Fingerprint)
|
||||
REGISTER_UNIT_TEST(AssetProcessorManagerUnitTests_CheckOutputFolders)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ Q_SIGNALS:
|
||||
virtual void StartTest() override;
|
||||
};
|
||||
|
||||
class AssetProcessorManagerUnitTests_CheckOutputFolders
|
||||
class AssetProcessorManagerUnitTests_CheckOutputFolders
|
||||
: public UnitTestRun
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "FileWatcherUnitTests.h"
|
||||
#include "native/FileWatcher/FileWatcher.h"
|
||||
#include "native/AssetManager/assetProcessorManager.h"
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace AssetProcessor;
|
||||
@@ -305,4 +306,6 @@ void FileWatcherUnitTestRunner::StartTest()
|
||||
Q_EMIT UnitTestPassed();
|
||||
}
|
||||
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
REGISTER_UNIT_TEST(FileWatcherUnitTestRunner)
|
||||
#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
@@ -10,6 +10,7 @@
|
||||
*
|
||||
*/
|
||||
#include "RCcontrollerUnitTests.h"
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#if defined(AZ_PLATFORM_LINUX)
|
||||
@@ -770,7 +771,7 @@ void RCcontrollerUnitTests::RunRCControllerTests()
|
||||
Q_EMIT UnitTestPassed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
REGISTER_UNIT_TEST(RCcontrollerUnitTests)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "native/utilities/ByteArrayStream.h"
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Jobs/Job.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <QThread>
|
||||
|
||||
|
||||
@@ -65,7 +66,9 @@ namespace AssetProcessor
|
||||
};
|
||||
}
|
||||
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
REGISTER_UNIT_TEST(UtilitiesUnitTests)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
void UtilitiesUnitTests::StartTest()
|
||||
{
|
||||
|
||||
@@ -674,7 +674,7 @@ void GUIApplicationManager::FileChanged(QString path)
|
||||
|
||||
if (m_connectionManager)
|
||||
{
|
||||
m_connectionManager->UpdateWhiteListFromBootStrap();
|
||||
m_connectionManager->UpdateAllowedListFromBootStrap();
|
||||
}
|
||||
|
||||
// Re-merge the Bootstrap.cfg into the SettingsRegistry
|
||||
|
||||
@@ -600,7 +600,7 @@ to ensure that the address is correct. Asset Processor won't be running in serve
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ReadWhitelistFromSettingsRegistry(QString initialFolder /*= QString()*/)
|
||||
QString ReadAllowedlistFromSettingsRegistry(QString initialFolder /*= QString()*/)
|
||||
{
|
||||
if (initialFolder.isEmpty())
|
||||
{
|
||||
@@ -613,14 +613,14 @@ to ensure that the address is correct. Asset Processor won't be running in serve
|
||||
initialFolder = assetRoot.absolutePath();
|
||||
}
|
||||
|
||||
constexpr size_t BufferSize = AZ_ARRAY_SIZE(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + AZStd::char_traits<char>::length("/white_list");
|
||||
AZStd::fixed_string<BufferSize> whiteListKey{ AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey };
|
||||
whiteListKey += "/white_list";
|
||||
constexpr size_t BufferSize = AZ_ARRAY_SIZE(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + AZStd::char_traits<char>::length("/allowed_list");
|
||||
AZStd::fixed_string<BufferSize> allowedListKey{ AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey };
|
||||
allowedListKey += "/allowed_list";
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString whiteListIp;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry && settingsRegistry->Get(whiteListIp, whiteListKey))
|
||||
AZ::SettingsRegistryInterface::FixedValueString allowedListIp;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry && settingsRegistry->Get(allowedListIp, allowedListKey))
|
||||
{
|
||||
return QString::fromUtf8(whiteListIp.c_str(), aznumeric_cast<int>(whiteListIp.size()));
|
||||
return QString::fromUtf8(allowedListIp.c_str(), aznumeric_cast<int>(allowedListIp.size()));
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -651,7 +651,7 @@ to ensure that the address is correct. Asset Processor won't be running in serve
|
||||
return {};
|
||||
}
|
||||
|
||||
bool WriteWhitelistToBootstrap(QStringList newWhiteList)
|
||||
bool WriteAllowedlistToBootstrap(QStringList newAllowedList)
|
||||
{
|
||||
QDir assetRoot;
|
||||
ComputeAssetRoot(assetRoot);
|
||||
@@ -669,21 +669,21 @@ to ensure that the address is correct. Asset Processor won't be running in serve
|
||||
return false;
|
||||
}
|
||||
|
||||
// regexp that matches either the beginning of the file, some whitespace, and white_list, or,
|
||||
// matches a newline, then whitespace, then white_list it will not match comments.
|
||||
QRegExp whiteListPattern("(^|\\n)\\s*white_list\\s*=\\s*(.+)", Qt::CaseInsensitive, QRegExp::RegExp);
|
||||
// regexp that matches either the beginning of the file, some whitespace, and allowed_list, or,
|
||||
// matches a newline, then whitespace, then allowed_list it will not match comments.
|
||||
QRegExp allowedListPattern("(^|\\n)\\s*allowed_list\\s*=\\s*(.+)", Qt::CaseInsensitive, QRegExp::RegExp);
|
||||
|
||||
//read the file line by line and try to find the white_list line
|
||||
QString readWhiteList;
|
||||
QString whiteListline;
|
||||
//read the file line by line and try to find the allowed_list line
|
||||
QString readAllowedList;
|
||||
QString allowedListline;
|
||||
while (!bootstrapFile.atEnd())
|
||||
{
|
||||
QString contents(bootstrapFile.readLine());
|
||||
int matchIdx = whiteListPattern.indexIn(contents);
|
||||
int matchIdx = allowedListPattern.indexIn(contents);
|
||||
if (matchIdx != -1)
|
||||
{
|
||||
whiteListline = contents;
|
||||
readWhiteList = whiteListPattern.cap(2);
|
||||
allowedListline = contents;
|
||||
readAllowedList = allowedListPattern.cap(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -694,15 +694,15 @@ to ensure that the address is correct. Asset Processor won't be running in serve
|
||||
fileContents = bootstrapFile.readAll();
|
||||
bootstrapFile.close();
|
||||
|
||||
//format the new white list
|
||||
QString formattedNewWhiteList = newWhiteList.join(", ");
|
||||
//format the new allowed list
|
||||
QString formattedNewAllowedList = newAllowedList.join(", ");
|
||||
|
||||
//if we didn't find a white_list entry then append one
|
||||
if (whiteListline.isEmpty())
|
||||
//if we didn't find a allowed_list entry then append one
|
||||
if (allowedListline.isEmpty())
|
||||
{
|
||||
fileContents.append("\nwhite_list = " + formattedNewWhiteList + "\n");
|
||||
fileContents.append("\nallowed_list = " + formattedNewAllowedList + "\n");
|
||||
}
|
||||
else if (QString::compare(formattedNewWhiteList, readWhiteList, Qt::CaseInsensitive) == 0)
|
||||
else if (QString::compare(formattedNewAllowedList, readAllowedList, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
// no need to update, they match
|
||||
return true;
|
||||
@@ -710,7 +710,7 @@ to ensure that the address is correct. Asset Processor won't be running in serve
|
||||
else
|
||||
{
|
||||
//Replace the found line with a new one
|
||||
fileContents.replace(whiteListline, "white_list = " + formattedNewWhiteList + "\n");
|
||||
fileContents.replace(allowedListline, "allowed_list = " + formattedNewAllowedList + "\n");
|
||||
}
|
||||
|
||||
// Make the bootstrap file writable
|
||||
|
||||
@@ -104,14 +104,14 @@ namespace AssetUtilities
|
||||
//! force=true is supplied
|
||||
QString ComputeGameName(QString gameNameOverride = QString(), bool force = false);
|
||||
|
||||
//! Reads the white list directly from the bootstrap file
|
||||
QString ReadWhitelistFromSettingsRegistry(QString initialFolder = QString());
|
||||
//! Reads the allowed list directly from the bootstrap file
|
||||
QString ReadAllowedlistFromSettingsRegistry(QString initialFolder = QString());
|
||||
|
||||
//! Reads the white list directly from the bootstrap file
|
||||
//! Reads the allowed list directly from the bootstrap file
|
||||
QString ReadRemoteIpFromSettingsRegistry(QString initialFolder = QString());
|
||||
|
||||
//! Writes the white list directly to the bootstrap file
|
||||
bool WriteWhitelistToBootstrap(QStringList whiteList);
|
||||
//! Writes the allowed list directly to the bootstrap file
|
||||
bool WriteAllowedlistToBootstrap(QStringList allowedList);
|
||||
|
||||
//! Writes the remote ip directly to the bootstrap file
|
||||
bool WriteRemoteIpToBootstrap(QString remoteIp);
|
||||
|
||||
-7
@@ -12,10 +12,6 @@ tags=tools,renderer
|
||||
[Platform server]
|
||||
tags=server
|
||||
|
||||
; we define an xenia platform in order to make sure that it does NOT show up anywhere
|
||||
[Platform xenia]
|
||||
tags=console,renderer
|
||||
|
||||
; for the purposes of this test, we enable only server and es3, but we make sure the CURRENT_PLATFORM is auto enabled.
|
||||
|
||||
[Platforms]
|
||||
@@ -23,7 +19,6 @@ tags=console,renderer
|
||||
es3=enabled
|
||||
;ios=enabled
|
||||
;osx_gl=enabled
|
||||
;xenia=enabled
|
||||
;provo=enabled
|
||||
server=enabled
|
||||
|
||||
@@ -76,8 +71,6 @@ params=defaultparams
|
||||
server=skip
|
||||
; es3 should have this overridden
|
||||
es3=mobile
|
||||
; xenia is allowed here but should be skipped
|
||||
xenia=copy
|
||||
; host should have defaultparams
|
||||
; make sure priority is used.
|
||||
priority=5
|
||||
|
||||
@@ -29,5 +29,5 @@ add_subdirectory(DeltaCataloger)
|
||||
add_subdirectory(SerializeContextTools)
|
||||
add_subdirectory(AssetBundler)
|
||||
add_subdirectory(GridHub)
|
||||
add_subdirectory(Woodpecker)
|
||||
add_subdirectory(Standalone)
|
||||
add_subdirectory(TestImpactFramework)
|
||||
@@ -250,8 +250,6 @@ bool CCrySimpleJobCompile::Compile(const TiXmlElement* pElement, std::vector<uin
|
||||
"METAL", SEnviropment::m_METAL_HLSLcc
|
||||
},{
|
||||
"ORBIS", SEnviropment::m_Orbis_DXC
|
||||
},{
|
||||
"DURANGO", SEnviropment::m_Durango_FXC
|
||||
},{
|
||||
"JASPER", SEnviropment::m_Jasper_FXC
|
||||
}
|
||||
@@ -457,10 +455,6 @@ bool CCrySimpleJobCompile::Compile(const TiXmlElement* pElement, std::vector<uin
|
||||
AZStd::string hardwareTarget;
|
||||
|
||||
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#if defined(TOOLS_SUPPORT_XENIA)
|
||||
#define AZ_RESTRICTED_SECTION CRYSIMPLEJOBCOMPILE_CPP_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySimpleJobCompile_cpp, xenia)
|
||||
#endif
|
||||
#if defined(TOOLS_SUPPORT_JASPER)
|
||||
#define AZ_RESTRICTED_SECTION CRYSIMPLEJOBCOMPILE_CPP_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySimpleJobCompile_cpp, jasper)
|
||||
|
||||
@@ -113,7 +113,6 @@ SEnviropment& SEnviropment::Instance()
|
||||
// Shader Compilers ID
|
||||
// NOTE: Values must be in sync with CShaderSrv::GetShaderCompilerName() function in the engine side.
|
||||
const char* SEnviropment::m_Orbis_DXC = "Orbis_DXC";
|
||||
const char* SEnviropment::m_Durango_FXC = "Durango_FXC";
|
||||
const char* SEnviropment::m_Jasper_FXC = "Jasper_FXC";
|
||||
const char* SEnviropment::m_D3D11_FXC = "D3D11_FXC";
|
||||
const char* SEnviropment::m_GLSL_HLSLcc = "GLSL_HLSLcc";
|
||||
@@ -126,7 +125,6 @@ void SEnviropment::InitializePlatformAttributes()
|
||||
// Initialize valid Plaforms
|
||||
// NOTE: Values must be in sync with CShaderSrv::GetPlatformName() function in the engine side.
|
||||
m_Platforms.insert("Orbis");
|
||||
m_Platforms.insert("Durango");
|
||||
m_Platforms.insert("Nx");
|
||||
m_Platforms.insert("PC");
|
||||
m_Platforms.insert("Mac");
|
||||
@@ -138,7 +136,6 @@ void SEnviropment::InitializePlatformAttributes()
|
||||
// Initialize valid Shader Languages
|
||||
// NOTE: Values must be in sync with GetShaderLanguageName() function in the engine side.
|
||||
m_ShaderLanguages.insert("Orbis");
|
||||
m_ShaderLanguages.insert("Durango");
|
||||
m_ShaderLanguages.insert("D3D11");
|
||||
m_ShaderLanguages.insert("METAL");
|
||||
m_ShaderLanguages.insert("GL4");
|
||||
@@ -153,10 +150,6 @@ void SEnviropment::InitializePlatformAttributes()
|
||||
// Initialize valid Shader Compilers ID and Executables.
|
||||
// Intentionally put a space after the executable name so that attackers can't try to change the executable name that we are going to run.
|
||||
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#if defined(TOOLS_SUPPORT_XENIA)
|
||||
#define AZ_RESTRICTED_SECTION CRYSIMPLESERVER_CPP_SECTION_2
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySimpleServer_cpp, xenia)
|
||||
#endif
|
||||
#if defined(TOOLS_SUPPORT_JASPER)
|
||||
#define AZ_RESTRICTED_SECTION CRYSIMPLESERVER_CPP_SECTION_2
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySimpleServer_cpp, jasper)
|
||||
@@ -394,10 +387,6 @@ void CompileJob::Process()
|
||||
}
|
||||
|
||||
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#if defined(TOOLS_SUPPORT_XENIA)
|
||||
#define AZ_RESTRICTED_SECTION CRYSIMPLESERVER_CPP_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySimpleServer_cpp, xenia)
|
||||
#endif
|
||||
#if defined(TOOLS_SUPPORT_JASPER)
|
||||
#define AZ_RESTRICTED_SECTION CRYSIMPLESERVER_CPP_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySimpleServer_cpp, jasper)
|
||||
|
||||
@@ -69,7 +69,6 @@ public:
|
||||
|
||||
// Shader Compilers ID
|
||||
static const char* m_Orbis_DXC;
|
||||
static const char* m_Durango_FXC;
|
||||
static const char* m_Jasper_FXC;
|
||||
static const char* m_D3D11_FXC;
|
||||
static const char* m_GLSL_HLSLcc;
|
||||
|
||||
@@ -142,9 +142,6 @@ public:
|
||||
SEnviropment::Instance().m_RunAsRoot = (runAsRoot == 1);
|
||||
}
|
||||
|
||||
#if defined(TOOLS_SUPPORT_XENIA)
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySCompileServer_cpp, xenia)
|
||||
#endif
|
||||
#if defined(TOOLS_SUPPORT_JASPER)
|
||||
#include AZ_RESTRICTED_FILE_EXPLICIT(CrySCompileServer_cpp, jasper)
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,4 @@ ly_add_target(
|
||||
3rdParty::Qt::Widgets
|
||||
AZ::AzCore
|
||||
AZ::GridMate
|
||||
COMPILE_DEFINITIONS
|
||||
PRIVATE
|
||||
GRIDMATE_FOR_TOOLS
|
||||
)
|
||||
|
||||
@@ -621,8 +621,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
bool failSilently = false;
|
||||
|
||||
// We are laucnhing this from Woodpecker all the time.
|
||||
// When launching from Woodpecker, we don't want to show
|
||||
// We are launching this from application all the time.
|
||||
// When launching from the application, we don't want to show
|
||||
// any of our error messages, which might be useful at other times.
|
||||
// So, it passes along this fail_silently flag which lets us suppress
|
||||
// our messages without disrupting any other flow.
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# this script modifies a single app, passed in, on the command line, to use @rpath dirs for Qt libs
|
||||
# you are expected to pass in the executable name on the command line as the first argument
|
||||
# you are expected to set QTDIR.
|
||||
# it works by searching all frameworks in QtDir/lib and seeing if your app has a reference to it
|
||||
# if it does, it replaces that reference with a relative-path reference instead.
|
||||
|
||||
NEWLIBPATH="@rpath"
|
||||
ORIGINALLIBPATH=${QTDIR}/lib
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Please input the application file to modify"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${QTDIR}" ]; then
|
||||
echo "QTDIR IS NOT SET. PLease set QTDIR to the root of your Qt platform install, usually Qt/VersionNumber/clang_64"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$QTDIR" ]; then
|
||||
echo "QTDIR does not appear to point at a directory ,currently its set to ${QTDIR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo changebinary_rpaths.sh: Remapping paths in $1 to be rpath instead.
|
||||
|
||||
# for each original framework, amend all frameworks in the target folder:
|
||||
ORIGINAL_LIBS=${ORIGINALLIBPATH}/*.framework
|
||||
for ORIGINAL_LIB in ${ORIGINAL_LIBS} ; do
|
||||
BIN_BASE_NAME=$(basename "${ORIGINALLIBPATH}/${ORIGINAL_LIB}" .framework)
|
||||
ORIGINAL_BINARY_NAME=`otool -DX "${ORIGINALLIBPATH}/${BIN_BASE_NAME}.framework/${BIN_BASE_NAME}"`
|
||||
NEWTARGETID=${NEWLIBPATH}/${BIN_BASE_NAME}.framework/${BIN_BASE_NAME}
|
||||
|
||||
# uncomment to debug:
|
||||
echo Remapping ${ORIGINAL_BINARY_NAME} ==\> ${NEWTARGETID}
|
||||
# BIN_BASE_NAME now contains the name of the lib, like 'QtCore'
|
||||
# ORIGINAL_BINARY_NAME now contains the full path to the binary inside the framework
|
||||
# for example /Users/lawsonn/Qt/5.3/clang_64/lib/Qt5Core.framework/Versions/5/Qt5Core
|
||||
# NEWTARGETID is the one to change it to
|
||||
# for example, @rpath/QtCore.framework/QtCore
|
||||
|
||||
# replace it in the executable:
|
||||
install_name_tool -change "${ORIGINAL_BINARY_NAME}" "${NEWTARGETID}" "$1"
|
||||
done
|
||||
|
||||
# now, we need to rename the dylib's own ID to be @rpath<currentId>
|
||||
MY_NAME=`otool -DX "$1"`
|
||||
install_name_tool -id "${NEWLIBPATH}/${MY_NAME}" "$1"
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# Shell script to print out the various qt libraries that a Qt framework
|
||||
# depends on. The libs that do not have @rpath in their name will need to
|
||||
# either be copied into the app bundle and be updated to use rpath or be
|
||||
# updated so that when an executable linking against them will pull in the
|
||||
# rpath information and use that instead of the hardcoded lib id. The
|
||||
# updateLibs.sh script will perform the necessary operations to update the lib
|
||||
# to have an rpath ID and change the name of the dynamic Qt libs it depends on
|
||||
# to use the rpath reference instead of a absolute path
|
||||
|
||||
DEBUG_PRINT=1
|
||||
VERBOSE_DEBUG_PRINT=0
|
||||
|
||||
runInstallNameToolOn ()
|
||||
{
|
||||
pushd $1/Versions/Current > /dev/null
|
||||
libs=$(find . -type f -depth 1)
|
||||
for lib in $libs; do
|
||||
lib=${lib:2} # Strip off the ./ from the front of the name
|
||||
printf "\t$lib has these dependenices\n"
|
||||
dependencies=$(otool -LX $lib | cut -d ' ' -f 1 | grep -i qt)
|
||||
for qtLib in $dependencies; do
|
||||
qtLibName=${qtLib##*/}
|
||||
[ $qtLibName != $lib ] && printf "\t\t$qtLib\n"
|
||||
done
|
||||
done
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
if [[ $1 != "" ]]; then
|
||||
doPopDir=1
|
||||
pushd $1 > /dev/null
|
||||
fi
|
||||
|
||||
frameworks=$(find . -name "*.framework" -type d)
|
||||
for framework in $frameworks; do
|
||||
printf "$framework\n"
|
||||
runInstallNameToolOn ${framework:2}
|
||||
done
|
||||
|
||||
if [[ $doPopDir -eq 1 ]]; then
|
||||
popd > /dev/null
|
||||
fi
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# Shell script that updates the Qt libraries and executables that are in the
|
||||
# 3rd party directory so that they contain the correct rpath references so that
|
||||
# the Qt command line executables can run properly as well as executables
|
||||
# linking to the libraries will automatically get the rpath versions and no
|
||||
# post build processing on them will need to be done.
|
||||
|
||||
DEBUG_PRINT=1
|
||||
|
||||
qtBaseDir="$1"
|
||||
|
||||
# Try and guess where 3rd party is located by seeing if we can sneak our way
|
||||
# through the backdoor symbolic link in the sandbox
|
||||
relativePathToSandboxSDKFromScriptLocaiton="../../Sandbox/SDKs/Qt"
|
||||
if [[ $qtBaseDir == "" && -e $relativePathToSandboxSDKFromScriptLocaiton ]]; then
|
||||
pushd $relativePathToSandboxSDKFromScriptLocaiton > /dev/null
|
||||
qtBaseDir=`pwd`
|
||||
popd > /dev/null
|
||||
fi
|
||||
|
||||
shopt -s nocasematch
|
||||
|
||||
if [[ $qtBaseDir != "" ]]; then
|
||||
read -e -p "Use the following Qt directory: $qtBaseDir? [y/n] " useQtBaseDir
|
||||
fi
|
||||
|
||||
if [[ $qtBaseDir == "" || $useQtBaseDir == "n" ]]; then
|
||||
read -e -p "Please enter the location of the Qt directory in the 3rd party directory: " qtBaseDir
|
||||
fi
|
||||
|
||||
[ $DEBUG_PRINT -eq 1 ] && echo "qtBaseDir = *$qtBaseDir*"
|
||||
|
||||
#(exec ./printQtLibDependencies.sh $qtBaseDir)
|
||||
echo "Updating Qt libraries..."
|
||||
(exec ./updateQtLibs.sh $qtBaseDir/lib)
|
||||
echo "Updating Qt executables..."
|
||||
(exec ./updateQtExecs.sh $qtBaseDir/bin)
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# Shell script to update all of the executables to use rpath to reference the
|
||||
# Qt libs that are stored in 3rd party. Not doing this prevents the executables
|
||||
# from running on the mac since they will have embedded in them the full
|
||||
# pathname of the QtLib where it was installed on the person's maching that
|
||||
# copied the libs into 3rd party. (use otool -LX [exe name] to find out the
|
||||
# names)
|
||||
|
||||
DEBUG_PRINT=0
|
||||
VERBOSE_DEBUG_PRINT=0
|
||||
|
||||
runInstallNameToolOn ()
|
||||
{
|
||||
# figure out how far back we need to go to get to the Qt/lib dir where the
|
||||
# frameworks are and where rpath will be pointing to
|
||||
IFS=/
|
||||
backDirString=""
|
||||
for dir in $1; do
|
||||
[ $VERBOSE_DEBUG_PRINT -eq 1 ] && printf "testing $dir length: ${#dir}\n"
|
||||
backDirString=$backDirString"/.."
|
||||
done
|
||||
unset IFS
|
||||
|
||||
[ $VERBOSE_DEBUG_PRINT -eq 1 ] && printf "backDirString = $backDirString\n"
|
||||
pushd $1 > /dev/null
|
||||
executables=$(find . -type f -d 1 -perm +1)
|
||||
for file in $executables; do
|
||||
file=${file:2} # strip ./ from the front of the file name
|
||||
# Get all the Qt libraries that don't have an rpath in them
|
||||
dependencies=$(otool -LX $file | cut -d ' ' -f 1 | grep -i qt | grep -v @rpath)
|
||||
if [[ ${#dependencies} -gt 0 ]]; then
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tUpdating $file to use rpath and relative qt libs\n"
|
||||
|
||||
cmd="chmod 777 $file"
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tRunning $cmd\n"
|
||||
`$cmd`
|
||||
|
||||
cmd="install_name_tool -add_rpath @executable_path$backDirString/lib $file"
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tRunning $cmd\n"
|
||||
`$cmd`
|
||||
fi
|
||||
for qtLib in $dependencies; do
|
||||
qtLibName=${qtLib##*/}
|
||||
cmd="install_name_tool -change $qtLib @rpath/$qtLibName.framework/$qtLibName $file"
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tRunning $cmd\n"
|
||||
`$cmd`
|
||||
done
|
||||
done
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
if [[ $1 != "" ]]; then
|
||||
doPopDir=1
|
||||
pushd $1 > /dev/null
|
||||
fi
|
||||
|
||||
directoriesToLookIn=$(find . -type d)
|
||||
for dir in $directoriesToLookIn; do
|
||||
printf "Looking in $dir for Qt executables...\n"
|
||||
runInstallNameToolOn ${dir}
|
||||
done
|
||||
|
||||
if [[ $doPopDir -eq 1 ]]; then
|
||||
popd > /dev/null
|
||||
fi
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# Shell script to update all of the libraries to use rpath to reference the
|
||||
# Qt libs. This only needs to be run once for the libs in 3rd party so that
|
||||
# they use the rpath references to the other libraries instead of the hardcoded
|
||||
# paths when Qt installs them on a machine. This will allow different users to
|
||||
# use the libraries directly from perforce instead of requiring a local version
|
||||
# to be installed
|
||||
|
||||
DEBUG_PRINT=0
|
||||
VERBOSE_DEBUG_PRINT=0
|
||||
|
||||
runInstallNameToolOn ()
|
||||
{
|
||||
pushd $1/Versions/Current > /dev/null
|
||||
libs=$(find . -type f -depth 1)
|
||||
for lib in $libs; do
|
||||
lib=${lib:2} # Strip off the ./ from the front of the name
|
||||
|
||||
cmd="chmod 666 $lib"
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tRunning $cmd\n"
|
||||
`$cmd`
|
||||
|
||||
# Don't update the id if it already uses rpath (grep -v returns things
|
||||
# that don't match the specified pattern
|
||||
if [[ `otool -DX $lib | grep -v @rpath` != "" ]]; then
|
||||
cmd="install_name_tool -id @rpath/$1/$lib $lib"
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tRunning $cmd\n"
|
||||
`$cmd`
|
||||
fi
|
||||
|
||||
# only update qt dependencies that don't have an rpath in them
|
||||
dependencies=$(otool -LX $lib | cut -d ' ' -f 1 | grep -i qt | grep -v @)
|
||||
for qtLib in $dependencies; do
|
||||
[ $VERBOSE_DEBUG_PRINT -eq 1 ] && printf "\tTrying to extract lib name from $qtLib\n"
|
||||
qtLibName=${qtLib##*/}
|
||||
[ $VERBOSE_DEBUG_PRINT -eq 1 ] && printf "\tComparing $qtLibName with $lib\n"
|
||||
if [[ $qtLibName != $lib ]]; then
|
||||
cmd="install_name_tool -change $qtLib @rpath/$qtLibName.framework/$qtLibName $lib"
|
||||
[ $DEBUG_PRINT -eq 1 ] && printf "\tRunning $cmd\n"
|
||||
`$cmd`
|
||||
fi
|
||||
done
|
||||
done
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
if [[ $1 != "" ]]; then
|
||||
doPopDir=1
|
||||
pushd $1 > /dev/null
|
||||
fi
|
||||
|
||||
frameworksToModify=$(find . -name "*.framework" -type d)
|
||||
for framework in $frameworksToModify; do
|
||||
printf "Looking at $framework...\n"
|
||||
runInstallNameToolOn ${framework:2}
|
||||
done
|
||||
|
||||
if [[ $doPopDir -eq 1 ]]; then
|
||||
popd > /dev/null
|
||||
fi
|
||||
@@ -18,11 +18,6 @@ name=provo
|
||||
bigendian=0
|
||||
pointersize=8
|
||||
|
||||
[_platform]
|
||||
name=xenia
|
||||
bigendian=0
|
||||
pointersize=8
|
||||
|
||||
[_platform]
|
||||
name=salem
|
||||
bigendian=0
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Cry_Geo.h> // Needed for CGFContent.h
|
||||
#include <CGFContent.h>
|
||||
#include <PropertyHelpers.h>
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/Rules/ITouchBendingRule.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBoneData.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphChildIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/SceneGraphSelector.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <RC/ResourceCompilerScene/Common/ExportContextGlobal.h>
|
||||
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
|
||||
#include <RC/ResourceCompilerScene/Common/TouchBendingExporter.h>
|
||||
|
||||
#include <SceneAPI/SceneCore/DataTypes/Groups/IMeshGroup.h> //Needed by CgfExportContexts.h
|
||||
#include <RC/ResourceCompilerScene/Cgf/CgfExportContexts.h>
|
||||
#include <RC/ResourceCompilerScene/Cgf/CgfUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RC
|
||||
{
|
||||
namespace SceneEvents = AZ::SceneAPI::Events;
|
||||
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
|
||||
namespace SceneContainers = AZ::SceneAPI::Containers;
|
||||
namespace SceneUtil = AZ::SceneAPI::Utilities;
|
||||
namespace SceneViews = AZ::SceneAPI::Containers::Views;
|
||||
namespace AzStringFunc = AzFramework::StringFunc;
|
||||
|
||||
TouchBendingExporter::TouchBendingExporter()
|
||||
: AZ::SceneAPI::SceneCore::RCExportingComponent()
|
||||
{
|
||||
BindToCall(&TouchBendingExporter::ConfigureContainer);
|
||||
BindToCall(&TouchBendingExporter::ProcessSkinnedMesh);
|
||||
}
|
||||
|
||||
void TouchBendingExporter::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<TouchBendingExporter, AZ::SceneAPI::SceneCore::RCExportingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
SceneEvents::ProcessingResult TouchBendingExporter::ConfigureContainer(ContainerExportContext& context)
|
||||
{
|
||||
switch (context.m_phase)
|
||||
{
|
||||
case Phase::Filling:
|
||||
{
|
||||
AZStd::shared_ptr<const SceneDataTypes::ITouchBendingRule> touchBendingRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ITouchBendingRule>();
|
||||
if (!touchBendingRule)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
|
||||
AZStd::vector<AZStd::string> noCollideTargetNodes = SceneUtil::SceneGraphSelector::GenerateTargetNodes(graph, touchBendingRule->GetSceneNodeSelectionList(), SceneUtil::SceneGraphSelector::IsMesh);
|
||||
ProcessMeshType(context, context.m_container, noCollideTargetNodes, PHYS_GEOM_TYPE_NO_COLLIDE);
|
||||
}
|
||||
return SceneEvents::ProcessingResult::Success;
|
||||
case Phase::Finalizing:
|
||||
{
|
||||
AZStd::shared_ptr<const SceneDataTypes::ITouchBendingRule> touchBendingRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ITouchBendingRule>();
|
||||
if (!touchBendingRule)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
//Let's make sure we have valid CSkinningInfo, otherwise,
|
||||
//there's no point in adding the Bone Tree helper nodes.
|
||||
CSkinningInfo* skinningInfo = context.m_container.GetSkinningInfo();
|
||||
if (skinningInfo->m_arrBonesDesc.size() < 1)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
AZStd::string rootBoneName = touchBendingRule->GetRootBoneName();
|
||||
AddHelperBoneNodes(context, context.m_container, rootBoneName,
|
||||
touchBendingRule->ShouldOverrideDamping(), touchBendingRule->GetOverrideDamping(),
|
||||
touchBendingRule->ShouldOverrideStiffness(), touchBendingRule->GetOverrideStiffness(),
|
||||
touchBendingRule->ShouldOverrideThickness(), touchBendingRule->GetOverrideThickness());
|
||||
}
|
||||
return SceneEvents::ProcessingResult::Success;
|
||||
default:
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
}
|
||||
|
||||
SceneEvents::ProcessingResult TouchBendingExporter::ProcessSkinnedMesh(AZ::RC::MeshNodeExportContext& context)
|
||||
{
|
||||
if (context.m_physicalizeType != PHYS_GEOM_TYPE_NONE)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<const SceneDataTypes::ITouchBendingRule> touchBendingRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ITouchBendingRule>();
|
||||
if (!touchBendingRule)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::string rootBoneName = touchBendingRule->GetRootBoneName();
|
||||
SceneEvents::ProcessingResult result = SceneEvents::ProcessingResult::Ignored;
|
||||
switch (context.m_phase)
|
||||
{
|
||||
case Phase::Filling:
|
||||
result = SceneEvents::Process<TouchBendableMeshNodeExportContext>(
|
||||
context, rootBoneName, Phase::Filling);
|
||||
break;
|
||||
case Phase::Construction:
|
||||
{
|
||||
//Add the Bones to CSkinningInfo only if they have not been added already.
|
||||
CSkinningInfo* skinningInfo = context.m_container.GetSkinningInfo();
|
||||
if (skinningInfo->m_arrBonesDesc.size() == 0)
|
||||
{
|
||||
result = SceneEvents::Process<AddBonesToSkinningInfoContext>(
|
||||
*skinningInfo, context.m_scene, rootBoneName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
The format is based on Cry's PropertyHelpers::SetPropertyValue.
|
||||
This version doesn't do any nullptr checking or white space trimming,
|
||||
because those errors are guaranteed not to happen.
|
||||
*/
|
||||
static void AddPropertyValue(AZStd::string& inoutPropertiesString, const char* propertyName, float value, const char * propertySeparator)
|
||||
{
|
||||
char valueStr[16];
|
||||
snprintf(valueStr, sizeof(valueStr), "%f", value);
|
||||
|
||||
AzStringFunc::Append(inoutPropertiesString, propertyName);
|
||||
AzStringFunc::Append(inoutPropertiesString, '=');
|
||||
AzStringFunc::Append(inoutPropertiesString, valueStr);
|
||||
if (propertySeparator)
|
||||
{
|
||||
AzStringFunc::Append(inoutPropertiesString, propertySeparator);
|
||||
}
|
||||
}
|
||||
|
||||
bool TouchBendingExporter::AddHelperBoneNodes(AZ::RC::ContainerExportContext& context, CContentCGF& content, AZStd::string& rootBoneName,
|
||||
[[maybe_unused]] bool shouldOverrideDamping, float damping,
|
||||
[[maybe_unused]] bool shouldOverrideStiffness, float stiffness,
|
||||
[[maybe_unused]] bool shouldOverrideThickness, float thickness)
|
||||
{
|
||||
AZ_TraceContext("AddHelperBoneNodes() rootBoneName:", rootBoneName);
|
||||
|
||||
if (rootBoneName.empty())
|
||||
{
|
||||
AZ_TracePrintf(TraceWindowName, "Root bone name cannot be empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
|
||||
SceneContainers::SceneGraph::NodeIndex nodeIndex = graph.Find(rootBoneName);
|
||||
if (!nodeIndex.IsValid())
|
||||
{
|
||||
AZ_TracePrintf(TraceWindowName, "Unable to find root bone in scene graph.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto contentStorage = graph.GetContentStorage();
|
||||
auto nameStorage = graph.GetNameStorage();
|
||||
auto pairView = SceneViews::MakePairView(contentStorage, nameStorage);
|
||||
auto view = SceneViews::MakeSceneGraphDownwardsView<SceneViews::DepthFirst>(graph, nodeIndex, pairView.begin(), true);
|
||||
int index = 0;
|
||||
|
||||
//Once SceneAPI supports Per Node Attributes, the string with properties
|
||||
//should be built per Node. In the meantime, because all the properties are
|
||||
//the same for all nodes, the string can be built once.
|
||||
AZStd::string nodeProperties;
|
||||
AddPropertyValue(nodeProperties, NODE_PROPERTY_DAMPING, damping, "\r\n");
|
||||
AddPropertyValue(nodeProperties, NODE_PROPERTY_STIFFNESS, stiffness, "\r\n");
|
||||
AddPropertyValue(nodeProperties, NODE_PROPERTY_THICKNESS, thickness, nullptr);
|
||||
for (auto it = view.begin(); it != view.end(); ++it)
|
||||
{
|
||||
if (it->first && it->first->RTTI_IsTypeOf(SceneDataTypes::IBoneData::TYPEINFO_Uuid()))
|
||||
{
|
||||
//These very dummy nodes, are only used to define the name
|
||||
//of the spines. It is not necessary to set transform matrices,
|
||||
//nor it is relevant to set parent pointers, etc.
|
||||
CNodeCGF* nodeCgf = new CNodeCGF();
|
||||
SetNodeName(it->second.GetName(), *nodeCgf);
|
||||
nodeCgf->type = CNodeCGF::NODE_HELPER;
|
||||
nodeCgf->helperType = HP_POINT;
|
||||
nodeCgf->properties = nodeProperties.c_str();
|
||||
content.AddNode(nodeCgf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// End of bone chain or interruption in the bone chain. In both cases stop looking into this part of hierarchy further.
|
||||
it.IgnoreNodeDescendants();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace RC
|
||||
} // namespace AZ
|
||||
@@ -1,60 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <SceneAPI/SceneCore/Components/RCExportingComponent.h>
|
||||
|
||||
struct CNodeCGF;
|
||||
class CContentCGF;
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
|
||||
namespace RC
|
||||
{
|
||||
struct CgfGroupExportContext;
|
||||
struct ContainerExportContext;
|
||||
struct MeshNodeExportContext;
|
||||
|
||||
class TouchBendingExporter
|
||||
: public AZ::SceneAPI::SceneCore::RCExportingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(TouchBendingExporter, "{4C6694B3-F7A8-48D8-A10A-46D57F8CC75E}", AZ::SceneAPI::SceneCore::RCExportingComponent);
|
||||
|
||||
TouchBendingExporter();
|
||||
~TouchBendingExporter() override = default;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
SceneAPI::Events::ProcessingResult ConfigureContainer(AZ::RC::ContainerExportContext& context);
|
||||
SceneAPI::Events::ProcessingResult ProcessSkinnedMesh(AZ::RC::MeshNodeExportContext& context);
|
||||
|
||||
static constexpr const char * const TraceWindowName = "TouchBending";
|
||||
|
||||
protected:
|
||||
/*!
|
||||
StaticObjectCompiler, when building SFoliageInfoCGF, uses the "branch%d_%d" named bones to build the spines.
|
||||
This methods adds the tree of CNodeCGF helper nodes from Bones with such names.
|
||||
*/
|
||||
bool AddHelperBoneNodes(AZ::RC::ContainerExportContext& context, CContentCGF& content, AZStd::string& rootBoneName,
|
||||
bool shouldOverrideDamping, float damping,
|
||||
bool shouldOverrideStiffness, float stiffness,
|
||||
bool shouldOverrideThickness, float thickness);
|
||||
}; //class TouchBendingCgfExporter
|
||||
} // namespace RC
|
||||
} //namespace AZ
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Cry_Geo.h> // Needed for CGFContent.h
|
||||
#include <CGFContent.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphChildIterator.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/Rules/IOriginRule.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/Groups/IMeshGroup.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/ITransform.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
|
||||
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
|
||||
#include <RC/ResourceCompilerScene/Common/WorldMatrixExporter.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RC
|
||||
{
|
||||
namespace SceneEvents = AZ::SceneAPI::Events;
|
||||
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
|
||||
namespace SceneContainers = AZ::SceneAPI::Containers;
|
||||
namespace SceneViews = AZ::SceneAPI::Containers::Views;
|
||||
|
||||
WorldMatrixExporter::WorldMatrixExporter()
|
||||
: m_cachedRootMatrix(MatrixType::CreateIdentity())
|
||||
, m_cachedGroup(nullptr)
|
||||
, m_cachedRootMatrixIsSet(false)
|
||||
{
|
||||
BindToCall(&WorldMatrixExporter::ProcessMeshGroup);
|
||||
BindToCall(&WorldMatrixExporter::ProcessNode);
|
||||
}
|
||||
|
||||
void WorldMatrixExporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<WorldMatrixExporter, SceneAPI::SceneCore::RCExportingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
SceneEvents::ProcessingResult WorldMatrixExporter::ProcessMeshGroup(ContainerExportContext& context)
|
||||
{
|
||||
if (context.m_phase != Phase::Construction)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
m_cachedGroup = &context.m_group;
|
||||
|
||||
m_cachedRootMatrix = MatrixType::CreateIdentity();
|
||||
m_cachedRootMatrixIsSet = false;
|
||||
|
||||
AZStd::shared_ptr<const SceneDataTypes::IOriginRule> rule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::IOriginRule>();
|
||||
if (rule)
|
||||
{
|
||||
if (rule->GetTranslation() != Vector3(0.0f, 0.0f, 0.0f) || !rule->GetRotation().IsIdentity())
|
||||
{
|
||||
m_cachedRootMatrix = MatrixType::CreateFromQuaternionAndTranslation(rule->GetRotation(), rule->GetTranslation());
|
||||
m_cachedRootMatrixIsSet = true;
|
||||
}
|
||||
|
||||
if (rule->GetScale() != 1.0f)
|
||||
{
|
||||
float scale = rule->GetScale();
|
||||
m_cachedRootMatrix.MultiplyByScale(Vector3(scale, scale, scale));
|
||||
m_cachedRootMatrixIsSet = true;
|
||||
}
|
||||
|
||||
if (!rule->GetOriginNodeName().empty() && !rule->UseRootAsOrigin())
|
||||
{
|
||||
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
|
||||
SceneContainers::SceneGraph::NodeIndex index = graph.Find(rule->GetOriginNodeName());
|
||||
if (index.IsValid())
|
||||
{
|
||||
MatrixType worldMatrix = MatrixType::CreateIdentity();
|
||||
if (ConcatenateMatricesUpwards(worldMatrix, graph.ConvertToHierarchyIterator(index), graph))
|
||||
{
|
||||
worldMatrix.InvertFull();
|
||||
m_cachedRootMatrix *= worldMatrix;
|
||||
m_cachedRootMatrixIsSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_cachedRootMatrixIsSet ? SceneEvents::ProcessingResult::Success : SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
}
|
||||
|
||||
SceneEvents::ProcessingResult WorldMatrixExporter::ProcessNode(NodeExportContext& context)
|
||||
{
|
||||
if (context.m_phase != Phase::Filling)
|
||||
{
|
||||
return SceneEvents::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
MatrixType worldMatrix = MatrixType::CreateIdentity();
|
||||
|
||||
const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph();
|
||||
HierarchyStorageIterator nodeIterator = graph.ConvertToHierarchyIterator(context.m_nodeIndex);
|
||||
bool translated = ConcatenateMatricesUpwards(worldMatrix, nodeIterator, graph);
|
||||
|
||||
AZ_Assert(m_cachedGroup == &context.m_group, "NodeExportContext doesn't belong to chain of previously called MeshGroupExportContext.");
|
||||
if (m_cachedRootMatrixIsSet)
|
||||
{
|
||||
worldMatrix = m_cachedRootMatrix * worldMatrix;
|
||||
translated = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//If we aren't merging nodes we need to put the transforms into the localTM
|
||||
//due to how the CGFSaver works inside the ResourceCompilerPC code.
|
||||
if (!context.m_container.GetExportInfo()->bMergeAllNodes)
|
||||
{
|
||||
SceneAPIMatrixTypeToMatrix34(context.m_node.localTM, worldMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneAPIMatrixTypeToMatrix34(context.m_node.worldTM, worldMatrix);
|
||||
}
|
||||
context.m_node.bIdentityMatrix = !translated;
|
||||
|
||||
return SceneEvents::ProcessingResult::Success;
|
||||
}
|
||||
|
||||
bool WorldMatrixExporter::ConcatenateMatricesUpwards(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneContainers::SceneGraph& graph) const
|
||||
{
|
||||
bool translated = false;
|
||||
|
||||
auto view = SceneViews::MakeSceneGraphUpwardsView(graph, nodeIterator, graph.GetContentStorage().cbegin(), true);
|
||||
for (auto it = view.begin(); it != view.end(); ++it)
|
||||
{
|
||||
if (!(*it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const SceneDataTypes::ITransform* nodeTransform = azrtti_cast<const SceneDataTypes::ITransform*>(it->get());
|
||||
if (nodeTransform)
|
||||
{
|
||||
transform = nodeTransform->GetMatrix() * transform;
|
||||
translated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool endPointTransform = MultiplyEndPointTransforms(transform, it.GetHierarchyIterator(), graph);
|
||||
translated = translated || endPointTransform;
|
||||
}
|
||||
}
|
||||
return translated;
|
||||
}
|
||||
|
||||
bool WorldMatrixExporter::MultiplyEndPointTransforms(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneContainers::SceneGraph& graph) const
|
||||
{
|
||||
// If the translation is not an end point it means it's its own group as opposed to being
|
||||
// a component of the parent, so only list end point children.
|
||||
auto view = SceneViews::MakeSceneGraphChildView<SceneViews::AcceptEndPointsOnly>(graph, nodeIterator,
|
||||
graph.GetContentStorage().begin(), true);
|
||||
auto result = AZStd::find_if(view.begin(), view.end(), SceneContainers::DerivedTypeFilter<SceneDataTypes::ITransform>());
|
||||
if (result != view.end())
|
||||
{
|
||||
transform = azrtti_cast<const SceneDataTypes::ITransform*>(result->get())->GetMatrix() * transform;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldMatrixExporter::SceneAPIMatrixTypeToMatrix34(Matrix34& out, const MatrixType& in) const
|
||||
{
|
||||
// Setting column instead of row because as of writing Matrix34 doesn't support adding
|
||||
// full rows, as the translation has to be done separately.
|
||||
for (int column = 0; column < 4; ++column)
|
||||
{
|
||||
Vector3 data = in.GetColumn(column);
|
||||
out.SetColumn(column, Vec3(data.GetX(), data.GetY(), data.GetZ()));
|
||||
}
|
||||
}
|
||||
} // namespace RC
|
||||
} // namespace AZ
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Cry_Matrix34.h>
|
||||
#include <SceneAPI/SceneCore/Components/RCExportingComponent.h>
|
||||
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class Transform;
|
||||
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace DataTypes
|
||||
{
|
||||
class IOriginRule;
|
||||
class IGroup;
|
||||
}
|
||||
}
|
||||
|
||||
namespace RC
|
||||
{
|
||||
struct ContainerExportContext;
|
||||
struct NodeExportContext;
|
||||
|
||||
class WorldMatrixExporter
|
||||
: public SceneAPI::SceneCore::RCExportingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(WorldMatrixExporter, "{65A0914C-5953-405F-819B-0E6EB96938F1}", SceneAPI::SceneCore::RCExportingComponent);
|
||||
|
||||
WorldMatrixExporter();
|
||||
~WorldMatrixExporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
SceneAPI::Events::ProcessingResult ProcessMeshGroup(ContainerExportContext& context);
|
||||
SceneAPI::Events::ProcessingResult ProcessNode(NodeExportContext& context);
|
||||
|
||||
protected:
|
||||
using HierarchyStorageIterator = SceneAPI::Containers::SceneGraph::HierarchyStorageConstIterator;
|
||||
using MatrixType = SceneAPI::DataTypes::MatrixType;
|
||||
|
||||
bool ConcatenateMatricesUpwards(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneAPI::Containers::SceneGraph& graph) const;
|
||||
bool MultiplyEndPointTransforms(MatrixType& transform, const HierarchyStorageIterator& nodeIterator, const SceneAPI::Containers::SceneGraph& graph) const;
|
||||
void SceneAPIMatrixTypeToMatrix34(Matrix34& out, const MatrixType& in) const;
|
||||
|
||||
MatrixType m_cachedRootMatrix;
|
||||
const SceneAPI::DataTypes::IGroup* m_cachedGroup;
|
||||
bool m_cachedRootMatrixIsSet;
|
||||
};
|
||||
} // namespace RC
|
||||
} // namespace AZ
|
||||
@@ -12,6 +12,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class IConfig;
|
||||
|
||||
namespace AZ
|
||||
@@ -30,4 +32,4 @@ namespace AZ
|
||||
|
||||
inline ISceneConfig::~ISceneConfig() = default;
|
||||
} // RC
|
||||
} // AZ
|
||||
} // AZ
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ResourceCompilerScene_precompiled.h"
|
||||
#include <ISystem.h>
|
||||
#include <platform.h>
|
||||
#include <IResCompiler.h>
|
||||
#include <IRCLog.h>
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define CRY_ASSERT(condition) assert(condition)
|
||||
#define CRY_ASSERT_TRACE(condition, message) assert(condition)
|
||||
#define CRY_ASSERT_MESSAGE(condition, message) assert(condition)
|
||||
|
||||
// Define this to prevent including CryAssert (there is no proper hook for turning this off, like the above).
|
||||
#define CRYINCLUDE_CRYCOMMON_CRYASSERT_H
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include <Cry_Geo.h>
|
||||
#include <CryHeaders.h>
|
||||
#include <primitives.h>
|
||||
#include <smartptr.h>
|
||||
#include <physinterface.h>
|
||||
#include <CrySizer.h>
|
||||
|
||||
#include <RC/ResourceCompiler/IRCLog.h>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ResourceCompilerScene_precompiled.h"
|
||||
#include <IRCLog.h>
|
||||
#include <ISceneConfig.h>
|
||||
#include <ISystem.h>
|
||||
@@ -43,13 +42,11 @@
|
||||
#include <RC/ResourceCompilerScene/Common/ContainerSettingsExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/MeshExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/MaterialExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/WorldMatrixExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/ColorStreamExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/UVStreamExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/SkeletonExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/SkinWeightExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/BlendShapeExporter.h>
|
||||
#include <RC/ResourceCompilerScene/Common/TouchBendingExporter.h>
|
||||
#include <RC/ResourceCompilerScene/SceneSerializationHandler.h>
|
||||
|
||||
#include <SceneAPI/SceneCore/Components/ExportingComponent.h>
|
||||
@@ -96,8 +93,6 @@ namespace AZ
|
||||
RegisterComponentDescriptor(SkeletonExporter::CreateDescriptor());
|
||||
RegisterComponentDescriptor(SkinWeightExporter::CreateDescriptor());
|
||||
RegisterComponentDescriptor(UVStreamExporter::CreateDescriptor());
|
||||
RegisterComponentDescriptor(WorldMatrixExporter::CreateDescriptor());
|
||||
RegisterComponentDescriptor(TouchBendingExporter::CreateDescriptor());
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList RCToolApplication::GetRequiredSystemComponents() const
|
||||
@@ -375,6 +370,12 @@ namespace AZ
|
||||
result += SceneEvents::Process<SceneEvents::PreGenerateEventContext>(scene, platformIdentifier);
|
||||
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "Generating...\n");
|
||||
result += SceneEvents::Process<SceneEvents::GenerateEventContext>(scene, platformIdentifier);
|
||||
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "Generating LODs...\n");
|
||||
result += SceneEvents::Process<SceneEvents::GenerateLODEventContext>(scene, platformIdentifier);
|
||||
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "Generating additions...\n");
|
||||
result += SceneEvents::Process<SceneEvents::GenerateAdditionEventContext>(scene, platformIdentifier);
|
||||
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "Simplifing scene...\n");
|
||||
result += SceneEvents::Process<SceneEvents::GenerateSimplificationEventContext>(scene, platformIdentifier);
|
||||
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "Finalizing generation process.\n");
|
||||
result += SceneEvents::Process<SceneEvents::PostGenerateEventContext>(scene, platformIdentifier);
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ResourceCompilerScene_precompiled.h"
|
||||
#include <IConfig.h>
|
||||
#include <SceneConfig.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ResourceCompilerScene_precompiled.h"
|
||||
#include <SceneConverter.h>
|
||||
#include <SceneCompiler.h>
|
||||
#include <ISceneConfig.h>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ResourceCompilerScene_precompiled.h"
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Cry_Geo.h> // Needed for Cry_Matrix34.h
|
||||
#include <Cry_Matrix34.h>
|
||||
#include <RC/ResourceCompilerScene/Tests/Cgf/CgfExportContextTestBase.h>
|
||||
#include <RC/ResourceCompilerScene/Cgf/CgfExportContexts.h>
|
||||
#include <RC/ResourceCompilerScene/Common/WorldMatrixExporter.h>
|
||||
#include <SceneAPI/SceneCore/Mocks/DataTypes/GraphData/MockITransform.h>
|
||||
#include <SceneAPI/SceneCore/Mocks/DataTypes/GraphData/MockIMeshData.h>
|
||||
#include <SceneAPI/SceneCore/Mocks/DataTypes/ManifestBase/MockISceneNodeSelectionList.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RC
|
||||
{
|
||||
using ::testing::Const;
|
||||
using ::testing::Return;
|
||||
using ::testing::ReturnRef;
|
||||
|
||||
class WorldMatrixExporterContextTestBase
|
||||
: public CgfExporterContextTestBase
|
||||
{
|
||||
public:
|
||||
WorldMatrixExporterContextTestBase()
|
||||
: m_stubTransformData(new SceneAPI::DataTypes::MockITransform())
|
||||
, m_stubMeshData(new SceneAPI::DataTypes::MockIMeshData())
|
||||
, m_stubTransform(AZ::SceneAPI::DataTypes::MatrixType::CreateTranslation(AZ::Vector3(0.f, 0.f, 1.f)))
|
||||
{
|
||||
}
|
||||
~WorldMatrixExporterContextTestBase() override = default;
|
||||
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
CgfExporterContextTestBase::SetUp();
|
||||
|
||||
m_outNode.bIdentityMatrix = true;
|
||||
SceneAPI::Containers::SceneGraph& sceneGraph = m_stubScene.GetGraph();
|
||||
SceneAPI::Containers::SceneGraph::NodeIndex rootIndex = sceneGraph.GetRoot();
|
||||
SceneAPI::Containers::SceneGraph::NodeIndex transformIndex = sceneGraph.AddChild(rootIndex, "SampleTransformData", m_stubTransformData);
|
||||
SceneAPI::Containers::SceneGraph::NodeIndex meshIndex = sceneGraph.AddChild(transformIndex, "SampleMeshData", m_stubMeshData);
|
||||
|
||||
UpdateNodeIndex(meshIndex);
|
||||
|
||||
EXPECT_CALL(Const(*m_stubTransformData), GetMatrix())
|
||||
.WillRepeatedly(ReturnRef(m_stubTransform));
|
||||
ON_CALL(m_stubMeshGroup, GetRuleContainer())
|
||||
.WillByDefault(ReturnRef(m_ruleContainer));
|
||||
ON_CALL(Const(m_stubMeshGroup), GetRuleContainerConst())
|
||||
.WillByDefault(ReturnRef(m_ruleContainer));
|
||||
}
|
||||
|
||||
bool TestChangedData()
|
||||
{
|
||||
return !m_outNode.bIdentityMatrix;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SceneAPI::DataTypes::MockITransform> m_stubTransformData;
|
||||
AZStd::shared_ptr<SceneAPI::DataTypes::MockIMeshData> m_stubMeshData;
|
||||
AZ::SceneAPI::DataTypes::MatrixType m_stubTransform;
|
||||
WorldMatrixExporter m_testExporter;
|
||||
SceneAPI::Containers::RuleContainer m_ruleContainer;
|
||||
};
|
||||
|
||||
class WorldMatrixExporterNoOpTestFramework
|
||||
: public WorldMatrixExporterContextTestBase
|
||||
{
|
||||
public:
|
||||
|
||||
~WorldMatrixExporterNoOpTestFramework() override = default;
|
||||
};
|
||||
|
||||
TEST_P(WorldMatrixExporterNoOpTestFramework, Process_UnsupportedContext_OutNodeAtIndentity)
|
||||
{
|
||||
m_testExporter.Process(m_stubContext);
|
||||
EXPECT_FALSE(TestChangedData());
|
||||
}
|
||||
|
||||
ContextPhaseTuple g_CgfWorldMatrixExporterTestsUnsupportedContextPhaseTuples[] =
|
||||
{
|
||||
{ TestContextMeshGroup, Phase::Filling },
|
||||
{ TestContextMeshGroup, Phase::Finalizing },
|
||||
{ TestContextContainer, Phase::Construction },
|
||||
{ TestContextContainer, Phase::Filling },
|
||||
{ TestContextContainer, Phase::Finalizing },
|
||||
{ TestContextNode, Phase::Construction },
|
||||
{ TestContextNode, Phase::Finalizing },
|
||||
{ TestContextMeshNode, Phase::Construction },
|
||||
{ TestContextMeshNode, Phase::Filling },
|
||||
{ TestContextMeshNode, Phase::Finalizing }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(WorldMatrixExporter,
|
||||
WorldMatrixExporterNoOpTestFramework,
|
||||
::testing::ValuesIn(g_CgfWorldMatrixExporterTestsUnsupportedContextPhaseTuples));
|
||||
|
||||
class WorldMatrixExporterSimpleTests
|
||||
: public WorldMatrixExporterContextTestBase
|
||||
{
|
||||
public:
|
||||
WorldMatrixExporterSimpleTests()
|
||||
: m_cacheGenerationContext(m_productList, m_stubScene, m_sampleOutputDirectory, m_stubMeshGroup, Phase::Construction)
|
||||
{
|
||||
}
|
||||
~WorldMatrixExporterSimpleTests() override = default;
|
||||
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
WorldMatrixExporterContextTestBase::SetUp();
|
||||
m_testExporter.Process(&m_cacheGenerationContext);
|
||||
}
|
||||
|
||||
CgfGroupExportContext m_cacheGenerationContext;
|
||||
};
|
||||
|
||||
// Disable the test due to an assert that checking consistency of cached mesh group which lacks a way to support currently
|
||||
//TEST_P(WorldMatrixExporterSimpleTests, Process_SupportedContext_OutNodeNotAtIndentity)
|
||||
//{
|
||||
// m_testExporter.Process(m_stubContext);
|
||||
// EXPECT_TRUE(TestChangedData());
|
||||
//}
|
||||
|
||||
ContextPhaseTuple g_CgfWorldMatrixExporterTestsSupportedContextPhaseTuples[] =
|
||||
{
|
||||
{ TestContextNode, Phase::Filling }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(WorldMatrixExporter,
|
||||
WorldMatrixExporterSimpleTests,
|
||||
::testing::ValuesIn(g_CgfWorldMatrixExporterTestsSupportedContextPhaseTuples));
|
||||
} // namespace RC
|
||||
} // namespace AZ
|
||||
@@ -10,7 +10,6 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
ResourceCompilerScene_precompiled.h
|
||||
TraceDrillerHook.h
|
||||
TraceDrillerHook.cpp
|
||||
ISceneConfig.h
|
||||
@@ -33,8 +32,6 @@ set(FILES
|
||||
Common/MeshExporter.cpp
|
||||
Common/MaterialExporter.h
|
||||
Common/MaterialExporter.cpp
|
||||
Common/WorldMatrixExporter.h
|
||||
Common/WorldMatrixExporter.cpp
|
||||
Common/ColorStreamExporter.h
|
||||
Common/ColorStreamExporter.cpp
|
||||
Common/UVStreamExporter.h
|
||||
@@ -45,8 +42,6 @@ set(FILES
|
||||
Common/SkinWeightExporter.cpp
|
||||
Common/BlendShapeExporter.h
|
||||
Common/BlendShapeExporter.cpp
|
||||
Common/TouchBendingExporter.h
|
||||
Common/TouchBendingExporter.cpp
|
||||
Cgf/CgfExportContexts.h
|
||||
Cgf/CgfExportContexts.cpp
|
||||
Cgf/CgfGroupExporter.h
|
||||
|
||||
@@ -18,6 +18,5 @@ set(FILES
|
||||
Tests/Cgf/CgfMeshExporterTests.cpp
|
||||
Tests/Cgf/CgfMeshGroupExporterTests.cpp
|
||||
Tests/Cgf/CgfUVStreamExporterTests.cpp
|
||||
Tests/Cgf/CgfWorldMatrixExporterTests.cpp
|
||||
ResourceCompilerScene.cpp
|
||||
)
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
set(sdkwrapper_dir ${CMAKE_CURRENT_LIST_DIR}/../SDKWrapper)
|
||||
set(sdkwrapper_pal_dir ${sdkwrapper_dir}/Platform/${PAL_PLATFORM_NAME})
|
||||
|
||||
if (NOT PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
return()
|
||||
@@ -23,9 +21,6 @@ ly_add_target(
|
||||
FILES_CMAKE
|
||||
fbxsdkwrapper_files.cmake
|
||||
${sdkwrapper_dir}/sdkwrapper_files.cmake
|
||||
${sdkwrapper_pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
|
||||
PLATFORM_INCLUDE_FILES
|
||||
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
.
|
||||
@@ -37,4 +32,5 @@ ly_add_target(
|
||||
AZ::AzToolsFramework
|
||||
PUBLIC
|
||||
3rdParty::FbxSdk
|
||||
3rdParty::assimplib
|
||||
)
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace AZ
|
||||
return 10.f;
|
||||
}
|
||||
|
||||
uint64_t FbxMaterialWrapper::GetUniqueId() const
|
||||
AZ::u64 FbxMaterialWrapper::GetUniqueId() const
|
||||
{
|
||||
return m_fbxMaterial->GetUniqueID();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace AZ
|
||||
AZ::Vector3 GetEmissiveColor() const override;
|
||||
float GetOpacity() const override;
|
||||
float GetShininess() const override;
|
||||
uint64_t GetUniqueId() const override;
|
||||
AZ::u64 GetUniqueId() const override;
|
||||
};
|
||||
} // namespace FbxSDKWrapper
|
||||
} // namespace AZ
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
set(LY_BUILD_DEPENDENCIES
|
||||
PUBLIC
|
||||
3rdParty::AssImp
|
||||
)
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC ASSET_IMPORTER_SDK_SUPPORTED_TRAIT)
|
||||
@@ -19,13 +19,18 @@
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h>
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxImporter.h>
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBitangentStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpColorStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMaterialImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMeshImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTangentStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpUvMapImporter.h>
|
||||
#endif
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinWeightsImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBlendShapeImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxAnimationImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBlendShapeImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBoneImporter.h>
|
||||
@@ -39,7 +44,6 @@
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTransformImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxUvMapImporter.h>
|
||||
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
@@ -86,13 +90,19 @@ namespace AZ
|
||||
g_componentDescriptors.push_back(FbxUvMapImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(FbxTangentStreamImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(FbxBitangentStreamImporter::CreateDescriptor());
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpColorStreamImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpMaterialImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpMeshImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpTangentStreamImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpTransformImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpUvMapImporter::CreateDescriptor());
|
||||
#endif
|
||||
g_componentDescriptors.push_back(AssImpSkinImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpSkinWeightsImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpBoneImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpAnimationImporter::CreateDescriptor());
|
||||
g_componentDescriptors.push_back(AssImpBlendShapeImporter::CreateDescriptor());
|
||||
|
||||
for (AZ::ComponentDescriptor* descriptor : g_componentDescriptors)
|
||||
{
|
||||
AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationBus::Handler::RegisterComponentDescriptor, descriptor);
|
||||
|
||||
@@ -21,10 +21,8 @@
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMaterialImporter.h>
|
||||
#endif
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
|
||||
@@ -32,10 +30,8 @@
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneData/GraphData/TransformData.h>
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#endif
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -59,7 +55,7 @@ namespace AZ
|
||||
FbxImporter::FbxImporter()
|
||||
: m_sceneSystem(new FbxSceneSystem())
|
||||
{
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
|
||||
if (m_useAssetImporterSDK)
|
||||
{
|
||||
m_sceneWrapper = AZStd::make_unique<AssImpSDKWrapper::AssImpSceneWrapper>();
|
||||
@@ -68,9 +64,7 @@ namespace AZ
|
||||
{
|
||||
m_sceneWrapper = AZStd::make_unique<FbxSDKWrapper::FbxSceneWrapper>();
|
||||
}
|
||||
#else
|
||||
m_sceneWrapper = AZStd::make_unique<FbxSDKWrapper::FbxSceneWrapper>();
|
||||
#endif
|
||||
|
||||
BindToCall(&FbxImporter::ImportProcessing);
|
||||
}
|
||||
|
||||
@@ -99,12 +93,10 @@ namespace AZ
|
||||
{
|
||||
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxSceneContext, this, AZStd::placeholders::_1);
|
||||
}
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
else
|
||||
{
|
||||
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxScene, this, AZStd::placeholders::_1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (convertFunc(context.GetScene()))
|
||||
{
|
||||
@@ -284,7 +276,7 @@ namespace AZ
|
||||
|
||||
return true;
|
||||
}
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
|
||||
bool FbxImporter::ConvertFbxScene(Containers::Scene& scene) const
|
||||
{
|
||||
std::shared_ptr<SDKNode::NodeWrapper> fbxRoot = m_sceneWrapper->GetRootNode();
|
||||
@@ -333,6 +325,8 @@ namespace AZ
|
||||
continue;
|
||||
}
|
||||
AZStd::string nodeName = nodeNameMap.GetNodeName(node.m_node);
|
||||
SanitizeNodeName(nodeName);
|
||||
|
||||
AZ_TraceContext("SceneAPI Node Name", nodeName);
|
||||
Containers::SceneGraph::NodeIndex newNode = scene.GetGraph().AddChild(node.m_parent, nodeName.c_str());
|
||||
|
||||
@@ -431,7 +425,13 @@ namespace AZ
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void FbxImporter::SanitizeNodeName(AZStd::string& nodeName) const
|
||||
{
|
||||
// Replace % with something else so it is safe for use in printfs.
|
||||
AZStd::replace(nodeName.begin(), nodeName.end(), '%', '_');
|
||||
}
|
||||
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -46,15 +46,12 @@ namespace AZ
|
||||
|
||||
protected:
|
||||
bool ConvertFbxSceneContext(Containers::Scene& scene) const;
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
bool ConvertFbxScene(Containers::Scene& scene) const;
|
||||
#endif
|
||||
void SanitizeNodeName(AZStd::string& nodeName) const;
|
||||
|
||||
AZStd::unique_ptr<SDKScene::SceneWrapperBase> m_sceneWrapper;
|
||||
AZStd::shared_ptr<FbxSceneSystem> m_sceneSystem;
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
bool m_useAssetImporterSDK = false;
|
||||
#endif
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
|
||||
@@ -13,12 +13,9 @@
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
#include <assimp/scene.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace AZ
|
||||
@@ -52,7 +49,6 @@ namespace AZ
|
||||
m_adjustTransformInverse.reset(new DataTypes::MatrixType(m_adjustTransform->GetInverseFull()));
|
||||
}
|
||||
}
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
else if (azrtti_istypeof<AssImpSDKWrapper::AssImpSceneWrapper>(fbxScene))
|
||||
{
|
||||
const AssImpSDKWrapper::AssImpSceneWrapper* assImpScene = azrtti_cast<const AssImpSDKWrapper::AssImpSceneWrapper*>(fbxScene);
|
||||
@@ -135,7 +131,6 @@ namespace AZ
|
||||
m_adjustTransformInverse.reset(new DataTypes::MatrixType(m_adjustTransform->GetInverseFull()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FbxSceneSystem::SwapVec3ForUpAxis(Vector3& swapVector) const
|
||||
|
||||
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include <AssImpTypeConverter.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxAnimCurveWrapper.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxAnimLayerWrapper.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxTimeSpanWrapper.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneData/GraphData/AnimationData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
const char* AssImpAnimationImporter::s_animationNodeName = "animation";
|
||||
const FbxSDKWrapper::FbxTimeWrapper::TimeMode AssImpAnimationImporter::s_defaultTimeMode =
|
||||
FbxSDKWrapper::FbxTimeWrapper::frames30;
|
||||
|
||||
AssImpAnimationImporter::AssImpAnimationImporter()
|
||||
{
|
||||
BindToCall(&AssImpAnimationImporter::ImportAnimation);
|
||||
}
|
||||
|
||||
void AssImpAnimationImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string GetName(const aiMeshAnim* anim)
|
||||
{
|
||||
return anim->mName.C_Str();
|
||||
}
|
||||
|
||||
AZStd::string GetName(const aiNodeAnim* anim)
|
||||
{
|
||||
return anim->mNodeName.C_Str();
|
||||
}
|
||||
|
||||
AZStd::string GetName(const aiMeshMorphAnim* anim)
|
||||
{
|
||||
return anim->mName.C_Str();
|
||||
}
|
||||
|
||||
struct ConsolidatedNodeAnim
|
||||
{
|
||||
ConsolidatedNodeAnim() = default;
|
||||
ConsolidatedNodeAnim(const ConsolidatedNodeAnim& other) = delete;
|
||||
|
||||
ConsolidatedNodeAnim(ConsolidatedNodeAnim&& other) noexcept
|
||||
: mNumPositionKeys{ other.mNumPositionKeys },
|
||||
mPositionKeys{ other.mPositionKeys },
|
||||
mNumRotationKeys{ other.mNumRotationKeys },
|
||||
mRotationKeys{ other.mRotationKeys },
|
||||
mNumScalingKeys{ other.mNumScalingKeys },
|
||||
mScalingKeys{ other.mScalingKeys },
|
||||
m_ownedPositionKeys{ std::move(other.m_ownedPositionKeys) },
|
||||
m_ownedScalingKeys{ std::move(other.m_ownedScalingKeys) },
|
||||
m_ownedRotationKeys{ std::move(other.m_ownedRotationKeys) },
|
||||
mPreState{ other.mPreState },
|
||||
mPostState{ other.mPostState }
|
||||
{
|
||||
}
|
||||
|
||||
ConsolidatedNodeAnim& operator=(const ConsolidatedNodeAnim& other) = delete;
|
||||
|
||||
ConsolidatedNodeAnim& operator=(ConsolidatedNodeAnim&& other) noexcept
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
mNumPositionKeys = other.mNumPositionKeys;
|
||||
mPositionKeys = other.mPositionKeys;
|
||||
mNumRotationKeys = other.mNumRotationKeys;
|
||||
mRotationKeys = other.mRotationKeys;
|
||||
mNumScalingKeys = other.mNumScalingKeys;
|
||||
mScalingKeys = other.mScalingKeys;
|
||||
m_ownedPositionKeys = std::move(other.m_ownedPositionKeys);
|
||||
m_ownedScalingKeys = std::move(other.m_ownedScalingKeys);
|
||||
m_ownedRotationKeys = std::move(other.m_ownedRotationKeys);
|
||||
mPreState = other.mPreState;
|
||||
mPostState = other.mPostState;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// These variables are named using AssImp naming convention for consistency
|
||||
unsigned int mNumPositionKeys{};
|
||||
aiVectorKey* mPositionKeys{};
|
||||
|
||||
unsigned int mNumRotationKeys{};
|
||||
aiQuatKey* mRotationKeys{};
|
||||
|
||||
unsigned int mNumScalingKeys{};
|
||||
aiVectorKey* mScalingKeys{};
|
||||
|
||||
AZStd::vector<aiVectorKey> m_ownedPositionKeys{};
|
||||
AZStd::vector<aiVectorKey> m_ownedScalingKeys{};
|
||||
AZStd::vector<aiQuatKey> m_ownedRotationKeys{};
|
||||
|
||||
aiAnimBehaviour mPreState{};
|
||||
aiAnimBehaviour mPostState{};
|
||||
};
|
||||
|
||||
AZStd::pair<const aiAnimation*, ConsolidatedNodeAnim> MakeMyPair(const aiAnimation* animation, const aiNodeAnim* anim)
|
||||
{
|
||||
ConsolidatedNodeAnim consolidatedNodeAnim{};
|
||||
|
||||
consolidatedNodeAnim.mNumRotationKeys = anim->mNumRotationKeys;
|
||||
consolidatedNodeAnim.mNumPositionKeys = anim->mNumPositionKeys;
|
||||
consolidatedNodeAnim.mNumScalingKeys = anim->mNumScalingKeys;
|
||||
consolidatedNodeAnim.mRotationKeys = anim->mRotationKeys;
|
||||
consolidatedNodeAnim.mPositionKeys = anim->mPositionKeys;
|
||||
consolidatedNodeAnim.mScalingKeys = anim->mScalingKeys;
|
||||
|
||||
return {animation, AZStd::move(consolidatedNodeAnim)};
|
||||
}
|
||||
|
||||
auto MakeMyPair(const aiAnimation* animation, const aiMeshAnim* anim)
|
||||
{
|
||||
return AZStd::make_pair(animation, anim);
|
||||
}
|
||||
|
||||
auto MakeMyPair(const aiAnimation* animation, const aiMeshMorphAnim* anim)
|
||||
{
|
||||
return AZStd::make_pair(animation, anim);
|
||||
}
|
||||
|
||||
|
||||
Events::ProcessingResult AssImpAnimationImporter::ImportAnimation(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Animation");
|
||||
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
// Add check for animation layers at the scene level.
|
||||
|
||||
if (!scene->HasAnimations() || IsPivotNode(currentNode->mName))
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::unordered_multimap<AZStd::string, AZStd::pair<const aiAnimation*, ConsolidatedNodeAnim>> boneAnimations;
|
||||
typedef AZStd::pair<const aiAnimation*, const aiMeshMorphAnim*> AnimAndMorphAnim;
|
||||
typedef AZStd::unordered_map<AZStd::string, AnimAndMorphAnim> ChannelToMorphAnim;
|
||||
typedef AZStd::unordered_map<AZStd::string, ChannelToMorphAnim> NodeToChannelToMorphAnim;
|
||||
NodeToChannelToMorphAnim meshMorphAnimations;
|
||||
|
||||
// Goes through all the animation channels of a given type and adds them to a map so we can easily find
|
||||
// all the animations for a given node
|
||||
// In the case of bone animations, the data is copied into a ConsolidatedNodeAnim so we can
|
||||
// do fix-ups later without affecting the original data
|
||||
auto mapAnimationsFunc = [](unsigned numChannels, auto** channels, const aiAnimation* animation, auto& map)
|
||||
{
|
||||
map.reserve(numChannels);
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < numChannels; ++channelIndex)
|
||||
{
|
||||
auto* nodeAnim = channels[channelIndex];
|
||||
AZStd::string name = GetName(nodeAnim);
|
||||
|
||||
map.emplace(name, MakeMyPair(animation, nodeAnim));
|
||||
}
|
||||
};
|
||||
|
||||
for (unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
|
||||
{
|
||||
const aiAnimation* animation = scene->mAnimations[animIndex];
|
||||
|
||||
mapAnimationsFunc(animation->mNumChannels, animation->mChannels, animation, boneAnimations);
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < animation->mNumMorphMeshChannels; ++channelIndex)
|
||||
{
|
||||
auto* nodeAnim = animation->mMorphMeshChannels[channelIndex];
|
||||
AZStd::string name = GetName(nodeAnim);
|
||||
|
||||
AZStd::vector<AZStd::string> meshNodeNameAndChannel;
|
||||
|
||||
// Morph target animations include the channel in the name,
|
||||
// so if a mesh is named Mesh01, the morph target for the first channel
|
||||
// will be named Mesh01*0
|
||||
AZ::StringFunc::Tokenize(name, meshNodeNameAndChannel, '*');
|
||||
|
||||
if (meshNodeNameAndChannel.size() != 2)
|
||||
{
|
||||
AZ_Error(
|
||||
"AnimationImporter", false,
|
||||
"Morph animation name %s was not in the expected format of: node name, asterisk, node channel. "
|
||||
"Example: 'NodeName*0'",
|
||||
name.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
AZStd::string meshNodeName(meshNodeNameAndChannel[0]);
|
||||
AZStd::string channel(meshNodeNameAndChannel[1]);
|
||||
meshMorphAnimations[meshNodeName][channel] = AnimAndMorphAnim(animation, nodeAnim);
|
||||
}
|
||||
}
|
||||
|
||||
// Go through all the bone animations and find any that reference a pivot node
|
||||
// We'll make a new node anim and store all the combined animation channels there
|
||||
// with the name set to the base bone name
|
||||
decltype(boneAnimations) combinedAnimations;
|
||||
|
||||
for (auto&& animation : boneAnimations)
|
||||
{
|
||||
size_t pos = AZ::StringFunc::Find(animation.first, PivotNodeMarker, 0);
|
||||
|
||||
if (pos != animation.first.npos)
|
||||
{
|
||||
AZStd::string_view name, part;
|
||||
SplitPivotNodeName(aiString(animation.first.c_str()), pos, name, part);
|
||||
|
||||
auto&& iterator = combinedAnimations.find(name);
|
||||
|
||||
if (iterator == combinedAnimations.end())
|
||||
{
|
||||
combinedAnimations.emplace(AZStd::string(name), AZStd::move(animation.second));
|
||||
iterator = combinedAnimations.find(name);
|
||||
}
|
||||
|
||||
if (iterator != combinedAnimations.end())
|
||||
{
|
||||
auto& existingNode = iterator->second.second;
|
||||
auto&& src = animation.second.second;
|
||||
|
||||
if (part == "Translation")
|
||||
{
|
||||
existingNode.mNumPositionKeys = src.mNumPositionKeys;
|
||||
existingNode.mPositionKeys = src.mPositionKeys;
|
||||
}
|
||||
else if (part == "Rotation")
|
||||
{
|
||||
existingNode.mNumRotationKeys = src.mNumRotationKeys;
|
||||
existingNode.mRotationKeys = src.mRotationKeys;
|
||||
}
|
||||
else if (part == "Scaling")
|
||||
{
|
||||
existingNode.mNumScalingKeys = src.mNumScalingKeys;
|
||||
existingNode.mScalingKeys = src.mScalingKeys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!combinedAnimations.empty())
|
||||
{
|
||||
boneAnimations.swap(combinedAnimations);
|
||||
}
|
||||
|
||||
Events::ProcessingResultCombiner combinedAnimationResult;
|
||||
for (unsigned meshIndex = 0; meshIndex < currentNode->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[meshIndex]];
|
||||
|
||||
if (NodeToChannelToMorphAnim::iterator channelsForMeshName = meshMorphAnimations.find(mesh->mName.C_Str());
|
||||
channelsForMeshName != meshMorphAnimations.end())
|
||||
{
|
||||
const auto [nodeIterName, channels] = *channelsForMeshName;
|
||||
for (const auto& [channel, animAndMorphAnim] : channels)
|
||||
{
|
||||
const auto& [animation, morphAnimation] = animAndMorphAnim;
|
||||
combinedAnimationResult += ImportBlendShapeAnimation(
|
||||
context, animation, morphAnimation, mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string nodeName = s_animationNodeName;
|
||||
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
|
||||
AZ_TraceContext("Animation node name", nodeName);
|
||||
|
||||
// If there are no bone animations, but there are mesh animations,
|
||||
// then a stub animation needs to be created so the exporter can create the exported morph target animation.
|
||||
if (boneAnimations.empty() && !meshMorphAnimations.empty())
|
||||
{
|
||||
const aiAnimation* animation = scene->mAnimations[0];
|
||||
|
||||
// Morph animations need a regular animation on the node, as well.
|
||||
// If there is no bone animation on the current node, then generate one here.
|
||||
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
|
||||
AZStd::make_shared<SceneData::GraphData::AnimationData>();
|
||||
createdAnimationData->ReserveKeyFrames(
|
||||
animation->mDuration +
|
||||
1); // +1 because we start at 0 and the last keyframe is at mDuration instead of mDuration-1
|
||||
createdAnimationData->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
|
||||
|
||||
// Set every frame of the animation to the start location of the node.
|
||||
aiMatrix4x4 combinedTransform = GetConcatenatedLocalTransform(currentNode);
|
||||
DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform);
|
||||
context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform);
|
||||
context.m_sourceSceneSystem.ConvertUnit(localTransform);
|
||||
for (unsigned time = 0; time <= animation->mDuration; ++time)
|
||||
{
|
||||
createdAnimationData->AddKeyFrame(localTransform);
|
||||
}
|
||||
|
||||
Containers::SceneGraph::NodeIndex addNode = context.m_scene.GetGraph().AddChild(
|
||||
context.m_currentGraphPosition, nodeName.c_str(), AZStd::move(createdAnimationData));
|
||||
context.m_scene.GetGraph().MakeEndPoint(addNode);
|
||||
|
||||
return combinedAnimationResult.GetResult();
|
||||
}
|
||||
decltype(boneAnimations) parentFillerAnimations;
|
||||
|
||||
// Go through all the animations and make sure we create animations for bones who's parents don't have an animation
|
||||
for (auto&& anim : boneAnimations)
|
||||
{
|
||||
aiNode* node = scene->mRootNode->FindNode(anim.first.c_str());
|
||||
aiNode* parent = node->mParent;
|
||||
|
||||
while (parent && parent != scene->mRootNode)
|
||||
{
|
||||
if (!IsPivotNode(parent->mName))
|
||||
{
|
||||
if (boneAnimations.find(parent->mName.C_Str()) == boneAnimations.end() &&
|
||||
parentFillerAnimations.find(parent->mName.C_Str()) == parentFillerAnimations.end())
|
||||
{
|
||||
// Create 1 key for each type that just copies the current transform
|
||||
ConsolidatedNodeAnim emptyAnimation;
|
||||
aiMatrix4x4 globalTransform = GetConcatenatedLocalTransform(parent);
|
||||
|
||||
aiVector3D position, scale;
|
||||
aiQuaternion rotation;
|
||||
|
||||
globalTransform.Decompose(scale, rotation, position);
|
||||
|
||||
emptyAnimation.mNumRotationKeys = emptyAnimation.mNumPositionKeys = emptyAnimation.mNumScalingKeys = 1;
|
||||
|
||||
emptyAnimation.m_ownedPositionKeys.emplace_back(0, position);
|
||||
emptyAnimation.mPositionKeys = emptyAnimation.m_ownedPositionKeys.data();
|
||||
|
||||
emptyAnimation.m_ownedRotationKeys.emplace_back(0, rotation);
|
||||
emptyAnimation.mRotationKeys = emptyAnimation.m_ownedRotationKeys.data();
|
||||
|
||||
emptyAnimation.m_ownedScalingKeys.emplace_back(0, scale);
|
||||
emptyAnimation.mScalingKeys = emptyAnimation.m_ownedScalingKeys.data();
|
||||
|
||||
parentFillerAnimations.insert(
|
||||
AZStd::make_pair(parent->mName.C_Str(), AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation))));
|
||||
}
|
||||
}
|
||||
|
||||
parent = parent->mParent;
|
||||
}
|
||||
}
|
||||
|
||||
boneAnimations.insert(AZStd::make_move_iterator(parentFillerAnimations.begin()), AZStd::make_move_iterator(parentFillerAnimations.end()));
|
||||
|
||||
auto animItr = boneAnimations.equal_range(currentNode->mName.C_Str());
|
||||
|
||||
if (animItr.first == animItr.second)
|
||||
{
|
||||
return combinedAnimationResult.GetResult();
|
||||
}
|
||||
|
||||
bool onlyOne = false;
|
||||
|
||||
for (auto it = animItr.first; it != animItr.second; ++it)
|
||||
{
|
||||
if (onlyOne)
|
||||
{
|
||||
AZ_Error("AnimationImporter", false, "Bone %s has multiple animations. Only 1 animation per bone is supported", currentNode->mName.C_Str());
|
||||
break;
|
||||
}
|
||||
|
||||
const aiAnimation* animation = it->second.first;
|
||||
const ConsolidatedNodeAnim* anim = &it->second.second;
|
||||
|
||||
// We don't currently handle having a different number of keys, with 1 exception:
|
||||
// 1 key is essentially a constant so we do handle that case
|
||||
if ((anim->mNumPositionKeys != anim->mNumRotationKeys && anim->mNumPositionKeys > 1 && anim->mNumRotationKeys > 1) ||
|
||||
(anim->mNumPositionKeys != anim->mNumScalingKeys && anim->mNumPositionKeys > 1 && anim->mNumScalingKeys > 1) ||
|
||||
(anim->mNumRotationKeys != anim->mNumScalingKeys && anim->mNumRotationKeys > 1 && anim->mNumScalingKeys > 1))
|
||||
{
|
||||
AZ_Error("AnimationImporter", false, "Bone Animation with different number of position (%d)/rotation (%d)/scaling (%d) keys not supported",
|
||||
anim->mNumPositionKeys, anim->mNumRotationKeys, anim->mNumScalingKeys);
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
unsigned numAnimationKeys = anim->mNumPositionKeys;
|
||||
|
||||
if (numAnimationKeys <= 1)
|
||||
{
|
||||
numAnimationKeys = AZStd::GetMax(anim->mNumRotationKeys, anim->mNumScalingKeys);
|
||||
}
|
||||
|
||||
auto sampleKeyFrame = [](const auto& keys, unsigned numKeys, double time)
|
||||
{
|
||||
AZ_Error("AnimationImporter", numKeys > 0, "Animation key set must have at least 1 key");
|
||||
|
||||
if (numKeys == 1)
|
||||
{
|
||||
return keys[0].mValue;
|
||||
}
|
||||
|
||||
auto returnValue = keys[0].mValue;
|
||||
|
||||
for (unsigned keyIndex = 0; keyIndex < numKeys; ++keyIndex)
|
||||
{
|
||||
const auto& key = keys[keyIndex];
|
||||
|
||||
// We want to return the key that exactly matches the time if possible, otherwise we'll keep track of the previous time
|
||||
// If we don't find an exact match and end up going past the desired time (or run out of keyframes) then we return the previous key
|
||||
if (key.mTime < time)
|
||||
{
|
||||
returnValue = key.mValue;
|
||||
}
|
||||
else if (key.mTime == time)
|
||||
{
|
||||
return key.mValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
|
||||
AZStd::make_shared<SceneData::GraphData::AnimationData>();
|
||||
createdAnimationData->ReserveKeyFrames(animation->mDuration + 1); // +1 because we start at 0 and the last keyframe is at mDuration instead of mDuration-1
|
||||
createdAnimationData->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
|
||||
|
||||
for (unsigned time = 0; time <= animation->mDuration; ++time)
|
||||
{
|
||||
auto scale = sampleKeyFrame(anim->mScalingKeys, anim->mNumScalingKeys, time);
|
||||
auto position = sampleKeyFrame(anim->mPositionKeys, anim->mNumPositionKeys, time);
|
||||
auto rotation = sampleKeyFrame(anim->mRotationKeys, anim->mNumRotationKeys, time);
|
||||
|
||||
aiMatrix4x4 transform(scale, rotation, position);
|
||||
|
||||
DataTypes::MatrixType animTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(transform);
|
||||
|
||||
context.m_sourceSceneSystem.SwapTransformForUpAxis(animTransform);
|
||||
context.m_sourceSceneSystem.ConvertBoneUnit(animTransform);
|
||||
|
||||
createdAnimationData->AddKeyFrame(animTransform);
|
||||
}
|
||||
|
||||
Containers::SceneGraph::NodeIndex addNode = context.m_scene.GetGraph().AddChild(
|
||||
context.m_currentGraphPosition, nodeName.c_str(), AZStd::move(createdAnimationData));
|
||||
context.m_scene.GetGraph().MakeEndPoint(addNode);
|
||||
|
||||
onlyOne = true;
|
||||
}
|
||||
|
||||
combinedAnimationResult += Events::ProcessingResult::Success;
|
||||
return combinedAnimationResult.GetResult();
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpAnimationImporter::ImportBlendShapeAnimation(
|
||||
AssImpSceneNodeAppendedContext& context,
|
||||
const aiAnimation* animation,
|
||||
const aiMeshMorphAnim* meshMorphAnim,
|
||||
const aiMesh* mesh)
|
||||
{
|
||||
if (meshMorphAnim->mNumKeys == 0)
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
Events::ProcessingResultCombiner combinedAnimationResult;
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
|
||||
// In:
|
||||
// Key index
|
||||
// Time
|
||||
// Values in AssImp, Channel in FBX SDK
|
||||
// Weights in AssImp, Values in FBX SDK
|
||||
// Num values & weights
|
||||
|
||||
// Out:
|
||||
// One BlendShapeAnimationData per value (Channel in FBX SDK) index
|
||||
// SetTimeStepBetweenFrames set on the animation data
|
||||
// Keyframes. Weights (Values in FBX SDK) per key time.
|
||||
// Keyframes generated for every single frame of the animation.
|
||||
|
||||
// Helper class to store key data, when translating from AssImp layout to the engine's scene format.
|
||||
struct KeyData
|
||||
{
|
||||
KeyData(float weight, float time) :
|
||||
m_weight(weight),
|
||||
m_time(time)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool operator<(const KeyData& other) const
|
||||
{
|
||||
return m_time < other.m_time;
|
||||
}
|
||||
|
||||
// Naming in the previous SDK (FBX SDK) and in the engine's scene format
|
||||
// doesn't match AssImp's naming convention.
|
||||
// weight here is the AssImp's name for the data, it was named value in FBX SDK.
|
||||
float m_weight = 0;
|
||||
float m_time = 0;
|
||||
};
|
||||
typedef AZStd::map<int, AZStd::vector<KeyData>> ValueToKeyDataMap;
|
||||
ValueToKeyDataMap valueToKeyDataMap;
|
||||
|
||||
for (int keyIdx = 0; keyIdx < meshMorphAnim->mNumKeys; keyIdx++)
|
||||
{
|
||||
aiMeshMorphKey& key = meshMorphAnim->mKeys[keyIdx];
|
||||
for (int valIdx = 0; valIdx < key.mNumValuesAndWeights; ++valIdx)
|
||||
{
|
||||
int currentValue = key.mValues[valIdx];
|
||||
KeyData thisKey(key.mWeights[valIdx], key.mTime);
|
||||
valueToKeyDataMap[currentValue].insert(
|
||||
AZStd::upper_bound(valueToKeyDataMap[currentValue].begin(), valueToKeyDataMap[currentValue].end(),thisKey),
|
||||
thisKey);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [meshIdx, keys] : valueToKeyDataMap)
|
||||
{
|
||||
AZStd::shared_ptr<SceneData::GraphData::BlendShapeAnimationData> morphAnimNode =
|
||||
AZStd::make_shared<SceneData::GraphData::BlendShapeAnimationData>();
|
||||
morphAnimNode->ReserveKeyFrames(animation->mDuration + 1);
|
||||
morphAnimNode->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
|
||||
|
||||
aiAnimMesh* aiAnimMesh = mesh->mAnimMeshes[meshIdx];
|
||||
AZStd::string_view nodeName(aiAnimMesh->mName.C_Str());
|
||||
|
||||
const unsigned maxKeys = keys.size();
|
||||
unsigned keyIdx = 0;
|
||||
for (unsigned time = 0; time <= animation->mDuration; ++time)
|
||||
{
|
||||
if (keyIdx < maxKeys - 1 && time >= keys[keyIdx+1].m_time)
|
||||
{
|
||||
++keyIdx;
|
||||
}
|
||||
float weight_value = keys[keyIdx].m_weight;
|
||||
if (keyIdx < maxKeys - 1)
|
||||
{
|
||||
float nextWeight = keys[keyIdx+1].m_weight;
|
||||
float normalizedTimeBetweenFrames = 0;
|
||||
|
||||
if (keys[keyIdx + 1].m_time != keys[keyIdx].m_time)
|
||||
{
|
||||
normalizedTimeBetweenFrames =
|
||||
(time - keys[keyIdx].m_time) / (keys[keyIdx + 1].m_time - keys[keyIdx].m_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("AnimationImporter", false,
|
||||
"Morph target mesh %s has keys with duplicate time, at indices %d and %d. The second will be ignored.",
|
||||
nodeName.data(),
|
||||
keyIdx,
|
||||
keyIdx+1);
|
||||
}
|
||||
|
||||
// AssImp and FBX both only support linear interpolation for blend shapes.
|
||||
weight_value = AZ::Lerp(weight_value, nextWeight, normalizedTimeBetweenFrames);
|
||||
}
|
||||
morphAnimNode->AddKeyFrame(weight_value);
|
||||
}
|
||||
|
||||
|
||||
const size_t dotIndex = nodeName.find_last_of('.');
|
||||
nodeName = nodeName.substr(dotIndex + 1);
|
||||
|
||||
morphAnimNode->SetBlendShapeName(nodeName.data());
|
||||
|
||||
AZStd::string animNodeName(AZStd::string::format("%s_%s", s_animationNodeName, nodeName.data()));
|
||||
Containers::SceneGraph::NodeIndex addNode = context.m_scene.GetGraph().AddChild(
|
||||
context.m_currentGraphPosition, animNodeName.c_str(), AZStd::move(morphAnimNode));
|
||||
context.m_scene.GetGraph().MakeEndPoint(addNode);
|
||||
|
||||
}
|
||||
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
|
||||
struct aiAnimation;
|
||||
struct aiMesh;
|
||||
struct aiMeshMorphAnim;
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpAnimationImporter
|
||||
: public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpAnimationImporter, "{93b3f4e3-6fcd-42b9-a74e-5923f76d25c7}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpAnimationImporter();
|
||||
~AssImpAnimationImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportAnimation(AssImpSceneNodeAppendedContext& context);
|
||||
Events::ProcessingResult ImportBlendShapeAnimation(
|
||||
AssImpSceneNodeAppendedContext& context,
|
||||
const aiAnimation* animation,
|
||||
const aiMeshMorphAnim* meshMorphAnim,
|
||||
const aiMesh* mesh);
|
||||
|
||||
protected:
|
||||
static const char* s_animationNodeName;
|
||||
static const FbxSDKWrapper::FbxTimeWrapper::TimeMode s_defaultTimeMode;
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBitangentStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/mesh.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
const char* AssImpBitangentStreamImporter::m_defaultNodeName = "Bitangent";
|
||||
|
||||
AssImpBitangentStreamImporter::AssImpBitangentStreamImporter()
|
||||
{
|
||||
BindToCall(&AssImpBitangentStreamImporter::ImportBitangentStreams);
|
||||
}
|
||||
|
||||
void AssImpBitangentStreamImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpBitangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpBitangentStreamImporter::ImportBitangentStreams(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", m_defaultNodeName);
|
||||
if (!context.m_sourceNode.ContainsMesh())
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct bitangent stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
size_t vertexCount = parentMeshData->GetVertexCount();
|
||||
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
if (sdkMeshIndex < 0 || sdkMeshIndex >= currentNode->mNumMeshes)
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct bitangent stream attribute for invalid or non-mesh parent data, mesh index is invalid");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
|
||||
|
||||
if (!mesh->HasTangentsAndBitangents())
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::MeshVertexBitangentData> bitangentStream =
|
||||
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexBitangentData>();
|
||||
|
||||
// AssImp only has one bitangentStream per mesh.
|
||||
bitangentStream->SetBitangentSetIndex(0);
|
||||
|
||||
bitangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
bitangentStream->ReserveContainerSpace(vertexCount);
|
||||
|
||||
for (int v = 0; v < mesh->mNumVertices; ++v)
|
||||
{
|
||||
const Vector3 bitangent(
|
||||
AssImpSDKWrapper::AssImpTypeConverter::ToVector3(mesh->mBitangents[v]));
|
||||
bitangentStream->AppendBitangent(bitangent);
|
||||
}
|
||||
|
||||
AZStd::string nodeName(AZStd::string::format("%s",m_defaultNodeName));
|
||||
Containers::SceneGraph::NodeIndex newIndex =
|
||||
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
|
||||
|
||||
Events::ProcessingResult bitangentResults;
|
||||
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, bitangentStream, newIndex, nodeName.c_str());
|
||||
bitangentResults = Events::Process(dataPopulated);
|
||||
|
||||
if (bitangentResults != Events::ProcessingResult::Failure)
|
||||
{
|
||||
bitangentResults = AddAttributeDataNodeWithContexts(dataPopulated);
|
||||
}
|
||||
|
||||
return bitangentResults;
|
||||
}
|
||||
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpBitangentStreamImporter : public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpBitangentStreamImporter, "{49FC818A-956F-43DA-BBAC-73198E0C5A1F}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpBitangentStreamImporter();
|
||||
~AssImpBitangentStreamImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportBitangentStreams(AssImpSceneNodeAppendedContext& context);
|
||||
|
||||
protected:
|
||||
static const char* m_defaultNodeName;
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBlendShapeImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
AssImpBlendShapeImporter::AssImpBlendShapeImporter()
|
||||
{
|
||||
BindToCall(&AssImpBlendShapeImporter::ImportBlendShapes);
|
||||
}
|
||||
|
||||
void AssImpBlendShapeImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpBlendShapeImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpBlendShapeImporter::ImportBlendShapes(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Blend Shapes");
|
||||
int numMesh = context.m_sourceNode.GetAssImpNode()->mNumMeshes;
|
||||
bool animMeshExists = false;
|
||||
for (int idx = 0; idx < numMesh; idx++)
|
||||
{
|
||||
int meshId = context.m_sourceNode.GetAssImpNode()->mMeshes[idx];
|
||||
aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[meshId];
|
||||
if (aiMesh->mNumAnimMeshes)
|
||||
{
|
||||
animMeshExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!animMeshExists)
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
Events::ProcessingResultCombiner combinedBlendShapeResult;
|
||||
|
||||
for (int meshIdx = 0; meshIdx < numMesh; meshIdx++)
|
||||
{
|
||||
int meshId = context.m_sourceNode.GetAssImpNode()->mMeshes[meshIdx];
|
||||
aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[meshId];
|
||||
if (!aiMesh->mNumAnimMeshes)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int animIdx = 0; animIdx < aiMesh->mNumAnimMeshes; animIdx++)
|
||||
{
|
||||
AZStd::shared_ptr<SceneData::GraphData::BlendShapeData> blendShapeData =
|
||||
AZStd::make_shared<SceneData::GraphData::BlendShapeData>();
|
||||
|
||||
aiAnimMesh* aiAnimMesh = aiMesh->mAnimMeshes[animIdx];
|
||||
AZStd::string nodeName(aiAnimMesh->mName.C_Str());
|
||||
size_t dotIndex = nodeName.rfind('.');
|
||||
if (dotIndex != AZStd::string::npos)
|
||||
{
|
||||
nodeName.erase(0, dotIndex + 1);
|
||||
}
|
||||
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition, "BlendShape");
|
||||
AZ_TraceContext("Blend shape name", nodeName);
|
||||
|
||||
int firstMeshVertexIndex = -1;
|
||||
int previousMeshVertexIndex = -1;
|
||||
|
||||
int verticesInMeshFace = 0;
|
||||
|
||||
for (int vertIdx = 0; vertIdx < aiAnimMesh->mNumVertices; ++vertIdx)
|
||||
{
|
||||
AZ::Vector3 vertex(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mVertices[vertIdx]));
|
||||
|
||||
context.m_sourceSceneSystem.SwapVec3ForUpAxis(vertex);
|
||||
context.m_sourceSceneSystem.ConvertUnit(vertex);
|
||||
|
||||
|
||||
AZ::Vector3 normal;
|
||||
if (aiAnimMesh->HasNormals())
|
||||
{
|
||||
normal = AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mNormals[vertIdx]);
|
||||
context.m_sourceSceneSystem.SwapVec3ForUpAxis(normal);
|
||||
normal.NormalizeSafe();
|
||||
}
|
||||
blendShapeData->AddVertex(vertex, normal);
|
||||
blendShapeData->SetVertexIndexToControlPointIndexMap(vertIdx, vertIdx);
|
||||
}
|
||||
|
||||
// aiAnimMesh just has a list of positions for vertices. The face indices are on the original mesh.
|
||||
for (int faceIdx = 0; faceIdx < aiMesh->mNumFaces; ++faceIdx)
|
||||
{
|
||||
aiFace face = aiMesh->mFaces[faceIdx];
|
||||
DataTypes::IBlendShapeData::Face blendFace;
|
||||
if (face.mNumIndices != 3)
|
||||
{
|
||||
// AssImp should have triangulated everything, so if this happens then someone has
|
||||
// probably changed AssImp's import settings. The engine only supports triangles.
|
||||
AZ_Error(
|
||||
Utilities::ErrorWindow, false,
|
||||
"Mesh for node %s has a face with %d vertices, only 3 vertices are supported per face.",
|
||||
nodeName.c_str(),
|
||||
face.mNumIndices);
|
||||
continue;
|
||||
}
|
||||
for (int idx = 0; idx < face.mNumIndices; ++idx)
|
||||
{
|
||||
blendFace.vertexIndex[idx] = face.mIndices[idx];
|
||||
}
|
||||
|
||||
blendShapeData->AddFace(blendFace);
|
||||
}
|
||||
|
||||
// Report problem if no vertex or face converted to MeshData
|
||||
if (blendShapeData->GetVertexCount() <= 0 || blendShapeData->GetFaceCount() <= 0)
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false, "Missing geometry data in blendshape node %s.", nodeName.c_str());
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
Containers::SceneGraph::NodeIndex newIndex =
|
||||
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
|
||||
|
||||
Events::ProcessingResult blendShapeResult;
|
||||
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, blendShapeData, newIndex, nodeName);
|
||||
blendShapeResult = Events::Process(dataPopulated);
|
||||
|
||||
if (blendShapeResult != Events::ProcessingResult::Failure)
|
||||
{
|
||||
blendShapeResult = AddAttributeDataNodeWithContexts(dataPopulated);
|
||||
}
|
||||
combinedBlendShapeResult += blendShapeResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return combinedBlendShapeResult.GetResult();
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpBlendShapeImporter
|
||||
: public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpBlendShapeImporter, "{B0F7174B-9863-4C03-BFB2-83BF29B1A2DD}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpBlendShapeImporter();
|
||||
~AssImpBlendShapeImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportBlendShapes(AssImpSceneNodeAppendedContext& context);
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BoneData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/RootBoneData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
AssImpBoneImporter::AssImpBoneImporter()
|
||||
{
|
||||
BindToCall(&AssImpBoneImporter::ImportBone);
|
||||
}
|
||||
|
||||
void AssImpBoneImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpBoneImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
void EnumBonesInNode(
|
||||
const aiScene* scene, const aiNode* node, AZStd::unordered_map<AZStd::string, aiNode*>& mainBoneList,
|
||||
AZStd::unordered_map<AZStd::string, aiBone*>& boneLookup)
|
||||
{
|
||||
/* From AssImp Documentation
|
||||
a) Create a map or a similar container to store which nodes are necessary for the skeleton. Pre-initialise it for all nodes with a "no".
|
||||
b) For each bone in the mesh:
|
||||
b1) Find the corresponding node in the scene's hierarchy by comparing their names.
|
||||
b2) Mark this node as "yes" in the necessityMap.
|
||||
b3) Mark all of its parents the same way until you 1) find the mesh's node or 2) the parent of the mesh's node.
|
||||
c) Recursively iterate over the node hierarchy
|
||||
c1) If the node is marked as necessary, copy it into the skeleton and check its children
|
||||
c2) If the node is marked as not necessary, skip it and do not iterate over its children.
|
||||
*/
|
||||
|
||||
for (unsigned meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
aiMesh* mesh = scene->mMeshes[node->mMeshes[meshIndex]];
|
||||
|
||||
for (unsigned boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex)
|
||||
{
|
||||
aiBone* bone = mesh->mBones[boneIndex];
|
||||
|
||||
aiNode* boneNode = scene->mRootNode->FindNode(bone->mName);
|
||||
aiNode* boneParent = boneNode->mParent;
|
||||
|
||||
mainBoneList[bone->mName.C_Str()] = boneNode;
|
||||
boneLookup[bone->mName.C_Str()] = bone;
|
||||
|
||||
while (boneParent && boneParent != node && boneParent != node->mParent && boneParent != scene->mRootNode)
|
||||
{
|
||||
mainBoneList[boneParent->mName.C_Str()] = boneParent;
|
||||
|
||||
boneParent = boneParent->mParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnumChildren(
|
||||
const aiScene* scene, const aiNode* node, AZStd::unordered_map<AZStd::string, aiNode*>& mainBoneList,
|
||||
AZStd::unordered_map<AZStd::string, aiBone*>& boneLookup)
|
||||
{
|
||||
EnumBonesInNode(scene, node, mainBoneList, boneLookup);
|
||||
|
||||
for (unsigned childIndex = 0; childIndex < node->mNumChildren; ++childIndex)
|
||||
{
|
||||
const aiNode* child = node->mChildren[childIndex];
|
||||
|
||||
EnumChildren(scene, child, mainBoneList, boneLookup);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpBoneImporter::ImportBone(AssImpNodeEncounteredContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Bone");
|
||||
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
if (IsPivotNode(currentNode->mName))
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
bool isBone = false;
|
||||
|
||||
if (NodeParentIsOfType(context.m_scene.GetGraph(), context.m_currentGraphPosition, DataTypes::IBoneData::TYPEINFO_Uuid()))
|
||||
{
|
||||
isBone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::unordered_map<AZStd::string, aiNode*> mainBoneList;
|
||||
AZStd::unordered_map<AZStd::string, aiBone*> boneLookup;
|
||||
EnumChildren(scene, scene->mRootNode, mainBoneList, boneLookup);
|
||||
|
||||
if (mainBoneList.find(currentNode->mName.C_Str()) != mainBoneList.end())
|
||||
{
|
||||
isBone = true;
|
||||
}
|
||||
|
||||
// If we have an animation, the bones will be listed in there
|
||||
if (!isBone)
|
||||
{
|
||||
for(unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
|
||||
{
|
||||
aiAnimation* animation = scene->mAnimations[animIndex];
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < animation->mNumChannels; ++channelIndex)
|
||||
{
|
||||
aiNodeAnim* nodeAnim = animation->mChannels[channelIndex];
|
||||
|
||||
if (nodeAnim->mNodeName == currentNode->mName)
|
||||
{
|
||||
isBone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!isBone)
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
// If the current scene node (our eventual parent) contains bone data, we are not a root bone
|
||||
AZStd::shared_ptr<SceneData::GraphData::BoneData> createdBoneData;
|
||||
|
||||
if (NodeHasAncestorOfType(
|
||||
context.m_scene.GetGraph(), context.m_currentGraphPosition, DataTypes::IBoneData::TYPEINFO_Uuid()))
|
||||
{
|
||||
createdBoneData = AZStd::make_shared<SceneData::GraphData::BoneData>();
|
||||
}
|
||||
else
|
||||
{
|
||||
createdBoneData = AZStd::make_shared<SceneData::GraphData::RootBoneData>();
|
||||
}
|
||||
|
||||
aiMatrix4x4 transform = currentNode->mTransformation;
|
||||
aiNode* parent = currentNode->mParent;
|
||||
|
||||
while (parent)
|
||||
{
|
||||
transform = parent->mTransformation * transform;
|
||||
parent = parent->mParent;
|
||||
}
|
||||
|
||||
SceneAPI::DataTypes::MatrixType globalTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(transform);
|
||||
|
||||
context.m_sourceSceneSystem.SwapTransformForUpAxis(globalTransform);
|
||||
context.m_sourceSceneSystem.ConvertBoneUnit(globalTransform);
|
||||
|
||||
createdBoneData->SetWorldTransform(globalTransform);
|
||||
|
||||
context.m_createdData.push_back(AZStd::move(createdBoneData));
|
||||
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpBoneImporter
|
||||
: public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpBoneImporter, "{E7A62DE7-B660-4920-BF91-32738175D5A7}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpBoneImporter();
|
||||
~AssImpBoneImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportBone(AssImpNodeEncounteredContext& context);
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -58,11 +58,10 @@ namespace AZ
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
AZ_Assert(
|
||||
parentData && parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()),
|
||||
"Tried to construct color stream attribute for invalid or non-mesh parent data");
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct color stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
@@ -71,9 +70,7 @@ namespace AZ
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
if (sdkMeshIndex < 0)
|
||||
{
|
||||
AZ_Error(
|
||||
Utilities::ErrorWindow,
|
||||
false,
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct color stream attribute for invalid or non-mesh parent data, mesh index is missing");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
bool IsSkinnedMesh(const aiNode& node, const aiScene& scene)
|
||||
{
|
||||
unsigned boneCount = 0;
|
||||
|
||||
for (unsigned mesh = 0; mesh < node.mNumMeshes; ++mesh)
|
||||
{
|
||||
if (scene.mMeshes[node.mMeshes[mesh]]->HasBones())
|
||||
{
|
||||
++boneCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (boneCount > 1 && boneCount != node.mNumMeshes)
|
||||
{
|
||||
AZ_Error("AssImpImporterUtilities", false, "Node has %d meshes but only %d are skinned. "
|
||||
"This is unexpected and may result in errors", node.mNumMeshes, boneCount);
|
||||
}
|
||||
|
||||
return boneCount > 0;
|
||||
}
|
||||
|
||||
bool IsPivotNode(const aiString& nodeName, size_t* pos)
|
||||
{
|
||||
AZStd::string_view name(nodeName.C_Str(), nodeName.length);
|
||||
|
||||
size_t myPos;
|
||||
|
||||
if (!pos)
|
||||
{
|
||||
pos = &myPos;
|
||||
}
|
||||
|
||||
*pos = AZ::StringFunc::Find(name, PivotNodeMarker);
|
||||
|
||||
return *pos != name.npos;
|
||||
}
|
||||
|
||||
void SplitPivotNodeName(const aiString& nodeName, size_t pivotPos, AZStd::string_view& baseNodeName, AZStd::string_view& pivotType)
|
||||
{
|
||||
AZStd::string_view nodeNameView(nodeName.data, nodeName.length);
|
||||
baseNodeName = AZStd::string_view(nodeNameView.substr(0, pivotPos));
|
||||
pivotType = AZStd::string_view(nodeNameView.substr(pivotPos + sizeof PivotNodeMarker - 1));
|
||||
}
|
||||
|
||||
aiMatrix4x4 GetConcatenatedLocalTransform(const aiNode* currentNode)
|
||||
{
|
||||
aiNode* parent = currentNode->mParent;
|
||||
aiMatrix4x4 combinedTransform = currentNode->mTransformation;
|
||||
|
||||
while (parent)
|
||||
{
|
||||
size_t pos;
|
||||
|
||||
if (IsPivotNode(parent->mName, &pos))
|
||||
{
|
||||
combinedTransform = parent->mTransformation * combinedTransform;
|
||||
parent = parent->mParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return combinedTransform;
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assimp/matrix4x4.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
struct aiNode;
|
||||
struct aiScene;
|
||||
struct aiString;
|
||||
|
||||
|
||||
namespace AZ::SceneAPI::FbxSceneBuilder
|
||||
{
|
||||
inline constexpr char PivotNodeMarker[] = "_$AssimpFbx$_";
|
||||
|
||||
bool IsSkinnedMesh(const aiNode& node, const aiScene& scene);
|
||||
|
||||
// Checks if a node name is a pivot node and optionally returns the position in the name of the pivot marker (for splitting out the parts later)
|
||||
bool IsPivotNode(const aiString& nodeName, size_t* pos = nullptr);
|
||||
|
||||
// Returns the bone name and type of a pivot node
|
||||
void SplitPivotNodeName(const aiString& nodeName, size_t pivotPos, AZStd::string_view& baseNodeName, AZStd::string_view& pivotType);
|
||||
|
||||
// Gets the entire, combined local transform for a node taking pivot nodes into account. When pivot nodes are not used, this just returns the node's transform
|
||||
aiMatrix4x4 GetConcatenatedLocalTransform(const aiNode* currentNode);
|
||||
} // namespace AZ
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
*/
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMaterialImporter.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
@@ -54,6 +56,8 @@ namespace AZ
|
||||
}
|
||||
|
||||
Events::ProcessingResultCombiner combinedMaterialImportResults;
|
||||
|
||||
AZStd::unordered_map<int, AZStd::shared_ptr<SceneData::GraphData::MaterialData>> materialMap;
|
||||
for (int idx = 0; idx < context.m_sourceNode.m_assImpNode->mNumMeshes; ++idx)
|
||||
{
|
||||
int meshIndex = context.m_sourceNode.m_assImpNode->mMeshes[idx];
|
||||
@@ -62,8 +66,6 @@ namespace AZ
|
||||
int materialIndex = assImpMesh->mMaterialIndex;
|
||||
AZ_TraceContext("Material Index", materialIndex);
|
||||
|
||||
AZStd::unordered_map<int, AZStd::shared_ptr<SceneData::GraphData::MaterialData>> materialMap;
|
||||
|
||||
auto matFound = materialMap.find(materialIndex);
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::MaterialData> material;
|
||||
@@ -82,19 +84,58 @@ namespace AZ
|
||||
|
||||
material->SetMaterialName(assImpMaterial->GetName());
|
||||
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Diffuse,
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Diffuse).c_str());
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Diffuse)).c_str());
|
||||
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Specular,
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Specular).c_str());
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Specular)).c_str());
|
||||
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Bump,
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Bump).c_str());
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Bump)).c_str());
|
||||
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Normal,
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Normal).c_str());
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Normal)).c_str());
|
||||
material->SetUniqueId(assImpMaterial->GetUniqueId());
|
||||
material->SetDiffuseColor(assImpMaterial->GetDiffuseColor());
|
||||
material->SetSpecularColor(assImpMaterial->GetSpecularColor());
|
||||
material->SetEmissiveColor(assImpMaterial->GetEmissiveColor());
|
||||
material->SetShininess(assImpMaterial->GetShininess());
|
||||
|
||||
material->SetUseColorMap(assImpMaterial->GetUseColorMap());
|
||||
material->SetBaseColor(assImpMaterial->GetBaseColor());
|
||||
|
||||
material->SetUseMetallicMap(assImpMaterial->GetUseMetallicMap());
|
||||
material->SetMetallicFactor(assImpMaterial->GetMetallicFactor());
|
||||
material->SetTexture(
|
||||
DataTypes::IMaterialData::TextureMapType::Metallic,
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Metallic).c_str()));
|
||||
|
||||
material->SetUseRoughnessMap(assImpMaterial->GetUseRoughnessMap());
|
||||
material->SetRoughnessFactor(assImpMaterial->GetRoughnessFactor());
|
||||
material->SetTexture(
|
||||
DataTypes::IMaterialData::TextureMapType::Roughness,
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Roughness).c_str()));
|
||||
|
||||
material->SetUseEmissiveMap(assImpMaterial->GetUseEmissiveMap());
|
||||
material->SetEmissiveIntensity(assImpMaterial->GetEmissiveIntensity());
|
||||
|
||||
material->SetUseAOMap(assImpMaterial->GetUseAOMap());
|
||||
material->SetTexture(
|
||||
DataTypes::IMaterialData::TextureMapType::AmbientOcclusion,
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::AmbientOcclusion).c_str()));
|
||||
|
||||
material->SetTexture(
|
||||
DataTypes::IMaterialData::TextureMapType::Emissive,
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Emissive).c_str()));
|
||||
|
||||
material->SetTexture(
|
||||
DataTypes::IMaterialData::TextureMapType::BaseColor,
|
||||
ResolveTexturePath(context.m_sourceScene.GetSceneFileName(),
|
||||
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::BaseColor).c_str()));
|
||||
|
||||
AZ_Assert(material, "Failed to allocate scene material data.");
|
||||
if (!material)
|
||||
@@ -135,6 +176,39 @@ namespace AZ
|
||||
|
||||
return combinedMaterialImportResults.GetResult();
|
||||
}
|
||||
|
||||
AZStd::string AssImpMaterialImporter::ResolveTexturePath(const AZStd::string& sceneFilePath, const AZStd::string& textureFilePath) const
|
||||
{
|
||||
if (textureFilePath.empty())
|
||||
{
|
||||
return textureFilePath;
|
||||
}
|
||||
|
||||
|
||||
AZStd::string texturePathRelativeToScene;
|
||||
AZStd::string cleanedUpSceneFilePath(sceneFilePath);
|
||||
AZ::StringFunc::Path::StripFullName(cleanedUpSceneFilePath);
|
||||
AZ::StringFunc::Path::Join(cleanedUpSceneFilePath.c_str(), textureFilePath.c_str(), texturePathRelativeToScene);
|
||||
|
||||
// If the texture did start with marker to change directories upward, then it's relative to the FBX file,
|
||||
// and that path needs to be resolved. It can't be resolved later. This was handled internally by FBX SDK,
|
||||
// but is not handled by AssImp.
|
||||
if (textureFilePath.starts_with(".."))
|
||||
{
|
||||
// Not checking for the file existing because it may not be there yet.
|
||||
return texturePathRelativeToScene;
|
||||
}
|
||||
|
||||
// The engine only supports relative paths to scan folders.
|
||||
// FBX files may have paths to textures, relative to the FBX file. Check for those, first.
|
||||
if (AZ::IO::FileIOBase::GetInstance()->Exists(texturePathRelativeToScene.c_str()))
|
||||
{
|
||||
return texturePathRelativeToScene;
|
||||
}
|
||||
|
||||
|
||||
return textureFilePath;
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace AZ
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportMaterials(AssImpSceneNodeAppendedContext& context);
|
||||
|
||||
private:
|
||||
AZStd::string ResolveTexturePath(const AZStd::string& sceneFilePath, const AZStd::string& textureFilePath) const;
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
|
||||
@@ -9,19 +9,17 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMeshImporter.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMeshImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -46,80 +44,23 @@ namespace AZ
|
||||
Events::ProcessingResult AssImpMeshImporter::ImportMesh(AssImpNodeEncounteredContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Mesh");
|
||||
if (!context.m_sourceNode.ContainsMesh())
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::unordered_map<int, int> assImpMatIndexToLYIndex;
|
||||
int lyMeshIndex = 0;
|
||||
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
for (int m = 0; m < currentNode->mNumMeshes; ++m)
|
||||
if (!context.m_sourceNode.ContainsMesh() || IsSkinnedMesh(*currentNode, *scene))
|
||||
{
|
||||
AZStd::shared_ptr<SceneData::GraphData::MeshData> newMesh =
|
||||
AZStd::make_shared<SceneData::GraphData::MeshData>();
|
||||
|
||||
newMesh->SetUnitSizeInMeters(context.m_sourceSceneSystem.GetUnitSizeInMeters());
|
||||
newMesh->SetOriginalUnitSizeInMeters(context.m_sourceSceneSystem.GetOriginalUnitSizeInMeters());
|
||||
|
||||
newMesh->SetSdkMeshIndex(m);
|
||||
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[m]];
|
||||
|
||||
// Lumberyard materials are created in order based on mesh references in the scene
|
||||
if (assImpMatIndexToLYIndex.find(mesh->mMaterialIndex) == assImpMatIndexToLYIndex.end())
|
||||
{
|
||||
assImpMatIndexToLYIndex.insert(AZStd::pair<int, int>(mesh->mMaterialIndex, lyMeshIndex++));
|
||||
}
|
||||
|
||||
for (int vertIdx = 0; vertIdx < mesh->mNumVertices; ++vertIdx)
|
||||
{
|
||||
AZ::Vector3 vertex(
|
||||
mesh->mVertices[vertIdx].x,
|
||||
mesh->mVertices[vertIdx].y,
|
||||
mesh->mVertices[vertIdx].z);
|
||||
|
||||
context.m_sourceSceneSystem.SwapVec3ForUpAxis(vertex);
|
||||
context.m_sourceSceneSystem.ConvertUnit(vertex);
|
||||
newMesh->AddPosition(vertex);
|
||||
|
||||
if (mesh->HasNormals())
|
||||
{
|
||||
AZ::Vector3 normal(
|
||||
mesh->mNormals[vertIdx].x,
|
||||
mesh->mNormals[vertIdx].y,
|
||||
mesh->mNormals[vertIdx].z);
|
||||
context.m_sourceSceneSystem.SwapVec3ForUpAxis(normal);
|
||||
normal.NormalizeSafe();
|
||||
newMesh->AddNormal(normal);
|
||||
}
|
||||
}
|
||||
|
||||
for (int faceIdx = 0; faceIdx < mesh->mNumFaces; ++faceIdx)
|
||||
{
|
||||
aiFace face = mesh->mFaces[faceIdx];
|
||||
AZ::SceneAPI::DataTypes::IMeshData::Face meshFace;
|
||||
if (face.mNumIndices != 3)
|
||||
{
|
||||
// AssImp should have triangulated everything, so if this happens then someone has
|
||||
// probably changed AssImp's import settings. The engine only supports triangles.
|
||||
AZ_Error(Utilities::ErrorWindow, false, "Mesh has a face with %d vertices, only 3 vertices are supported per face.");
|
||||
continue;
|
||||
}
|
||||
for (int idx = 0; idx < face.mNumIndices; ++idx)
|
||||
{
|
||||
meshFace.vertexIndex[idx] = face.mIndices[idx];
|
||||
}
|
||||
|
||||
newMesh->AddFace(meshFace, assImpMatIndexToLYIndex[mesh->mMaterialIndex]);
|
||||
}
|
||||
|
||||
context.m_createdData.push_back(std::move(newMesh));
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
return Events::ProcessingResult::Success;
|
||||
|
||||
if (BuildSceneMeshFromAssImpMesh(currentNode, scene, context.m_sourceSceneSystem, context.m_createdData, [] {
|
||||
return AZStd::make_shared<SceneData::GraphData::MeshData>();
|
||||
}))
|
||||
{
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
AssImpSkinImporter::AssImpSkinImporter()
|
||||
{
|
||||
BindToCall(&AssImpSkinImporter::ImportSkin);
|
||||
}
|
||||
|
||||
void AssImpSkinImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpSkinImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpSkinImporter::ImportSkin(AssImpNodeEncounteredContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Skin");
|
||||
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
if (!context.m_sourceNode.ContainsMesh() || !IsSkinnedMesh(*currentNode, *scene))
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
if (BuildSceneMeshFromAssImpMesh(currentNode, scene, context.m_sourceSceneSystem, context.m_createdData, [] {
|
||||
return AZStd::make_shared<SceneData::GraphData::SkinMeshData>();
|
||||
}))
|
||||
{
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpSkinImporter
|
||||
: public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpSkinImporter, "{8FBCA725-C04E-42B7-9669-82DB3BB0901F}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpSkinImporter();
|
||||
~AssImpSkinImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportSkin(AssImpNodeEncounteredContext& context);
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinWeightsImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
|
||||
#include <SceneAPI/SceneData/GraphData/SkinWeightData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
const AZStd::string AssImpSkinWeightsImporter::s_skinWeightName = "SkinWeight_";
|
||||
|
||||
AssImpSkinWeightsImporter::AssImpSkinWeightsImporter()
|
||||
{
|
||||
BindToCall(&AssImpSkinWeightsImporter::ImportSkinWeights);
|
||||
BindToCall(&AssImpSkinWeightsImporter::SetupNamedBoneLinks);
|
||||
}
|
||||
|
||||
void AssImpSkinWeightsImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpSkinWeightsImporter::ImportSkinWeights(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Skin Weights");
|
||||
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
if(currentNode->mNumMeshes <= 0)
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
Events::ProcessingResultCombiner combinedSkinWeightsResult;
|
||||
|
||||
for(unsigned m = 0; m < currentNode->mNumMeshes; ++m)
|
||||
{
|
||||
auto mesh = scene->mMeshes[currentNode->mMeshes[m]];
|
||||
|
||||
for(unsigned b = 0; b < mesh->mNumBones; ++b)
|
||||
{
|
||||
auto bone = mesh->mBones[b];
|
||||
|
||||
if(bone->mNumWeights <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AZStd::string skinWeightName = s_skinWeightName;
|
||||
skinWeightName += AZStd::to_string(b);
|
||||
RenamedNodesMap::SanitizeNodeName(skinWeightName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> skinDeformer = BuildSkinWeightData(bone, mesh->mNumVertices);
|
||||
|
||||
Containers::SceneGraph::NodeIndex newIndex =
|
||||
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, skinWeightName.c_str());
|
||||
|
||||
AZ_Error("SkinWeightsImporter", newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
|
||||
if (!newIndex.IsValid())
|
||||
{
|
||||
combinedSkinWeightsResult += Events::ProcessingResult::Failure;
|
||||
continue;
|
||||
}
|
||||
|
||||
Events::ProcessingResult skinWeightsResult;
|
||||
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, skinDeformer, newIndex, skinWeightName);
|
||||
skinWeightsResult = Events::Process(dataPopulated);
|
||||
|
||||
if (skinWeightsResult != Events::ProcessingResult::Failure)
|
||||
{
|
||||
skinWeightsResult = AddAttributeDataNodeWithContexts(dataPopulated);
|
||||
}
|
||||
|
||||
combinedSkinWeightsResult += skinWeightsResult;
|
||||
}
|
||||
}
|
||||
|
||||
return combinedSkinWeightsResult.GetResult();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> AssImpSkinWeightsImporter::BuildSkinWeightData(aiBone* bone, unsigned numVertices)
|
||||
{
|
||||
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> skinWeightData =
|
||||
AZStd::make_shared<SceneData::GraphData::SkinWeightData>();
|
||||
|
||||
// Cache the new object and the link info for now so it can be resolved at a later point when all
|
||||
// names have been updated.
|
||||
Pending pending;
|
||||
pending.m_bone = bone;
|
||||
pending.m_numVertices = numVertices;
|
||||
pending.m_skinWeightData = skinWeightData;
|
||||
m_pendingSkinWeights.push_back(pending);
|
||||
|
||||
return skinWeightData;
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpSkinWeightsImporter::SetupNamedBoneLinks(AssImpFinalizeSceneContext& /*context*/)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Skin Weights");
|
||||
|
||||
for (auto& it : m_pendingSkinWeights)
|
||||
{
|
||||
it.m_skinWeightData->ResizeContainerSpace(it.m_numVertices);
|
||||
|
||||
AZStd::string boneName = it.m_bone->mName.C_Str();
|
||||
int boneId = it.m_skinWeightData->GetBoneId(boneName);
|
||||
|
||||
for(unsigned weight = 0; weight < it.m_bone->mNumWeights; ++weight)
|
||||
{
|
||||
DataTypes::ISkinWeightData::Link link;
|
||||
link.boneId = boneId;
|
||||
link.weight = it.m_bone->mWeights[weight].mWeight;
|
||||
|
||||
it.m_skinWeightData->AppendLink(it.m_bone->mWeights[weight].mVertexId, link);
|
||||
}
|
||||
}
|
||||
const auto result = m_pendingSkinWeights.empty() ? Events::ProcessingResult::Ignored : Events::ProcessingResult::Success;
|
||||
m_pendingSkinWeights.clear();
|
||||
return result;
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/ISkinWeightData.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace FbxSDKWrapper
|
||||
{
|
||||
class FbxMeshWrapper;
|
||||
}
|
||||
|
||||
namespace SceneData
|
||||
{
|
||||
namespace GraphData
|
||||
{
|
||||
class SkinWeightData;
|
||||
}
|
||||
}
|
||||
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace Events
|
||||
{
|
||||
class PostImportEventContext;
|
||||
}
|
||||
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpSkinWeightsImporter
|
||||
: public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpSkinWeightsImporter, "{79B5E863-C155-473A-BC0D-B85F8D8303EB}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpSkinWeightsImporter();
|
||||
~AssImpSkinWeightsImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportSkinWeights(AssImpSceneNodeAppendedContext& context);
|
||||
Events::ProcessingResult SetupNamedBoneLinks(AssImpFinalizeSceneContext& context);
|
||||
|
||||
protected:
|
||||
struct Pending
|
||||
{
|
||||
aiBone* m_bone = nullptr;
|
||||
unsigned m_numVertices = 0;
|
||||
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> m_skinWeightData;
|
||||
};
|
||||
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> BuildSkinWeightData(aiBone* bone, unsigned numVertices);
|
||||
|
||||
//! List of skin weights that still need to be filled in. Setting the data for skin weights is
|
||||
//! delayed until after the tree has been fully constructed as bones are linked by name, but until
|
||||
//! the graph has been fully filled in, those names can change which would break the names recorded
|
||||
//! for the skin.
|
||||
AZStd::vector<Pending> m_pendingSkinWeights;
|
||||
|
||||
static const AZStd::string s_skinWeightName;
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTangentStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/mesh.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
const char* AssImpTangentStreamImporter::m_defaultNodeName = "Tangent";
|
||||
|
||||
AssImpTangentStreamImporter::AssImpTangentStreamImporter()
|
||||
{
|
||||
BindToCall(&AssImpTangentStreamImporter::ImportTangentStreams);
|
||||
}
|
||||
|
||||
void AssImpTangentStreamImporter::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpTangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpTangentStreamImporter::ImportTangentStreams(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", m_defaultNodeName);
|
||||
if (!context.m_sourceNode.ContainsMesh())
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct tangent stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
size_t vertexCount = parentMeshData->GetVertexCount();
|
||||
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
if (sdkMeshIndex < 0 || sdkMeshIndex >= currentNode->mNumMeshes)
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct tangent stream attribute for invalid or non-mesh parent data, mesh index is invalid");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
|
||||
|
||||
if (!mesh->HasTangentsAndBitangents())
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::MeshVertexTangentData> tangentStream =
|
||||
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexTangentData>();
|
||||
|
||||
// AssImp only has one tangentStream per mesh.
|
||||
tangentStream->SetTangentSetIndex(0);
|
||||
|
||||
tangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
|
||||
tangentStream->ReserveContainerSpace(vertexCount);
|
||||
|
||||
for (int v = 0; v < mesh->mNumVertices; ++v)
|
||||
{
|
||||
// Vector4's constructor that takes in a vector3 sets w to 1.0f automatically.
|
||||
const Vector4 tangent(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(mesh->mTangents[v]));
|
||||
tangentStream->AppendTangent(tangent);
|
||||
}
|
||||
|
||||
AZStd::string nodeName(AZStd::string::format("%s", m_defaultNodeName));
|
||||
Containers::SceneGraph::NodeIndex newIndex =
|
||||
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
|
||||
|
||||
Events::ProcessingResult tangentResults;
|
||||
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, tangentStream, newIndex, nodeName.c_str());
|
||||
tangentResults = Events::Process(dataPopulated);
|
||||
|
||||
if (tangentResults != Events::ProcessingResult::Failure)
|
||||
{
|
||||
tangentResults = AddAttributeDataNodeWithContexts(dataPopulated);
|
||||
}
|
||||
|
||||
return tangentResults;
|
||||
}
|
||||
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
class AssImpTangentStreamImporter : public SceneCore::LoadingComponent
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AssImpTangentStreamImporter, "{AB2D1D1E-5A19-40AF-B4F4-C652DD578F43}", SceneCore::LoadingComponent);
|
||||
|
||||
AssImpTangentStreamImporter();
|
||||
~AssImpTangentStreamImporter() override = default;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
Events::ProcessingResult ImportTangentStreams(AssImpSceneNodeAppendedContext& context);
|
||||
|
||||
protected:
|
||||
static const char* m_defaultNodeName;
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -45,16 +46,25 @@ namespace AZ
|
||||
serializeContext->Class<AssImpTransformImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Events::ProcessingResult AssImpTransformImporter::ImportTransform(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "transform");
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
if (currentNode == scene->mRootNode || IsPivotNode(currentNode->mName))
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(context.m_sourceNode.GetAssImpNode()->mTransformation);
|
||||
aiMatrix4x4 combinedTransform = GetConcatenatedLocalTransform(currentNode);
|
||||
|
||||
DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform);
|
||||
|
||||
context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform);
|
||||
context.m_sourceSceneSystem.ConvertUnit(localTransform);
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::TransformData> transformData =
|
||||
AZStd::make_shared<SceneData::GraphData::TransformData>(localTransform);
|
||||
AZ_Error(SceneAPI::Utilities::ErrorWindow, transformData, "Failed to allocate transform data.");
|
||||
@@ -63,7 +73,6 @@ namespace AZ
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
|
||||
// If it is non-endpoint data populated node, add a transform attribute
|
||||
if (context.m_scene.GetGraph().HasNodeContent(context.m_currentGraphPosition))
|
||||
{
|
||||
|
||||
@@ -59,10 +59,10 @@ namespace AZ
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
AZ_Assert(parentData && parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()),
|
||||
"Tried to construct uv stream attribute for invalid or non-mesh parent data");
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct uv stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData =
|
||||
@@ -75,40 +75,44 @@ namespace AZ
|
||||
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
|
||||
|
||||
if (!mesh->mTextureCoords[0])
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
Events::ProcessingResultCombiner combinedUvMapResults;
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> uvMap =
|
||||
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexUVData>();
|
||||
uvMap->ReserveContainerSpace(vertexCount);
|
||||
uvMap->SetCustomName(m_defaultNodeName);
|
||||
|
||||
for (int v = 0; v < mesh->mNumVertices; ++v)
|
||||
for (int texCoordIndex = 0; texCoordIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++texCoordIndex)
|
||||
{
|
||||
AZ::Vector2 vertexUV(
|
||||
mesh->mTextureCoords[0][v].x,
|
||||
mesh->mTextureCoords[0][v].y);
|
||||
uvMap->AppendUV(vertexUV);
|
||||
if (!mesh->mTextureCoords[texCoordIndex])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> uvMap =
|
||||
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexUVData>();
|
||||
uvMap->ReserveContainerSpace(vertexCount);
|
||||
AZStd::string name(AZStd::string::format("%s%d", m_defaultNodeName, texCoordIndex));
|
||||
uvMap->SetCustomName(name.c_str());
|
||||
|
||||
for (int v = 0; v < mesh->mNumVertices; ++v)
|
||||
{
|
||||
AZ::Vector2 vertexUV(
|
||||
mesh->mTextureCoords[texCoordIndex][v].x,
|
||||
// The engine's V coordinate is reverse of how it's stored in the FBX file.
|
||||
1.0f - mesh->mTextureCoords[texCoordIndex][v].y);
|
||||
uvMap->AppendUV(vertexUV);
|
||||
}
|
||||
|
||||
Containers::SceneGraph::NodeIndex newIndex =
|
||||
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, name.c_str());
|
||||
|
||||
Events::ProcessingResult uvMapResults;
|
||||
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, uvMap, newIndex, name);
|
||||
uvMapResults = Events::Process(dataPopulated);
|
||||
|
||||
if (uvMapResults != Events::ProcessingResult::Failure)
|
||||
{
|
||||
uvMapResults = AddAttributeDataNodeWithContexts(dataPopulated);
|
||||
}
|
||||
|
||||
combinedUvMapResults += uvMapResults;
|
||||
}
|
||||
|
||||
Containers::SceneGraph::NodeIndex newIndex =
|
||||
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, m_defaultNodeName);
|
||||
|
||||
Events::ProcessingResult uvMapResults;
|
||||
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, uvMap, newIndex, m_defaultNodeName);
|
||||
uvMapResults = Events::Process(dataPopulated);
|
||||
|
||||
if (uvMapResults != Events::ProcessingResult::Failure)
|
||||
{
|
||||
uvMapResults = AddAttributeDataNodeWithContexts(dataPopulated);
|
||||
}
|
||||
|
||||
combinedUvMapResults += uvMapResults;
|
||||
|
||||
return combinedUvMapResults.GetResult();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace AZ
|
||||
SceneNodeFinalizeContext finalizeNode(addedAttributes);
|
||||
nodeResults += Events::Process(finalizeNode);
|
||||
}
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
else
|
||||
{
|
||||
AssImpSceneDataPopulatedContext* dataPopulatedContext = azrtti_cast<AssImpSceneDataPopulatedContext*>(&dataPopulated);
|
||||
@@ -75,7 +74,6 @@ namespace AZ
|
||||
AssImpSceneNodeFinalizeContext finalizeNode(addedAttributes);
|
||||
nodeResults += Events::Process(finalizeNode);
|
||||
}
|
||||
#endif
|
||||
|
||||
return nodeResults.GetResult();
|
||||
}
|
||||
@@ -99,14 +97,12 @@ namespace AZ
|
||||
SceneAttributeNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
|
||||
nodeResults += Events::Process(nodeAppended);
|
||||
}
|
||||
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
|
||||
else
|
||||
{
|
||||
AssImpSceneAttributeDataPopulatedContext* dataPopulatedContext = azrtti_cast<AssImpSceneAttributeDataPopulatedContext*>(&dataPopulated);
|
||||
AssImpSceneAttributeNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
|
||||
nodeResults += Events::Process(nodeAppended);
|
||||
}
|
||||
#endif
|
||||
|
||||
return nodeResults.GetResult();
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
|
||||
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
|
||||
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
struct Uuid;
|
||||
|
||||
@@ -79,4 +79,4 @@ namespace AZ
|
||||
}
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
} // namespace AZ
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
|
||||
namespace AZ::SceneAPI::FbxSceneBuilder
|
||||
{
|
||||
bool BuildSceneMeshFromAssImpMesh(aiNode* currentNode, const aiScene* scene, const FbxSceneSystem& sceneSystem, AZStd::vector<AZStd::shared_ptr<DataTypes::IGraphObject>>& meshes,
|
||||
const AZStd::function<AZStd::shared_ptr<SceneData::GraphData::MeshData>()>& makeMeshFunc)
|
||||
{
|
||||
AZStd::unordered_map<int, int> assImpMatIndexToLYIndex;
|
||||
int lyMeshIndex = 0;
|
||||
|
||||
if(!currentNode || !scene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int m = 0; m < currentNode->mNumMeshes; ++m)
|
||||
{
|
||||
auto newMesh = makeMeshFunc();
|
||||
|
||||
newMesh->SetUnitSizeInMeters(sceneSystem.GetUnitSizeInMeters());
|
||||
newMesh->SetOriginalUnitSizeInMeters(sceneSystem.GetOriginalUnitSizeInMeters());
|
||||
|
||||
newMesh->SetSdkMeshIndex(m);
|
||||
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[m]];
|
||||
|
||||
// Lumberyard materials are created in order based on mesh references in the scene
|
||||
if (assImpMatIndexToLYIndex.find(mesh->mMaterialIndex) == assImpMatIndexToLYIndex.end())
|
||||
{
|
||||
assImpMatIndexToLYIndex.insert(AZStd::pair<int, int>(mesh->mMaterialIndex, lyMeshIndex++));
|
||||
}
|
||||
|
||||
for (int vertIdx = 0; vertIdx < mesh->mNumVertices; ++vertIdx)
|
||||
{
|
||||
AZ::Vector3 vertex(mesh->mVertices[vertIdx].x, mesh->mVertices[vertIdx].y, mesh->mVertices[vertIdx].z);
|
||||
|
||||
sceneSystem.SwapVec3ForUpAxis(vertex);
|
||||
sceneSystem.ConvertUnit(vertex);
|
||||
newMesh->AddPosition(vertex);
|
||||
newMesh->SetVertexIndexToControlPointIndexMap(vertIdx, vertIdx);
|
||||
|
||||
if (mesh->HasNormals())
|
||||
{
|
||||
AZ::Vector3 normal(mesh->mNormals[vertIdx].x, mesh->mNormals[vertIdx].y, mesh->mNormals[vertIdx].z);
|
||||
sceneSystem.SwapVec3ForUpAxis(normal);
|
||||
normal.NormalizeSafe();
|
||||
newMesh->AddNormal(normal);
|
||||
}
|
||||
}
|
||||
|
||||
for (int faceIdx = 0; faceIdx < mesh->mNumFaces; ++faceIdx)
|
||||
{
|
||||
aiFace face = mesh->mFaces[faceIdx];
|
||||
AZ::SceneAPI::DataTypes::IMeshData::Face meshFace;
|
||||
if (face.mNumIndices != 3)
|
||||
{
|
||||
// AssImp should have triangulated everything, so if this happens then someone has
|
||||
// probably changed AssImp's import settings. The engine only supports triangles.
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Mesh on node %s has a face with %d vertices, only 3 vertices are supported per face.",
|
||||
currentNode->mName.C_Str(),
|
||||
face.mNumIndices);
|
||||
continue;
|
||||
}
|
||||
for (int idx = 0; idx < face.mNumIndices; ++idx)
|
||||
{
|
||||
meshFace.vertexIndex[idx] = face.mIndices[idx];
|
||||
}
|
||||
|
||||
newMesh->AddFace(meshFace, assImpMatIndexToLYIndex[mesh->mMaterialIndex]);
|
||||
}
|
||||
|
||||
meshes.push_back(newMesh);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct aiNode;
|
||||
struct aiScene;
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace FbxSDKWrapper
|
||||
{
|
||||
class FbxMeshWrapper;
|
||||
}
|
||||
|
||||
namespace SceneData
|
||||
{
|
||||
namespace GraphData
|
||||
{
|
||||
class MeshData;
|
||||
class BlendShapeData;
|
||||
}
|
||||
}
|
||||
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace DataTypes
|
||||
{
|
||||
class IGraphObject;
|
||||
}
|
||||
|
||||
class FbxSceneSystem;
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
bool BuildSceneMeshFromAssImpMesh(aiNode* currentNode, const aiScene* scene, const FbxSceneSystem& sceneSystem, AZStd::vector<AZStd::shared_ptr<DataTypes::IGraphObject>>& meshes,
|
||||
const AZStd::function<AZStd::shared_ptr<SceneData::GraphData::MeshData>()>& makeMeshFunc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,16 +10,4 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
../../ImportContexts/AssImpImportContexts.h
|
||||
../../ImportContexts/AssImpImportContexts.cpp
|
||||
../../Importers/AssImpColorStreamImporter.h
|
||||
../../Importers/AssImpColorStreamImporter.cpp
|
||||
../../Importers/AssImpMaterialImporter.h
|
||||
../../Importers/AssImpMaterialImporter.cpp
|
||||
../../Importers/AssImpMeshImporter.h
|
||||
../../Importers/AssImpMeshImporter.cpp
|
||||
../../Importers/AssImpUvMapImporter.h
|
||||
../../Importers/AssImpUvMapImporter.cpp
|
||||
../../Importers/AssImpTransformImporter.h
|
||||
../../Importers/AssImpTransformImporter.cpp
|
||||
)
|
||||
|
||||
@@ -21,6 +21,8 @@ set(FILES
|
||||
ImportContexts/ImportContexts.cpp
|
||||
ImportContexts/FbxImportContexts.h
|
||||
ImportContexts/FbxImportContexts.cpp
|
||||
ImportContexts/AssImpImportContexts.h
|
||||
ImportContexts/AssImpImportContexts.cpp
|
||||
Importers/FbxAnimationImporter.h
|
||||
Importers/FbxAnimationImporter.cpp
|
||||
Importers/FbxBoneImporter.h
|
||||
@@ -50,6 +52,36 @@ set(FILES
|
||||
Importers/FbxUvMapImporter.cpp
|
||||
Importers/Utilities/FbxMeshImporterUtilities.h
|
||||
Importers/Utilities/FbxMeshImporterUtilities.cpp
|
||||
Importers/Utilities/AssImpMeshImporterUtilities.h
|
||||
Importers/Utilities/AssImpMeshImporterUtilities.cpp
|
||||
Importers/Utilities/RenamedNodesMap.h
|
||||
Importers/Utilities/RenamedNodesMap.cpp
|
||||
Importers/AssImpAnimationImporter.h
|
||||
Importers/AssImpAnimationImporter.cpp
|
||||
Importers/AssImpBitangentStreamImporter.h
|
||||
Importers/AssImpBitangentStreamImporter.cpp
|
||||
Importers/AssImpBlendShapeImporter.h
|
||||
Importers/AssImpBlendShapeImporter.cpp
|
||||
Importers/AssImpBoneImporter.h
|
||||
Importers/AssImpBoneImporter.cpp
|
||||
Importers/AssImpColorStreamImporter.h
|
||||
Importers/AssImpColorStreamImporter.cpp
|
||||
Importers/AssImpImporterUtilities.h
|
||||
Importers/AssImpImporterUtilities.cpp
|
||||
Importers/AssImpMaterialImporter.h
|
||||
Importers/AssImpMaterialImporter.cpp
|
||||
Importers/AssImpMeshImporter.h
|
||||
Importers/AssImpMeshImporter.cpp
|
||||
Importers/AssImpSkinImporter.h
|
||||
Importers/AssImpSkinImporter.cpp
|
||||
Importers/AssImpSkinWeightsImporter.h
|
||||
Importers/AssImpSkinWeightsImporter.cpp
|
||||
Importers/AssImpTangentStreamImporter.h
|
||||
Importers/AssImpTangentStreamImporter.cpp
|
||||
Importers/AssImpTransformImporter.h
|
||||
Importers/AssImpTransformImporter.cpp
|
||||
Importers/AssImpUvMapImporter.h
|
||||
Importers/AssImpUvMapImporter.cpp
|
||||
Importers/AssImpAnimationImporter.h
|
||||
Importers/AssImpAnimationImporter.cpp
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user