Merge branch 'main' into TIF/Runtime
This commit is contained in:
@@ -15,14 +15,14 @@ android {
|
||||
${SIGNING_CONFIGS}
|
||||
compileSdkVersion sdkVer
|
||||
buildToolsVersion buildToolsVer
|
||||
|
||||
ndkVersion ndkPlatformVer
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion ndkPlatformVer
|
||||
minSdkVersion minSdkVer
|
||||
targetSdkVersion sdkVer
|
||||
${NATIVE_CMAKE_SECTION_DEFAULT_CONFIG}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,5 @@
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
# ${GENERATION_TIMESTAMP}
|
||||
ndk.dir=${ANDROID_NDK_PATH}
|
||||
sdk.dir=${ANDROID_SDK_PATH}
|
||||
${CMAKE_DIR_LINE}
|
||||
|
||||
@@ -12,10 +12,9 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.4'
|
||||
classpath 'com.android.tools.build:gradle:${ANDROID_GRADLE_PLUGIN_VERSION}'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@@ -26,14 +25,14 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
ext {
|
||||
minSdkVer = ${MIN_SDK_VER}
|
||||
sdkVer = ${SDK_VER}
|
||||
ndkPlatformVer = ${NDK_PLATFORM_VER}
|
||||
ndkPlatformVer = '${NDK_VERSION}'
|
||||
buildToolsVer = '${SDK_BUILD_TOOL_VER}'
|
||||
lyEngineRoot = '${LY_ENGINE_ROOT}'
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"AssetProcessor": {
|
||||
"Settings": {
|
||||
"Platforms": {
|
||||
"es3": "enabled"
|
||||
"android": "enabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzToolsFramework/Asset/AssetBundler.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistryImpl.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
|
||||
@@ -57,6 +58,22 @@ namespace AssetBundler
|
||||
UnitTest::ScopedAllocatorSetupFixture::SetUp();
|
||||
m_data = AZStd::make_unique<StaticData>();
|
||||
|
||||
AZ::SettingsRegistryInterface* registry = nullptr;
|
||||
if (!AZ::SettingsRegistry::Get())
|
||||
{
|
||||
AZ::SettingsRegistry::Register(&m_registry);
|
||||
registry = &m_registry;
|
||||
}
|
||||
else
|
||||
{
|
||||
registry = AZ::SettingsRegistry::Get();
|
||||
}
|
||||
auto projectPathKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
|
||||
+ "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
|
||||
m_data->m_applicationManager.reset(aznew MockApplicationManagerTest(0, 0));
|
||||
m_data->m_applicationManager->Start(AzFramework::Application::Descriptor());
|
||||
|
||||
@@ -84,6 +101,12 @@ namespace AssetBundler
|
||||
delete m_data->m_localFileIO;
|
||||
AZ::IO::FileIOBase::SetInstance(m_data->m_priorFileIO);
|
||||
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
if(settingsRegistry == &m_registry)
|
||||
{
|
||||
AZ::SettingsRegistry::Unregister(settingsRegistry);
|
||||
}
|
||||
|
||||
m_data->m_applicationManager->Stop();
|
||||
m_data->m_applicationManager.reset();
|
||||
m_data.reset();
|
||||
@@ -99,6 +122,7 @@ namespace AssetBundler
|
||||
};
|
||||
|
||||
AZStd::unique_ptr<StaticData> m_data;
|
||||
AZ::SettingsRegistryImpl m_registry;
|
||||
};
|
||||
|
||||
TEST_F(ApplicationManagerTest, ValidatePlatformFlags_ReadConfigFiles_OK)
|
||||
@@ -126,7 +150,7 @@ namespace AssetBundler
|
||||
|
||||
AzFramework::PlatformFlags platformFlags = GetEnabledPlatformFlags(m_data->m_testEngineRoot.c_str(), m_data->m_testEngineRoot.c_str(), DummyProjectName);
|
||||
AzFramework::PlatformFlags hostPlatformFlag = AzFramework::PlatformHelper::GetPlatformFlag(AzToolsFramework::AssetSystem::GetHostAssetPlatform());
|
||||
AzFramework::PlatformFlags expectedFlags = AzFramework::PlatformFlags::Platform_ES3 | AzFramework::PlatformFlags::Platform_IOS | AzFramework::PlatformFlags::Platform_PROVO | hostPlatformFlag;
|
||||
AzFramework::PlatformFlags expectedFlags = AzFramework::PlatformFlags::Platform_ANDROID | AzFramework::PlatformFlags::Platform_IOS | AzFramework::PlatformFlags::Platform_PROVO | hostPlatformFlag;
|
||||
ASSERT_EQ(platformFlags, expectedFlags);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@ namespace AssetBundler
|
||||
|
||||
TEST_F(AssetBundlerBatchUtilsTest, SplitFilename_MacFile_OutputBaseNameAndPlatform)
|
||||
{
|
||||
AZStd::string filePath = "assetInfoFile_osx_gl.xml";
|
||||
AZStd::string filePath = "assetInfoFile_mac.xml";
|
||||
AZStd::string baseFilename;
|
||||
AZStd::string platformIdentifier;
|
||||
|
||||
AzToolsFramework::SplitFilename(filePath, baseFilename, platformIdentifier);
|
||||
|
||||
ASSERT_EQ(baseFilename, "assetInfoFile");
|
||||
ASSERT_EQ(platformIdentifier, "osx_gl");
|
||||
ASSERT_EQ(platformIdentifier, "mac");
|
||||
}
|
||||
|
||||
TEST_F(AssetBundlerBatchUtilsTest, SplitFilename_PcFile_OutputBaseNameAndPlatform)
|
||||
@@ -64,14 +64,14 @@ namespace AssetBundler
|
||||
|
||||
TEST_F(AssetBundlerBatchUtilsTest, SplitFilename_MacFileWithUnderScoreInFileName_OutputBaseNameAndPlatform)
|
||||
{
|
||||
AZStd::string filePath = "assetInfoFile_test_osx_gl.xml";
|
||||
AZStd::string filePath = "assetInfoFile_test_mac.xml";
|
||||
AZStd::string baseFilename;
|
||||
AZStd::string platformIdentifier;
|
||||
|
||||
AzToolsFramework::SplitFilename(filePath, baseFilename, platformIdentifier);
|
||||
|
||||
ASSERT_EQ(baseFilename, "assetInfoFile_test");
|
||||
ASSERT_EQ(platformIdentifier, "osx_gl");
|
||||
ASSERT_EQ(platformIdentifier, "mac");
|
||||
}
|
||||
|
||||
TEST_F(AssetBundlerBatchUtilsTest, SplitFilename_PcFileWithUnderScoreInFileName_OutputBaseNameAndPlatform)
|
||||
@@ -97,7 +97,28 @@ namespace AssetBundler
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
{
|
||||
AZ::SettingsRegistryInterface* registry = nullptr;
|
||||
if (!AZ::SettingsRegistry::Get())
|
||||
{
|
||||
AZ::SettingsRegistry::Register(&m_registry);
|
||||
registry = &m_registry;
|
||||
}
|
||||
else
|
||||
{
|
||||
registry = AZ::SettingsRegistry::Get();
|
||||
}
|
||||
auto projectPathKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
|
||||
+ "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
AZ::IO::FixedMaxPath engineRoot = AZ::Utils::GetEnginePath();
|
||||
if (engineRoot.empty())
|
||||
{
|
||||
GTEST_FATAL_FAILURE_(AZStd::string::format("Unable to locate engine root.\n").c_str());
|
||||
}
|
||||
|
||||
m_data = AZStd::make_unique<StaticData>();
|
||||
m_data->m_application.reset(aznew AzToolsFramework::ToolsApplication());
|
||||
m_data->m_application.get()->Start(AzFramework::Application::Descriptor());
|
||||
@@ -107,19 +128,6 @@ namespace AssetBundler
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
if (!AZ::SettingsRegistry::Get())
|
||||
{
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(m_registry);
|
||||
AZ::SettingsRegistry::Register(&m_registry);
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath engineRoot = AZ::Utils::GetEnginePath();
|
||||
if (engineRoot.empty())
|
||||
{
|
||||
GTEST_FATAL_FAILURE_(AZStd::string::format("Unable to locate engine root.\n").c_str());
|
||||
}
|
||||
|
||||
|
||||
m_data->m_testEngineRoot = (engineRoot / RelativeTestFolder).LexicallyNormal().String();
|
||||
|
||||
m_data->m_localFileIO = aznew AZ::IO::LocalFileIO();
|
||||
@@ -144,14 +152,24 @@ namespace AssetBundler
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
delete m_data->m_localFileIO;
|
||||
AZ::IO::FileIOBase::SetInstance(m_data->m_priorFileIO);
|
||||
if (m_data)
|
||||
{
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
delete m_data->m_localFileIO;
|
||||
AZ::IO::FileIOBase::SetInstance(m_data->m_priorFileIO);
|
||||
|
||||
m_data->m_gemInfoList.set_capacity(0);
|
||||
m_data->m_gemSeedFilePairList.set_capacity(0);
|
||||
m_data->m_application.get()->Stop();
|
||||
m_data->m_application.reset();
|
||||
}
|
||||
|
||||
if(auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
settingsRegistry == &m_registry)
|
||||
{
|
||||
AZ::SettingsRegistry::Unregister(settingsRegistry);
|
||||
}
|
||||
|
||||
m_data->m_gemInfoList.set_capacity(0);
|
||||
m_data->m_gemSeedFilePairList.set_capacity(0);
|
||||
m_data->m_application.get()->Stop();
|
||||
m_data->m_application.reset();
|
||||
}
|
||||
|
||||
void AddGemData(const char* engineRoot, const char* gemName, bool seedFileExists = true)
|
||||
|
||||
@@ -78,17 +78,17 @@ namespace AssetBuilderSDK
|
||||
{
|
||||
return AssetBuilderSDK::Platform_PC;
|
||||
}
|
||||
if (azstricmp(newPlatformName, "es3") == 0)
|
||||
if (azstricmp(newPlatformName, "android") == 0)
|
||||
{
|
||||
return AssetBuilderSDK::Platform_ES3;
|
||||
return AssetBuilderSDK::Platform_ANDROID;
|
||||
}
|
||||
if (azstricmp(newPlatformName, "ios") == 0)
|
||||
{
|
||||
return AssetBuilderSDK::Platform_IOS;
|
||||
}
|
||||
if (azstricmp(newPlatformName, "osx_gl") == 0)
|
||||
if (azstricmp(newPlatformName, "mac") == 0)
|
||||
{
|
||||
return AssetBuilderSDK::Platform_OSX;
|
||||
return AssetBuilderSDK::Platform_MAC;
|
||||
}
|
||||
if (azstricmp(newPlatformName, "provo") == 0)
|
||||
{
|
||||
@@ -115,12 +115,12 @@ namespace AssetBuilderSDK
|
||||
{
|
||||
case AssetBuilderSDK::Platform_PC:
|
||||
return "pc";
|
||||
case AssetBuilderSDK::Platform_ES3:
|
||||
return "es3";
|
||||
case AssetBuilderSDK::Platform_ANDROID:
|
||||
return "android";
|
||||
case AssetBuilderSDK::Platform_IOS:
|
||||
return "ios";
|
||||
case AssetBuilderSDK::Platform_OSX:
|
||||
return "osx_gl";
|
||||
case AssetBuilderSDK::Platform_MAC:
|
||||
return "mac";
|
||||
case AssetBuilderSDK::Platform_PROVO:
|
||||
return "provo";
|
||||
case AssetBuilderSDK::Platform_SALEM:
|
||||
|
||||
@@ -148,15 +148,15 @@ namespace AssetBuilderSDK
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 0x01,
|
||||
Platform_ES3 = 0x02,
|
||||
Platform_ANDROID = 0x02,
|
||||
Platform_IOS = 0x04,
|
||||
Platform_OSX = 0x08,
|
||||
Platform_MAC = 0x08,
|
||||
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_PROVO | Platform_SALEM | Platform_JASPER
|
||||
AllPlatforms = Platform_PC | Platform_ANDROID | Platform_IOS | Platform_MAC | 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.
|
||||
@@ -503,7 +503,7 @@ namespace AssetBuilderSDK
|
||||
AZ_CLASS_ALLOCATOR(PlatformInfo, AZ::SystemAllocator, 0);
|
||||
AZ_TYPE_INFO(PlatformInfo, "{F7DA39A5-C319-4552-954B-3479E2454D3F}");
|
||||
|
||||
AZStd::string m_identifier; ///< like "pc" or "es3" or "ios"...
|
||||
AZStd::string m_identifier; ///< like "pc" or "android" or "ios"...
|
||||
AZStd::unordered_set<AZStd::string> m_tags; ///< The tags like "console" or "tools" on that platform
|
||||
|
||||
PlatformInfo() = default;
|
||||
|
||||
@@ -125,6 +125,10 @@ ly_add_target(
|
||||
AZ::AssetProcessorBatch.Static
|
||||
)
|
||||
|
||||
if(LY_FIRST_PROJECT_PATH)
|
||||
set_property(TARGET AssetProcessor AssetProcessorBatch APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_FIRST_PROJECT_PATH}\"")
|
||||
endif()
|
||||
|
||||
# Adds the AssetProcessorBatch 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
|
||||
# specified for the target.
|
||||
|
||||
@@ -655,6 +655,80 @@ namespace AssetProcessor
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetCatalog::GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& relativePath, AZStd::string& rootFolder)
|
||||
{
|
||||
QString normalizedSourcePath = AssetUtilities::NormalizeFilePath(sourcePath.c_str());
|
||||
QDir inputPath(normalizedSourcePath);
|
||||
QString scanFolder;
|
||||
QString relativeName;
|
||||
|
||||
bool validResult = false;
|
||||
|
||||
AZ_TracePrintf(AssetProcessor::DebugChannel, "ProcessGenerateRelativeSourcePathRequest: %s...\n", sourcePath.c_str());
|
||||
|
||||
if (sourcePath.empty())
|
||||
{
|
||||
// For an empty input path, do nothing, we'll return an empty, invalid result.
|
||||
// (We check fullPath instead of inputPath, because an empty fullPath actually produces "." for inputPath)
|
||||
}
|
||||
else if (inputPath.isAbsolute())
|
||||
{
|
||||
// For an absolute path, try to convert it to a relative path, based on the existing scan folders.
|
||||
// To get the inputPath, we use absolutePath() instead of path() so that any . or .. entries get collapsed.
|
||||
validResult = m_platformConfig->ConvertToRelativePath(inputPath.absolutePath(), relativeName, scanFolder);
|
||||
}
|
||||
else if (inputPath.isRelative())
|
||||
{
|
||||
// For a relative path, concatenate it with each scan folder, and see if a valid relative path emerges.
|
||||
int scanFolders = m_platformConfig->GetScanFolderCount();
|
||||
for (int scanIdx = 0; scanIdx < scanFolders; scanIdx++)
|
||||
{
|
||||
auto& scanInfo = m_platformConfig->GetScanFolderAt(scanIdx);
|
||||
QDir possibleRoot(scanInfo.ScanPath());
|
||||
QDir possibleAbsolutePath = possibleRoot.filePath(normalizedSourcePath);
|
||||
// To get the inputPath, we use absolutePath() instead of path() so that any . or .. entries get collapsed.
|
||||
if (m_platformConfig->ConvertToRelativePath(possibleAbsolutePath.absolutePath(), relativeName, scanFolder))
|
||||
{
|
||||
validResult = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The input has produced a valid relative path. However, the path might match multiple nested scan folders,
|
||||
// so look to see if a higher-priority folder has a better match.
|
||||
if (validResult)
|
||||
{
|
||||
QString overridingFile = m_platformConfig->GetOverridingFile(relativeName, scanFolder);
|
||||
|
||||
if (!overridingFile.isEmpty())
|
||||
{
|
||||
overridingFile = AssetUtilities::NormalizeFilePath(overridingFile);
|
||||
validResult = m_platformConfig->ConvertToRelativePath(overridingFile, relativeName, scanFolder);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validResult)
|
||||
{
|
||||
// if we are here it means we have failed to determine the relativePath, so we will send back the original path
|
||||
AZ_TracePrintf(AssetProcessor::DebugChannel,
|
||||
"GenerateRelativeSourcePath found no valid result, returning original path: %s...\n", sourcePath.c_str());
|
||||
|
||||
rootFolder.clear();
|
||||
relativePath.clear();
|
||||
relativePath = sourcePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
relativePath = relativeName.toUtf8().data();
|
||||
rootFolder = scanFolder.toUtf8().data();
|
||||
|
||||
AZ_Assert(!relativePath.empty(), "ConvertToRelativePath returned true, but relativePath is empty");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetCatalog::GetFullSourcePathFromRelativeProductPath(const AZStd::string& relPath, AZStd::string& fullSourcePath)
|
||||
{
|
||||
ProcessGetFullSourcePathFromRelativeProductPathRequest(relPath, fullSourcePath);
|
||||
|
||||
@@ -95,6 +95,12 @@ namespace AssetProcessor
|
||||
const char* GetAbsoluteDevGameFolderPath() override;
|
||||
const char* GetAbsoluteDevRootFolderPath() override;
|
||||
bool GetRelativeProductPathFromFullSourceOrProductPath(const AZStd::string& fullPath, AZStd::string& relativeProductPath) override;
|
||||
|
||||
//! Given a partial or full source file path, respond with its relative path and the watch folder it is relative to.
|
||||
//! The input source path does not need to exist, so this can be used for new files that haven't been saved yet.
|
||||
bool GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& relativePath, AZStd::string& watchFolder) override;
|
||||
|
||||
bool GetFullSourcePathFromRelativeProductPath(const AZStd::string& relPath, AZStd::string& fullSourcePath) override;
|
||||
bool GetAssetInfoById(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType, const AZStd::string& platformName, AZ::Data::AssetInfo& assetInfo, AZStd::string& rootFilePath) override;
|
||||
bool GetSourceInfoBySourcePath(const char* sourcePath, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override;
|
||||
|
||||
@@ -104,6 +104,27 @@ namespace
|
||||
return GetRelativeProductPathFromFullSourceOrProductPathResponse(relPathFound, relProductPath);
|
||||
}
|
||||
|
||||
GenerateRelativeSourcePathResponse HandleGenerateRelativeSourcePathRequest(
|
||||
MessageData<GenerateRelativeSourcePathRequest> messageData)
|
||||
{
|
||||
bool relPathFound = false;
|
||||
AZStd::string relPath;
|
||||
AZStd::string watchFolder;
|
||||
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
relPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GenerateRelativeSourcePath,
|
||||
messageData.m_message->m_sourcePath, relPath, watchFolder);
|
||||
|
||||
if (!relPathFound)
|
||||
{
|
||||
AZ_TracePrintf(
|
||||
AssetProcessor::ConsoleChannel, "Could not find relative source path for the source file (%s).",
|
||||
messageData.m_message->m_sourcePath.c_str());
|
||||
}
|
||||
|
||||
return GenerateRelativeSourcePathResponse(relPathFound, relPath, watchFolder);
|
||||
}
|
||||
|
||||
SourceAssetInfoResponse HandleSourceAssetInfoRequest(MessageData<SourceAssetInfoRequest> messageData)
|
||||
{
|
||||
SourceAssetInfoResponse response;
|
||||
@@ -407,6 +428,7 @@ AssetRequestHandler::AssetRequestHandler()
|
||||
|
||||
m_requestRouter.RegisterMessageHandler(&HandleGetFullSourcePathFromRelativeProductPathRequest);
|
||||
m_requestRouter.RegisterMessageHandler(&HandleGetRelativeProductPathFromFullSourceOrProductPathRequest);
|
||||
m_requestRouter.RegisterMessageHandler(&HandleGenerateRelativeSourcePathRequest);
|
||||
m_requestRouter.RegisterMessageHandler(&HandleSourceAssetInfoRequest);
|
||||
m_requestRouter.RegisterMessageHandler(&HandleSourceAssetProductsInfoRequest);
|
||||
m_requestRouter.RegisterMessageHandler(&HandleGetScanFoldersRequest);
|
||||
|
||||
@@ -190,9 +190,8 @@ Please note that only those seed files will get updated that are active for your
|
||||
void SourceFileRelocator::HandleMetaDataFiles(QStringList pathMatches, QHash<QString, int>& sourceIndexMap, const ScanFolderInfo* scanFolderInfo, SourceFileRelocationContainer& metadataFiles, bool excludeMetaDataFiles) const
|
||||
{
|
||||
QSet<QString> metaDataFileEntries;
|
||||
for (QStringList::Iterator fileIter = pathMatches.begin(); fileIter != pathMatches.end();)
|
||||
for (QString file : pathMatches)
|
||||
{
|
||||
QString file = *fileIter;
|
||||
for (int idx = 0; idx < m_platformConfig->MetaDataFileTypesCount(); idx++)
|
||||
{
|
||||
QPair<QString, QString> metaInfo = m_platformConfig->GetMetaDataFileTypeAt(idx);
|
||||
@@ -203,8 +202,7 @@ Please note that only those seed files will get updated that are active for your
|
||||
{
|
||||
AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Metadata file %s will be ignored because --excludeMetadataFiles was specified in the command line.\n",
|
||||
file.toUtf8().constData());
|
||||
fileIter = pathMatches.erase(fileIter);
|
||||
continue;
|
||||
break; // don't check it against other metafile entries, we've already ascertained its a metafile.
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -263,8 +261,6 @@ Please note that only those seed files will get updated that are active for your
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileIter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ namespace AzFramework
|
||||
class GetRelativeProductPathFromFullSourceOrProductPathRequest;
|
||||
class GetRelativeProductPathFromFullSourceOrProductPathResponse;
|
||||
|
||||
class GenerateRelativeSourcePathRequest;
|
||||
class GenerateRelativeSourcePathResponse;
|
||||
|
||||
class GetFullSourcePathFromRelativeProductPathRequest;
|
||||
class GetFullSourcePathFromRelativeProductPathResponse;
|
||||
class AssetNotificationMessage;
|
||||
@@ -104,6 +107,8 @@ namespace AssetProcessor
|
||||
using GetAbsoluteAssetDatabaseLocationResponse = AzToolsFramework::AssetSystem::GetAbsoluteAssetDatabaseLocationResponse;
|
||||
using GetRelativeProductPathFromFullSourceOrProductPathRequest = AzFramework::AssetSystem::GetRelativeProductPathFromFullSourceOrProductPathRequest;
|
||||
using GetRelativeProductPathFromFullSourceOrProductPathResponse = AzFramework::AssetSystem::GetRelativeProductPathFromFullSourceOrProductPathResponse;
|
||||
using GenerateRelativeSourcePathRequest = AzFramework::AssetSystem::GenerateRelativeSourcePathRequest;
|
||||
using GenerateRelativeSourcePathResponse = AzFramework::AssetSystem::GenerateRelativeSourcePathResponse;
|
||||
using GetFullSourcePathFromRelativeProductPathRequest = AzFramework::AssetSystem::GetFullSourcePathFromRelativeProductPathRequest;
|
||||
using GetFullSourcePathFromRelativeProductPathResponse = AzFramework::AssetSystem::GetFullSourcePathFromRelativeProductPathResponse;
|
||||
|
||||
|
||||
@@ -291,26 +291,33 @@ namespace AssetProcessor
|
||||
}
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(registry);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_EngineRegistry(registry, platform, specialization, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, platform, specialization, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, platform, specialization, &scratchBuffer);
|
||||
|
||||
// Merge the Project User and User home settings registry only in non-release builds
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
AZ::CommandLine* commandLine{};
|
||||
AZ::ComponentApplicationBus::Broadcast([®istry, &commandLine](AZ::ComponentApplicationRequests* appRequests)
|
||||
{
|
||||
commandLine = appRequests->GetAzCommandLine();
|
||||
});
|
||||
|
||||
if (!specialization.Contains("release"))
|
||||
{
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, platform, specialization, &scratchBuffer);
|
||||
if (commandLine)
|
||||
{
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands);
|
||||
}
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, platform, specialization, &scratchBuffer);
|
||||
}
|
||||
|
||||
AZ::ComponentApplicationBus::Broadcast([®istry](AZ::ComponentApplicationRequests* appRequests)
|
||||
if (commandLine)
|
||||
{
|
||||
if (AZ::CommandLine* commandLine = appRequests->GetAzCommandLine(); commandLine != nullptr)
|
||||
{
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands);
|
||||
}
|
||||
});
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands);
|
||||
}
|
||||
|
||||
|
||||
if (registry.Visit(exporter, ""))
|
||||
{
|
||||
|
||||
@@ -124,131 +124,29 @@ namespace AssetProcessor
|
||||
|
||||
NativeLegacyRCCompiler::NativeLegacyRCCompiler()
|
||||
: m_resourceCompilerInitialized(false)
|
||||
, m_systemRoot()
|
||||
, m_rcExecutableFullPath()
|
||||
, m_requestedQuit(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool NativeLegacyRCCompiler::Initialize(const QString& systemRoot, const QString& rcExecutableFullPath)
|
||||
|
||||
bool NativeLegacyRCCompiler::Initialize()
|
||||
{
|
||||
// QFile::exists(normalizedPath)
|
||||
if (!QDir(systemRoot).exists())
|
||||
{
|
||||
AZ_TracePrintf(AssetProcessor::DebugChannel, QString("Cannot locate system root dir %1").arg(systemRoot).toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AZ::IO::SystemFile::Exists(rcExecutableFullPath.toUtf8().data()))
|
||||
{
|
||||
AZ_TracePrintf(AssetProcessor::DebugChannel, QString("Invalid executable path '%1'").arg(rcExecutableFullPath).toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
this->m_systemRoot.setPath(systemRoot);
|
||||
this->m_rcExecutableFullPath = rcExecutableFullPath;
|
||||
this->m_resourceCompilerInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeLegacyRCCompiler::Execute(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier,
|
||||
const QString& params, const QString& dest, const AssetBuilderSDK::JobCancelListener* jobCancelListener, Result& result) const
|
||||
bool NativeLegacyRCCompiler::Execute(
|
||||
[[maybe_unused]] const QString& inputFile,
|
||||
[[maybe_unused]] const QString& watchFolder,
|
||||
[[maybe_unused]] const QString& platformIdentifier,
|
||||
[[maybe_unused]] const QString& params,
|
||||
[[maybe_unused]] const QString& dest,
|
||||
[[maybe_unused]] const AssetBuilderSDK::JobCancelListener* jobCancelListener,
|
||||
[[maybe_unused]] Result& result) const
|
||||
{
|
||||
if (!this->m_resourceCompilerInitialized)
|
||||
{
|
||||
result.m_exitCode = JobExitCode_RCCouldNotBeLaunched;
|
||||
result.m_crashed = false;
|
||||
AZ_Warning("RC Builder", false, "RC Compiler has not been initialized before use.");
|
||||
return false;
|
||||
}
|
||||
// running RC.EXE is deprecated.
|
||||
AZ_Error("RC Builder", false, "running RC.EXE is deprecated");
|
||||
|
||||
// build the command line:
|
||||
QString commandString = NativeLegacyRCCompiler::BuildCommand(inputFile, watchFolder, platformIdentifier, params, dest);
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
// while it might be tempting to set the executable in processLaunchInfo.m_processExecutableString, it turns out that RC.EXE
|
||||
// won't work if you do that because it assumes the first command line param is the exe name, which is not the case if you do it that way...
|
||||
|
||||
QString formatter("\"%1\" %2");
|
||||
processLaunchInfo.m_commandlineParameters = QString(formatter).arg(m_rcExecutableFullPath).arg(commandString).toUtf8().data();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
processLaunchInfo.m_workingDirectory = m_systemRoot.absolutePath().toUtf8().data();
|
||||
processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_IDLE;
|
||||
|
||||
AZ_TracePrintf("RC Builder", "Executing RC.EXE: '%s' ...\n", processLaunchInfo.m_commandlineParameters.c_str());
|
||||
AZ_TracePrintf("Rc Builder", "Executing RC.EXE with working directory: '%s' ...\n", processLaunchInfo.m_workingDirectory.c_str());
|
||||
|
||||
AzFramework::ProcessWatcher* watcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT);
|
||||
|
||||
if (!watcher)
|
||||
{
|
||||
result.m_exitCode = JobExitCode_RCCouldNotBeLaunched;
|
||||
result.m_crashed = false;
|
||||
AZ_Error("RC Builder", false, "RC failed to execute\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QElapsedTimer ticker;
|
||||
ticker.start();
|
||||
|
||||
// it created the process, wait for it to exit:
|
||||
bool finishedOK = false;
|
||||
{
|
||||
CommunicatorTracePrinter tracer(watcher->GetCommunicator(), "RC Builder"); // allow this to go out of scope...
|
||||
while ((!m_requestedQuit) && (!finishedOK))
|
||||
{
|
||||
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(NativeLegacyRCCompiler::s_maxSleepTime));
|
||||
|
||||
tracer.Pump();
|
||||
|
||||
if (ticker.elapsed() > s_jobMaximumWaitTime || (jobCancelListener && jobCancelListener->IsCancelled()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
AZ::u32 exitCode = 0;
|
||||
if (!watcher->IsProcessRunning(&exitCode))
|
||||
{
|
||||
finishedOK = true; // we either cant wait for it, or it finished.
|
||||
result.m_exitCode = exitCode;
|
||||
result.m_crashed = (exitCode == 100) || (exitCode == 101); // these indicate fatal errors.
|
||||
break;
|
||||
}
|
||||
}
|
||||
tracer.Pump(); // empty whats left if possible.
|
||||
}
|
||||
if (!finishedOK)
|
||||
{
|
||||
if (watcher->IsProcessRunning())
|
||||
{
|
||||
watcher->TerminateProcess(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
if (!this->m_requestedQuit)
|
||||
{
|
||||
if (jobCancelListener == nullptr || !jobCancelListener->IsCancelled())
|
||||
{
|
||||
AZ_Error("RC Builder", false, "RC failed to complete within the maximum allowed time and was terminated. please see %s/rc_log.log for details", result.m_outputDir.toUtf8().data());
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_TracePrintf("RC Builder", "RC was terminated. There was a request to cancel the job.\n");
|
||||
result.m_exitCode = JobExitCode_JobCancelled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("RC Builder", false, "RC terminated because the application is shutting down.\n");
|
||||
result.m_exitCode = JobExitCode_JobCancelled;
|
||||
}
|
||||
result.m_crashed = false;
|
||||
}
|
||||
AZ_TracePrintf("RC Builder", "RC.EXE execution has ended\n");
|
||||
|
||||
delete watcher;
|
||||
|
||||
return finishedOK;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString NativeLegacyRCCompiler::BuildCommand(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params, const QString& dest)
|
||||
@@ -438,22 +336,7 @@ namespace AssetProcessor
|
||||
bool InternalRecognizerBasedBuilder::Initialize(const RecognizerConfiguration& recognizerConfig)
|
||||
{
|
||||
InitializeAssetRecognizers(recognizerConfig.GetAssetRecognizerContainer());
|
||||
|
||||
// Get the engine root since rc.exe will exist there and not in any external project folder
|
||||
QString systemRoot;
|
||||
QString rcFullPath;
|
||||
|
||||
// Validate that the engine root contains the necessary rc.exe
|
||||
if (!FindRC(rcFullPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!m_rcCompiler->Initialize(systemRoot, rcFullPath))
|
||||
{
|
||||
AssetBuilderSDK::BuilderLog(m_internalRecognizerBuilderUuid, "Unable to find rc.exe from the engine root (%1).", rcFullPath.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return m_rcCompiler->Initialize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace AssetProcessor
|
||||
};
|
||||
|
||||
virtual ~RCCompiler() = default;
|
||||
virtual bool Initialize(const QString& systemRoot, const QString& rcExecutableFullPath) = 0;
|
||||
virtual bool Initialize() = 0;
|
||||
virtual bool Execute(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params,
|
||||
const QString& dest, const AssetBuilderSDK::JobCancelListener* jobCancelListener, Result& result) const = 0;
|
||||
virtual void RequestQuit() = 0;
|
||||
@@ -44,7 +44,7 @@ namespace AssetProcessor
|
||||
public:
|
||||
NativeLegacyRCCompiler();
|
||||
|
||||
bool Initialize(const QString& systemRoot, const QString& rcExecutableFullPath) override;
|
||||
bool Initialize() override;
|
||||
bool Execute(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params, const QString& dest,
|
||||
const AssetBuilderSDK::JobCancelListener* jobCancelListener, Result& result) const override;
|
||||
static QString BuildCommand(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params, const QString& dest);
|
||||
@@ -53,8 +53,6 @@ namespace AssetProcessor
|
||||
static const int s_maxSleepTime;
|
||||
static const unsigned int s_jobMaximumWaitTime;
|
||||
bool m_resourceCompilerInitialized;
|
||||
QDir m_systemRoot;
|
||||
QString m_rcExecutableFullPath;
|
||||
volatile bool m_requestedQuit;
|
||||
};
|
||||
|
||||
|
||||
@@ -130,6 +130,9 @@ namespace AssetProcessor
|
||||
auto cacheRootKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_cache_path";
|
||||
settingsRegistry->Set(cacheRootKey, m_data->m_temporarySourceDir.absoluteFilePath("Cache").toUtf8().constData());
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
settingsRegistry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*settingsRegistry);
|
||||
AssetUtilities::ComputeProjectCacheRoot(m_data->m_cacheRootDir);
|
||||
QString normalizedCacheRoot = AssetUtilities::NormalizeDirectoryPath(m_data->m_cacheRootDir.absolutePath());
|
||||
@@ -221,20 +224,28 @@ namespace AssetProcessor
|
||||
dbConn->SetScanFolder(newScanFolder);
|
||||
}
|
||||
|
||||
// build some default configs.
|
||||
void BuildConfig(const QDir& tempPath, AssetDatabaseConnection* dbConn, PlatformConfiguration& config)
|
||||
virtual void AddScanFolders(
|
||||
const QDir& tempPath, AssetDatabaseConnection* dbConn, PlatformConfiguration& config,
|
||||
const AZStd::vector<AssetBuilderSDK::PlatformInfo>& platforms)
|
||||
{
|
||||
config.EnablePlatform({ "pc" ,{ "desktop", "renderer" } }, true);
|
||||
config.EnablePlatform({ "es3" ,{ "mobile", "renderer" } }, true);
|
||||
config.EnablePlatform({ "fandango" ,{ "console", "renderer" } }, false);
|
||||
AZStd::vector<AssetBuilderSDK::PlatformInfo> platforms;
|
||||
config.PopulatePlatformsForScanFolder(platforms);
|
||||
// PATH DisplayName PortKey root recurse platforms order
|
||||
AddScanFolder(ScanFolderInfo(tempPath.filePath("subfolder4"), "subfolder4", "subfolder4", false, false, platforms, -6), config, dbConn); // subfolder 4 overrides subfolder3
|
||||
AddScanFolder(ScanFolderInfo(tempPath.filePath("subfolder3"), "subfolder3", "subfolder3", false, false, platforms, -5), config, dbConn); // subfolder 3 overrides subfolder2
|
||||
AddScanFolder(ScanFolderInfo(tempPath.filePath("subfolder2"), "subfolder2", "subfolder2", false, true, platforms, -2), config, dbConn); // subfolder 2 overrides subfolder1
|
||||
AddScanFolder(ScanFolderInfo(tempPath.filePath("subfolder1"), "subfolder1", "subfolder1", false, true, platforms, -1), config, dbConn); // subfolder1 overrides root
|
||||
AddScanFolder(ScanFolderInfo(tempPath.absolutePath(), "temp", "tempfolder", true, false, platforms, 0), config, dbConn); // add the root
|
||||
}
|
||||
|
||||
// build some default configs.
|
||||
void BuildConfig(const QDir& tempPath, AssetDatabaseConnection* dbConn, PlatformConfiguration& config)
|
||||
{
|
||||
config.EnablePlatform({ "pc" ,{ "desktop", "renderer" } }, true);
|
||||
config.EnablePlatform({ "android" ,{ "mobile", "renderer" } }, true);
|
||||
config.EnablePlatform({ "fandango" ,{ "console", "renderer" } }, false);
|
||||
AZStd::vector<AssetBuilderSDK::PlatformInfo> platforms;
|
||||
config.PopulatePlatformsForScanFolder(platforms);
|
||||
|
||||
AddScanFolders(tempPath, dbConn, config, platforms);
|
||||
|
||||
config.AddMetaDataType("exportsettings", QString());
|
||||
|
||||
@@ -243,22 +254,22 @@ namespace AssetProcessor
|
||||
|
||||
AssetRecognizer rec;
|
||||
AssetPlatformSpec specpc;
|
||||
AssetPlatformSpec speces3;
|
||||
AssetPlatformSpec specandroid;
|
||||
|
||||
speces3.m_extraRCParams = "somerandomparam";
|
||||
specandroid.m_extraRCParams = "somerandomparam";
|
||||
rec.m_name = "random files";
|
||||
rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.random", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
config.AddRecognizer(rec);
|
||||
|
||||
specpc.m_extraRCParams = ""; // blank must work
|
||||
speces3.m_extraRCParams = "testextraparams";
|
||||
specandroid.m_extraRCParams = "testextraparams";
|
||||
|
||||
const char* builderTxt1Name = "txt files";
|
||||
rec.m_name = builderTxt1Name;
|
||||
rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
rec.m_platformSpecs.insert("es3", speces3);
|
||||
rec.m_platformSpecs.insert("android", specandroid);
|
||||
|
||||
config.AddRecognizer(rec);
|
||||
|
||||
@@ -269,7 +280,7 @@ namespace AssetProcessor
|
||||
ignore_rec.m_name = "ignore files";
|
||||
ignore_rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.ignore", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
ignore_rec.m_platformSpecs.insert("pc", specpc);
|
||||
ignore_rec.m_platformSpecs.insert("es3", ignore_spec);
|
||||
ignore_rec.m_platformSpecs.insert("android", ignore_spec);
|
||||
config.AddRecognizer(ignore_rec);
|
||||
|
||||
ExcludeAssetRecognizer excludeRecogniser;
|
||||
@@ -356,7 +367,8 @@ namespace AssetProcessor
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calls the GetFullSourcePathFromRelativeProductPath function and checks the return results, returning true if it matches both of the expected results
|
||||
// Calls the GetFullSourcePathFromRelativeProductPath function and checks the return results, returning true if it matches both of
|
||||
// the expected results
|
||||
bool TestGetFullSourcePath(const QString& fileToCheck, const QDir& tempPath, bool expectToFind, const char* expectedPath)
|
||||
{
|
||||
bool fullPathfound = false;
|
||||
@@ -528,6 +540,177 @@ namespace AssetProcessor
|
||||
ASSERT_TRUE(TestGetRelativeProductPath(fileToCheck, true, { "aaa/basefile.txt" }));
|
||||
}
|
||||
|
||||
class AssetCatalogTestRelativeSourcePath : public AssetCatalogTest
|
||||
{
|
||||
public:
|
||||
QDir GetRoot()
|
||||
{
|
||||
// Return an OS-friendly absolute root directory for our tests ("C:/sourceRoot" or "/sourceRoot"). It doesn't
|
||||
// need to exist, it just needs to be an absolute path.
|
||||
return QDir::root().filePath("sourceRoot");
|
||||
}
|
||||
|
||||
// Set up custom scan folders for the "relative source path" tests, so that we can try out specific combinations of watch folders
|
||||
void AddScanFolders(
|
||||
[[maybe_unused]] const QDir& tempPath, AssetDatabaseConnection* dbConn, PlatformConfiguration& config,
|
||||
const AZStd::vector<AssetBuilderSDK::PlatformInfo>& platforms) override
|
||||
{
|
||||
QDir root = GetRoot();
|
||||
|
||||
// This will set up the following watch folders, in highest to lowest priority:
|
||||
|
||||
// /sourceRoot/recurseNested/nested (recurse)
|
||||
// /sourceRoot/noRecurse (no recurse)
|
||||
// /sourceRoot/recurseNotNested (recurse)
|
||||
// /sourceRoot/recurseNested (recurse)
|
||||
|
||||
AddScanFolder(
|
||||
ScanFolderInfo(root.filePath("recurseNested/nested"), "nested", "nested", false, true, platforms, -4), config, dbConn);
|
||||
AddScanFolder(
|
||||
ScanFolderInfo(root.filePath("noRecurse"), "noRecurse", "noRecurse", false, false, platforms, -3), config, dbConn);
|
||||
AddScanFolder(
|
||||
ScanFolderInfo(root.filePath("recurseNotNested"), "recurseNotNested", "recurseNotNested", false, true, platforms, -2),
|
||||
config, dbConn);
|
||||
AddScanFolder(
|
||||
ScanFolderInfo(root.filePath("recurseNested"), "recurseNested", "recurseNested", false, true, platforms, -1),
|
||||
config, dbConn);
|
||||
}
|
||||
|
||||
// Calls the GenerateRelativeSourcePath function and validates that the results match the expected inputs.
|
||||
void TestGetRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, bool expectedToFind, const AZStd::string& expectedPath, const AZStd::string& expectedRoot)
|
||||
{
|
||||
bool relPathFound = false;
|
||||
AZStd::string relPath;
|
||||
AZStd::string rootFolder;
|
||||
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
relPathFound, &AzToolsFramework::AssetSystem::AssetSystemRequest::GenerateRelativeSourcePath, sourcePath,
|
||||
relPath, rootFolder);
|
||||
|
||||
EXPECT_EQ(relPathFound, expectedToFind);
|
||||
EXPECT_EQ(relPath, expectedPath);
|
||||
EXPECT_EQ(rootFolder, expectedRoot);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_EmptySourcePath_ReturnsNoMatch)
|
||||
{
|
||||
// Test passes in an empty source path, which shouldn't produce a valid result.
|
||||
// Input: empty source path
|
||||
// Output: empty, not found result
|
||||
TestGetRelativeSourcePath("", false, "", "");
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_AbsolutePathOutsideWatchFolders_ReturnsNoMatch)
|
||||
{
|
||||
// Test passes in an invalid absolute source path, which shouldn't produce a valid result.
|
||||
// Input: "/sourceRoot/noWatchFolder/test.txt"
|
||||
// Output: not found result, which also returns the input as the relative file name
|
||||
QDir watchFolder = GetRoot().filePath("noWatchFolder/");
|
||||
QString fileToCheck = watchFolder.filePath("test.txt");
|
||||
|
||||
TestGetRelativeSourcePath(fileToCheck.toUtf8().constData(), false, fileToCheck.toUtf8().constData(), "");
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_AbsolutePathUnderWatchFolder_ReturnsRelativePath)
|
||||
{
|
||||
// Test passes in a valid absolute source path, which should produce a valid relative path
|
||||
// Input: "/sourceRoot/noRecurse/test.txt"
|
||||
// Output: "test.txt" in folder "/sourceRoot/noRecurse/"
|
||||
QDir watchFolder = GetRoot().filePath("noRecurse/");
|
||||
QString fileToCheck = watchFolder.filePath("test.txt");
|
||||
|
||||
TestGetRelativeSourcePath(fileToCheck.toUtf8().constData(), true, "test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_AbsolutePathUnderNestedWatchFolders_ReturnsRelativePath)
|
||||
{
|
||||
// Test passes in a valid absolute source path that matches a watch folder and a nested watch folder.
|
||||
// The output relative path should match the nested folder, because the nested folder has a higher priority registered with the AP.
|
||||
// Input: "/sourceRoot/recurseNested/nested/test.txt"
|
||||
// Output: "test.txt" in folder "/sourceRoot/recurseNested/nested/"
|
||||
QDir watchFolder = GetRoot().filePath("recurseNested/nested/");
|
||||
QString fileToCheck = watchFolder.filePath("test.txt");
|
||||
|
||||
TestGetRelativeSourcePath(fileToCheck.toUtf8().constData(), true, "test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_BareFileNameValidInWatchFolder_ReturnsHighestPriorityWatchFolder)
|
||||
{
|
||||
// Test passes in a simple file name. The output should be relative to the highest-priority watch folder.
|
||||
// Input: "test.txt"
|
||||
// Output: "test.txt" in folder "/sourceRoot/recurseNested/nested/"
|
||||
QDir watchFolder = GetRoot().filePath("recurseNested/nested/");
|
||||
|
||||
TestGetRelativeSourcePath("test.txt", true, "test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_RelativePathValidInWatchFolder_ReturnsHighestPriorityWatchFolder)
|
||||
{
|
||||
// Test passes in a relative path. The output should preserve the relative path, but list it as relative to the highest-priority
|
||||
// watch folder.
|
||||
// Input: "a/b/c/test.txt"
|
||||
// Output: "a/b/c/test.txt" in folder "/sourceRoot/recurseNested/nested/"
|
||||
QDir watchFolder = GetRoot().filePath("recurseNested/nested/");
|
||||
|
||||
TestGetRelativeSourcePath("a/b/c/test.txt", true, "a/b/c/test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_RelativePathNotInWatchFolder_ReturnsNoMatch)
|
||||
{
|
||||
// Test passes in a relative path that "backs up" two directories. This will be invalid, because no matter which watch directory
|
||||
// we start at, the result will be outside of any watch directory.
|
||||
// Input: "../../test.txt"
|
||||
// Output: not found result, which also returns the input as the relative file name
|
||||
TestGetRelativeSourcePath("../../test.txt", false, "../../test.txt", "");
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_RelativePathValidFromNestedWatchFolder_ReturnsOuterFolder)
|
||||
{
|
||||
// Test passes in a relative path that "backs up" one directory. This will produce a valid result, because we can back up from
|
||||
// the "recurseNested/nested/" watch folder to "recurseNested", which is also a valid watch folder.
|
||||
// Input: "../test.txt"
|
||||
// Output: "test.txt" in folder "/sourceRoot/recurseNested"
|
||||
QDir watchFolder = GetRoot().filePath("recurseNested/");
|
||||
TestGetRelativeSourcePath("../test.txt", true, "test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_RelativePathMovesToParentWatchFolder_ReturnsOuterFolder)
|
||||
{
|
||||
// Test passes in a relative path that backs up one directory and then forward into a directory. This will produce a valid
|
||||
// result, because it can validly start in the highest-priority watch folder (recurseNested/nested), move back one into the
|
||||
// outer watch folder (recurseNested), and then have a subdirectory within it.
|
||||
// Note that it would also be valid to move from recurseNested to recurseNotNested, but that won't be the result of this test
|
||||
// because that's a lower-priority match.
|
||||
// Input: "../recurseNotNested/test.txt"
|
||||
// Output: "recurseNotNested/test.txt" in folder "/sourceRoot/recurseNested/"
|
||||
QDir watchFolder = GetRoot().filePath("recurseNested/");
|
||||
|
||||
TestGetRelativeSourcePath("../recurseNotNested/test.txt", true, "recurseNotNested/test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_RelativePathMovesToSiblingWatchFolder_ReturnsSiblingFolder)
|
||||
{
|
||||
// Test passes in a relative path that backs up two directories and then forward into a directory. This will produce a valid
|
||||
// result, because it can validly start in the recurseNested/nested folder, move back two folders, then forward into the sibling
|
||||
// recurseNotNested folder. The result will be a relative path to the sibling folder.
|
||||
// Input: "../../recurseNotNested/test.txt"
|
||||
// Output: "test.txt" in folder "/sourceRoot/recurseNotNested/"
|
||||
QDir watchFolder = GetRoot().filePath("recurseNotNested/");
|
||||
|
||||
TestGetRelativeSourcePath("../../recurseNotNested/test.txt", true, "test.txt", watchFolder.path().toUtf8().constData());
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTestRelativeSourcePath, GenerateRelativeSourcePath_RelativePathBacksOutOfWatchFolder_ReturnsNoMatch)
|
||||
{
|
||||
// Test passes in a relative path that adds a directory, then "backs up" three directories. This will be invalid, because no
|
||||
// matter which watch directory we start at, the result will be outside of any watch directory.
|
||||
// Input: "../test.txt"
|
||||
// Output: "test.txt" in folder "/sourceRoot/recurseNested"
|
||||
TestGetRelativeSourcePath("a/../../../test.txt", false, "a/../../../test.txt", "");
|
||||
}
|
||||
|
||||
class AssetCatalogTest_GetFullSourcePath
|
||||
: public AssetCatalogTest
|
||||
{
|
||||
@@ -909,7 +1092,7 @@ namespace AssetProcessor
|
||||
{
|
||||
AssetCatalogTest::SetUp();
|
||||
m_platforms.push_back("pc");
|
||||
m_platforms.push_back("es3");
|
||||
m_platforms.push_back("android");
|
||||
|
||||
// 4 products for one platform, 1 product for the other.
|
||||
m_platformToProductsForSourceWithDifferentProducts["pc"].push_back("subfolder3/basefilez.arc2");
|
||||
@@ -917,7 +1100,7 @@ namespace AssetProcessor
|
||||
m_platformToProductsForSourceWithDifferentProducts["pc"].push_back("subfolder3/basefile.arc2");
|
||||
m_platformToProductsForSourceWithDifferentProducts["pc"].push_back("subfolder3/basefile.azm2");
|
||||
|
||||
m_platformToProductsForSourceWithDifferentProducts["es3"].push_back("subfolder3/es3exclusivefile.azm2");
|
||||
m_platformToProductsForSourceWithDifferentProducts["android"].push_back("subfolder3/androidexclusivefile.azm2");
|
||||
|
||||
m_sourceFileWithDifferentProductsPerPlatform = AZ::Uuid::CreateString("{38032FC9-2838-4D6A-9DA0-79E5E4F20C1B}");
|
||||
m_sourceFileWithDependency = AZ::Uuid::CreateString("{807C4174-1D19-42AD-B8BC-A59291D9388C}");
|
||||
@@ -930,7 +1113,7 @@ namespace AssetProcessor
|
||||
// resulting in image processing jobs having different products per platform. Because of this, the material jobs will then have different
|
||||
// dependencies per platform, because each material will depend on a referenced texture and all of that texture's mipmaps.
|
||||
|
||||
// Add a source file with 4 products on pc, but 1 on es3
|
||||
// Add a source file with 4 products on pc, but 1 on android
|
||||
bool result = AddSourceAndJobForMultiplePlatforms(
|
||||
"subfolder3",
|
||||
"MultiplatformFile.txt",
|
||||
@@ -945,7 +1128,7 @@ namespace AssetProcessor
|
||||
result = AddSourceAndJobForMultiplePlatforms("subfolder3", "FileWithDependency.txt", &(m_data->m_dbConn), sourceFileWithSameProductsJobsPerPlatform, m_platforms, m_sourceFileWithDependency);
|
||||
EXPECT_TRUE(result);
|
||||
|
||||
const AZStd::string fileWithDependencyProductPath = "subfolder3/es3exclusivefile.azm2";
|
||||
const AZStd::string fileWithDependencyProductPath = "subfolder3/androidexclusivefile.azm2";
|
||||
|
||||
for (const AZStd::string& platform : m_platforms)
|
||||
{
|
||||
|
||||
@@ -265,6 +265,9 @@ namespace AssetProcessorMessagesTests
|
||||
|
||||
addPairFunc(new GetFullSourcePathFromRelativeProductPathRequest(), new GetFullSourcePathFromRelativeProductPathResponse());
|
||||
addPairFunc(new GetRelativeProductPathFromFullSourceOrProductPathRequest(), new GetRelativeProductPathFromFullSourceOrProductPathResponse());
|
||||
addPairFunc(
|
||||
new GenerateRelativeSourcePathRequest(),
|
||||
new GenerateRelativeSourcePathResponse());
|
||||
addPairFunc(new SourceAssetInfoRequest(), new SourceAssetInfoResponse());
|
||||
addPairFunc(new SourceAssetProductsInfoRequest(), new SourceAssetProductsInfoResponse());
|
||||
addPairFunc(new GetScanFoldersRequest(), new GetScanFoldersResponse());
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "AssetProcessorTest.h"
|
||||
|
||||
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
|
||||
#include "BaseAssetProcessorTest.h"
|
||||
@@ -67,6 +67,12 @@ namespace AssetProcessor
|
||||
static char processName[] = {"AssetProcessorBatch"};
|
||||
static char* namePtr = &processName[0];
|
||||
static char** paramStringArray = &namePtr;
|
||||
|
||||
auto registry = AZ::SettingsRegistry::Get();
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
m_application.reset(new UnitTestAppManager(&numParams, ¶mStringArray));
|
||||
ASSERT_EQ(m_application->BeforeRun(), ApplicationManager::Status_Success);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <native/utilities/assetUtils.h>
|
||||
#include <native/unittests/UnitTestRunner.h> // for the assert absorber.
|
||||
@@ -44,7 +45,18 @@ namespace AssetProcessor
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
|
||||
}
|
||||
m_errorAbsorber = new UnitTestUtils::AssertAbsorber();
|
||||
|
||||
m_application = AZStd::make_unique<AzFramework::Application>();
|
||||
|
||||
// Inject the AutomatedTesting project as a project path into test fixture
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
constexpr auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
|
||||
+ "/project_path";
|
||||
if(auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
settingsRegistry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*settingsRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace AssetProcessor
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
}, { "android", {}
|
||||
}
|
||||
};
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformsCount(), 2);
|
||||
@@ -48,19 +48,19 @@ namespace AssetProcessor
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_NONE);
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "es3", {}
|
||||
{ "android", {}
|
||||
}
|
||||
};
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(0), AssetBuilderSDK::Platform_ES3);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(0), AssetBuilderSDK::Platform_ANDROID);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_NONE);
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
}, { "android", {}
|
||||
}
|
||||
};
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(0), AssetBuilderSDK::Platform_PC);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_ES3);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_ANDROID);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(2), AssetBuilderSDK::Platform_NONE);
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
@@ -72,24 +72,24 @@ namespace AssetProcessor
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
}, { "android", {}
|
||||
}, { "ios", {}
|
||||
}, { "osx_gl", {}
|
||||
}, { "mac", {}
|
||||
}
|
||||
};
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(0), AssetBuilderSDK::Platform_PC);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_ES3);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_ANDROID);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(2), AssetBuilderSDK::Platform_IOS);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(3), AssetBuilderSDK::Platform_OSX);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(3), AssetBuilderSDK::Platform_MAC);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(4), AssetBuilderSDK::Platform_NONE);
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
}, { "android", {}
|
||||
}
|
||||
};
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(0), AssetBuilderSDK::Platform_PC);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_ES3);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(1), AssetBuilderSDK::Platform_ANDROID);
|
||||
ASSERT_EQ(createJobsRequest.GetEnabledPlatformAt(2), AssetBuilderSDK::Platform_NONE);
|
||||
// using a deprecated API should have generated warnings.
|
||||
// but we can't test for it because these warnings are WarningOnce and some other unit test might have already triggered it
|
||||
@@ -106,23 +106,23 @@ namespace AssetProcessor
|
||||
}
|
||||
};
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_PC));
|
||||
ASSERT_FALSE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_ES3));
|
||||
ASSERT_FALSE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_ANDROID));
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
}, { "android", {}
|
||||
}
|
||||
};
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_PC));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_ES3));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_ANDROID));
|
||||
|
||||
createJobsRequest.m_enabledPlatforms = {
|
||||
{ "pc", {}
|
||||
}, { "es3", {}
|
||||
}, { "android", {}
|
||||
}
|
||||
};
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_PC));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_ES3));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformEnabled(AssetBuilderSDK::Platform_ANDROID));
|
||||
// using a deprecated API should have generated warnings.
|
||||
// but we can't test for it because these warnings are WarningOnce and some other unit test might have already triggered it
|
||||
}
|
||||
@@ -133,9 +133,9 @@ namespace AssetProcessor
|
||||
UnitTestUtils::AssertAbsorber absorb;
|
||||
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_PC));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_ES3));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_ANDROID));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_IOS));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_OSX));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_MAC));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_PROVO));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_SALEM));
|
||||
ASSERT_TRUE(createJobsRequest.IsPlatformValid(AssetBuilderSDK::Platform_JASPER));
|
||||
|
||||
@@ -204,6 +204,9 @@ void AssetProcessorManagerTest::SetUp()
|
||||
auto cacheRootKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_cache_path";
|
||||
registry->Set(cacheRootKey, tempPath.absoluteFilePath("Cache").toUtf8().constData());
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
m_data->m_databaseLocationListener.BusConnect();
|
||||
@@ -4017,15 +4020,15 @@ TEST_F(ModtimeScanningTest, ModtimeSkipping_EnablePlatform_ShouldProcessFilesFor
|
||||
m_assetProcessorManager->m_allowModtimeSkippingFeature = true;
|
||||
AssetUtilities::SetUseFileHashOverride(true, true);
|
||||
|
||||
// Enable es3 platform after the initial SetUp has already processed the files for pc
|
||||
// Enable android platform after the initial SetUp has already processed the files for pc
|
||||
QDir tempPath(m_tempDir.path());
|
||||
AssetBuilderSDK::PlatformInfo es3Platform("es3", { "host", "renderer" });
|
||||
m_config->EnablePlatform(es3Platform, true);
|
||||
AssetBuilderSDK::PlatformInfo androidPlatform("android", { "host", "renderer" });
|
||||
m_config->EnablePlatform(androidPlatform, true);
|
||||
|
||||
// There's no way to remove scanfolders and adding a new one after enabling the platform will cause the pc assets to build as well, which we don't want
|
||||
// Instead we'll just const cast the vector and modify the enabled platforms for the scanfolder
|
||||
auto& platforms = const_cast<AZStd::vector<AssetBuilderSDK::PlatformInfo>&>(m_config->GetScanFolderAt(0).GetPlatforms());
|
||||
platforms.push_back(es3Platform);
|
||||
platforms.push_back(androidPlatform);
|
||||
|
||||
// We need the builder fingerprints to be updated to reflect the newly enabled platform
|
||||
m_assetProcessorManager->ComputeBuilderDirty();
|
||||
@@ -4033,10 +4036,10 @@ TEST_F(ModtimeScanningTest, ModtimeSkipping_EnablePlatform_ShouldProcessFilesFor
|
||||
QSet<AssetFileInfo> filePaths = BuildFileSet();
|
||||
SimulateAssetScanner(filePaths);
|
||||
|
||||
ExpectWork(4, 2); // CreateJobs = 4, 2 files * 2 platforms. ProcessJobs = 2, just the es3 platform jobs (pc is already processed)
|
||||
ExpectWork(4, 2); // CreateJobs = 4, 2 files * 2 platforms. ProcessJobs = 2, just the android platform jobs (pc is already processed)
|
||||
|
||||
ASSERT_TRUE(m_data->m_processResults[0].m_destinationPath.contains("es3"));
|
||||
ASSERT_TRUE(m_data->m_processResults[1].m_destinationPath.contains("es3"));
|
||||
ASSERT_TRUE(m_data->m_processResults[0].m_destinationPath.contains("android"));
|
||||
ASSERT_TRUE(m_data->m_processResults[1].m_destinationPath.contains("android"));
|
||||
}
|
||||
|
||||
TEST_F(ModtimeScanningTest, ModtimeSkipping_ModifyTimestamp)
|
||||
|
||||
+23
-24
@@ -39,7 +39,6 @@ void PlatformConfigurationUnitTests::SetUp()
|
||||
m_qApp = new QCoreApplication(m_argc, m_argv);
|
||||
AssetProcessorTest::SetUp();
|
||||
AssetUtilities::ResetAssetRoot();
|
||||
|
||||
}
|
||||
|
||||
void PlatformConfigurationUnitTests::TearDown()
|
||||
@@ -121,14 +120,14 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Regular_Platforms)
|
||||
|
||||
// verify the data.
|
||||
ASSERT_NE(config.GetPlatformByIdentifier(AzToolsFramework::AssetSystem::GetHostAssetPlatform()), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("es3"), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("android"), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("server"), nullptr);
|
||||
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("es3")->HasTag("mobile"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("es3")->HasTag("renderer"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("es3")->HasTag("android"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("android")->HasTag("mobile"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("android")->HasTag("renderer"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("android")->HasTag("android"));
|
||||
ASSERT_TRUE(config.GetPlatformByIdentifier("server")->HasTag("server"));
|
||||
ASSERT_FALSE(config.GetPlatformByIdentifier("es3")->HasTag("server"));
|
||||
ASSERT_FALSE(config.GetPlatformByIdentifier("android")->HasTag("server"));
|
||||
ASSERT_FALSE(config.GetPlatformByIdentifier("server")->HasTag("renderer"));
|
||||
}
|
||||
|
||||
@@ -398,7 +397,7 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_RegularScanfolderP
|
||||
AZStd::vector<AssetBuilderSDK::PlatformInfo> platforms = config.GetScanFolderAt(0).GetPlatforms();
|
||||
ASSERT_EQ(platforms.size(), 4);
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo(AzToolsFramework::AssetSystem::GetHostAssetPlatform(), AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("es3", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("android", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("ios", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("server", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
|
||||
@@ -406,12 +405,12 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_RegularScanfolderP
|
||||
platforms = config.GetScanFolderAt(1).GetPlatforms();
|
||||
ASSERT_EQ(platforms.size(), 2);
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo(AzToolsFramework::AssetSystem::GetHostAssetPlatform(), AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("es3", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("android", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
|
||||
ASSERT_EQ(config.GetScanFolderAt(2).GetDisplayName(), QString("folder1output"));
|
||||
platforms = config.GetScanFolderAt(2).GetPlatforms();
|
||||
ASSERT_EQ(platforms.size(), 1);
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("es3", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
ASSERT_TRUE(AZStd::find(platforms.begin(), platforms.end(), AssetBuilderSDK::PlatformInfo("android", AZStd::unordered_set<AZStd::string>{})) != platforms.end());
|
||||
|
||||
ASSERT_EQ(config.GetScanFolderAt(3).GetDisplayName(), QString("folder2output"));
|
||||
platforms = config.GetScanFolderAt(3).GetPlatforms();
|
||||
@@ -455,7 +454,7 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Recognizers)
|
||||
using namespace AzToolsFramework::AssetSystem;
|
||||
using namespace AssetProcessor;
|
||||
#if defined(AZ_PLATFORM_WINDOWS)
|
||||
const char* platformWhichIsNotCurrentPlatform = "osx_gl";
|
||||
const char* platformWhichIsNotCurrentPlatform = "mac";
|
||||
#else
|
||||
const char* platformWhichIsNotCurrentPlatform = "pc";
|
||||
#endif
|
||||
@@ -476,27 +475,27 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Recognizers)
|
||||
ASSERT_EQ(recogs["i_caf"].m_patternMatcher.GetBuilderPattern().m_pattern, "*.i_caf");
|
||||
ASSERT_EQ(recogs["i_caf"].m_patternMatcher.GetBuilderPattern().m_type, AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs.size(), 2);
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_FALSE(recogs["i_caf"].m_platformSpecs.contains("server")); // server has been set to skip.
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs["es3"].m_extraRCParams, "mobile");
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs["android"].m_extraRCParams, "mobile");
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs[AzToolsFramework::AssetSystem::GetHostAssetPlatform()].m_extraRCParams, "defaultparams");
|
||||
|
||||
ASSERT_TRUE(recogs.contains("caf"));
|
||||
ASSERT_TRUE(recogs["caf"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_TRUE(recogs["caf"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["caf"].m_platformSpecs.contains("server"));
|
||||
ASSERT_TRUE(recogs["caf"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_EQ(recogs["caf"].m_platformSpecs.size(), 3);
|
||||
ASSERT_EQ(recogs["caf"].m_platformSpecs["es3"].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["caf"].m_platformSpecs["android"].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["caf"].m_platformSpecs[AzToolsFramework::AssetSystem::GetHostAssetPlatform()].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["caf"].m_platformSpecs["server"].m_extraRCParams, "copy");
|
||||
|
||||
ASSERT_TRUE(recogs.contains("mov"));
|
||||
ASSERT_TRUE(recogs["mov"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_TRUE(recogs["mov"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["mov"].m_platformSpecs.contains("server"));
|
||||
ASSERT_TRUE(recogs["mov"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_EQ(recogs["mov"].m_platformSpecs.size(), 3);
|
||||
ASSERT_EQ(recogs["mov"].m_platformSpecs["es3"].m_extraRCParams, "platformspecificoverride");
|
||||
ASSERT_EQ(recogs["mov"].m_platformSpecs["android"].m_extraRCParams, "platformspecificoverride");
|
||||
ASSERT_EQ(recogs["mov"].m_platformSpecs[AzToolsFramework::AssetSystem::GetHostAssetPlatform()].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["mov"].m_platformSpecs["server"].m_extraRCParams, "copy");
|
||||
|
||||
@@ -504,27 +503,27 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Recognizers)
|
||||
// (but platforms can override it)
|
||||
ASSERT_TRUE(recogs.contains("rend"));
|
||||
ASSERT_TRUE(recogs["rend"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_TRUE(recogs["rend"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_TRUE(recogs["rend"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["rend"].m_platformSpecs.contains("server"));
|
||||
ASSERT_FALSE(recogs["rend"].m_platformSpecs.contains(platformWhichIsNotCurrentPlatform)); // this is not an enabled platform and should not be there.
|
||||
ASSERT_EQ(recogs["rend"].m_platformSpecs.size(), 3);
|
||||
ASSERT_EQ(recogs["rend"].m_platformSpecs[AzToolsFramework::AssetSystem::GetHostAssetPlatform()].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["rend"].m_platformSpecs["es3"].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["rend"].m_platformSpecs["android"].m_extraRCParams, "rendererparams");
|
||||
ASSERT_EQ(recogs["rend"].m_platformSpecs["server"].m_extraRCParams, ""); // default if not specified is empty string
|
||||
|
||||
ASSERT_TRUE(recogs.contains("alldefault"));
|
||||
ASSERT_TRUE(recogs["alldefault"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_TRUE(recogs["alldefault"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_TRUE(recogs["alldefault"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["alldefault"].m_platformSpecs.contains("server"));
|
||||
ASSERT_FALSE(recogs["alldefault"].m_platformSpecs.contains(platformWhichIsNotCurrentPlatform)); // this is not an enabled platform and should not be there.
|
||||
ASSERT_EQ(recogs["alldefault"].m_platformSpecs.size(), 3);
|
||||
ASSERT_EQ(recogs["alldefault"].m_platformSpecs[AzToolsFramework::AssetSystem::GetHostAssetPlatform()].m_extraRCParams, "");
|
||||
ASSERT_EQ(recogs["alldefault"].m_platformSpecs["es3"].m_extraRCParams, "");
|
||||
ASSERT_EQ(recogs["alldefault"].m_platformSpecs["android"].m_extraRCParams, "");
|
||||
ASSERT_EQ(recogs["alldefault"].m_platformSpecs["server"].m_extraRCParams, "");
|
||||
|
||||
ASSERT_TRUE(recogs.contains("skipallbutone"));
|
||||
ASSERT_FALSE(recogs["skipallbutone"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_FALSE(recogs["skipallbutone"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_FALSE(recogs["skipallbutone"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["skipallbutone"].m_platformSpecs.contains("server")); // server is only one enabled (set to copy)
|
||||
ASSERT_EQ(recogs["skipallbutone"].m_platformSpecs.size(), 1);
|
||||
ASSERT_EQ(recogs["skipallbutone"].m_platformSpecs["server"].m_extraRCParams, "copy");
|
||||
@@ -550,7 +549,7 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Overrides)
|
||||
|
||||
// verify the data.
|
||||
ASSERT_NE(config.GetPlatformByIdentifier(AzToolsFramework::AssetSystem::GetHostAssetPlatform()), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("es3"), nullptr);
|
||||
ASSERT_NE(config.GetPlatformByIdentifier("android"), 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("server"), nullptr); // this should be off due to overrides
|
||||
@@ -567,11 +566,11 @@ TEST_F(PlatformConfigurationUnitTests, TestFailReadConfigFile_Overrides)
|
||||
ASSERT_EQ(recogs["i_caf"].m_patternMatcher.GetBuilderPattern().m_pattern, "*.i_caf");
|
||||
ASSERT_EQ(recogs["i_caf"].m_patternMatcher.GetBuilderPattern().m_type, AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs.size(), 3);
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains("es3"));
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains("android"));
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains("provo"));
|
||||
ASSERT_TRUE(recogs["i_caf"].m_platformSpecs.contains(AzToolsFramework::AssetSystem::GetHostAssetPlatform()));
|
||||
ASSERT_FALSE(recogs["i_caf"].m_platformSpecs.contains("server")); // server has been set to skip.
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs["es3"].m_extraRCParams, "mobile");
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs["android"].m_extraRCParams, "mobile");
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs[AzToolsFramework::AssetSystem::GetHostAssetPlatform()].m_extraRCParams, "defaultparams");
|
||||
ASSERT_EQ(recogs["i_caf"].m_platformSpecs["provo"].m_extraRCParams, "copy");
|
||||
|
||||
|
||||
-1
@@ -37,6 +37,5 @@ private:
|
||||
int m_argc;
|
||||
char** m_argv;
|
||||
QCoreApplication* m_qApp;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -43,19 +43,6 @@ TEST_F(RCBuilderTest, Shutdown_NormalShutdown_Requested)
|
||||
}
|
||||
|
||||
|
||||
TEST_F(RCBuilderTest, Initialize_StandardInitialization_Fail)
|
||||
{
|
||||
MockRCCompiler* mockRC = new MockRCCompiler();
|
||||
TestInternalRecognizerBasedBuilder test(mockRC);
|
||||
|
||||
MockRecognizerConfiguration configuration;
|
||||
|
||||
mockRC->SetResultInitialize(false);
|
||||
bool initialization_result = test.Initialize(configuration);
|
||||
ASSERT_FALSE(initialization_result);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(RCBuilderTest, Initialize_StandardInitializationWithDuplicateAndInvalidRecognizers_Valid)
|
||||
{
|
||||
MockRCCompiler* mockRC = new MockRCCompiler();
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool Initialize([[maybe_unused]] const QString& systemRoot, [[maybe_unused]] const QString& rcExecutableFullPath) override
|
||||
bool Initialize() override
|
||||
{
|
||||
m_initialize++;
|
||||
return m_initializeResult;
|
||||
|
||||
@@ -224,7 +224,7 @@ void RCcontrollerTest_Simple::SubmitJob()
|
||||
|
||||
// This is a regresssion test to ensure the rccontroller can handle multiple jobs for the same file being completed before
|
||||
// the APM has a chance to send OnFinishedProcesssingJob events
|
||||
TEST_F(RCcontrollerTest_Simple, SameJobIsCompletedMultipleTimes_CompletesWithoutError)
|
||||
TEST_F(RCcontrollerTest_Simple, DISABLED_SameJobIsCompletedMultipleTimes_CompletesWithoutError)
|
||||
{
|
||||
using namespace AssetProcessor;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "ProductAssetTreeItemData.h"
|
||||
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AssetProcessor
|
||||
@@ -159,31 +160,33 @@ namespace AssetProcessor
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::IO::Path productNamePath(product.m_productName, AZ::IO::PosixPathSeparator);
|
||||
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
AzFramework::StringFunc::Tokenize(product.m_productName.c_str(), tokens, AZ_CORRECT_DATABASE_SEPARATOR, false, true);
|
||||
|
||||
if (tokens.empty())
|
||||
if (productNamePath.empty())
|
||||
{
|
||||
AZ_Warning("AssetProcessor", false, "Product id %d has an invalid name: %s", product.m_productID, product.m_productName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AssetTreeItem* parentItem = m_root.get();
|
||||
AZStd::string fullFolderName;
|
||||
for (int i = 0; i < tokens.size() - 1; ++i)
|
||||
AZ::IO::Path currentFullFolderPath;
|
||||
const AZ::IO::PathView filename = productNamePath.Filename();
|
||||
const AZ::IO::PathView fullPathWithoutFilename = productNamePath.RemoveFilename();
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> currentPath;
|
||||
for (auto pathIt = fullPathWithoutFilename.begin(); pathIt != fullPathWithoutFilename.end(); ++pathIt)
|
||||
{
|
||||
AzFramework::StringFunc::AssetDatabasePath::Join(fullFolderName.c_str(), tokens[i].c_str(), fullFolderName);
|
||||
AssetTreeItem* nextParent = parentItem->GetChildFolder(tokens[i].c_str());
|
||||
currentPath = pathIt->FixedMaxPathString();
|
||||
currentFullFolderPath /= currentPath;
|
||||
AssetTreeItem* nextParent = parentItem->GetChildFolder(currentPath.c_str());
|
||||
if (!nextParent)
|
||||
{
|
||||
if (!modelIsResetting)
|
||||
{
|
||||
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
|
||||
}
|
||||
nextParent = parentItem->CreateChild(ProductAssetTreeItemData::MakeShared(nullptr, fullFolderName, tokens[i].c_str(), true, AZ::Uuid::CreateNull()));
|
||||
m_productToTreeItem[fullFolderName] = nextParent;
|
||||
nextParent = parentItem->CreateChild(ProductAssetTreeItemData::MakeShared(nullptr, currentFullFolderPath.Native(), currentPath.c_str(), true, AZ::Uuid::CreateNull()));
|
||||
m_productToTreeItem[currentFullFolderPath.Native()] = nextParent;
|
||||
// m_productIdToTreeItem is not used for folders, folders don't have product IDs.
|
||||
|
||||
if (!modelIsResetting)
|
||||
@@ -205,12 +208,12 @@ namespace AssetProcessor
|
||||
|
||||
if (!modelIsResetting)
|
||||
{
|
||||
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<ProductAssetTreeItemData> productItemData =
|
||||
ProductAssetTreeItemData::MakeShared(&product, product.m_productName, tokens[tokens.size() - 1].c_str(), false, sourceId);
|
||||
ProductAssetTreeItemData::MakeShared(&product, product.m_productName, AZStd::fixed_string<AZ::IO::MaxPathLength>(filename.Native()).c_str(), false, sourceId);
|
||||
m_productToTreeItem[product.m_productName] =
|
||||
parentItem->CreateChild(productItemData);
|
||||
m_productIdToTreeItem[product.m_productID] = m_productToTreeItem[product.m_productName];
|
||||
|
||||
@@ -63,8 +63,7 @@ namespace AssetProcessor
|
||||
}
|
||||
|
||||
|
||||
auto fullPath = AZ::IO::Path(scanFolder.m_scanFolder) / source.m_sourceName;
|
||||
|
||||
AZ::IO::Path fullPath = AZ::IO::Path(scanFolder.m_scanFolder, AZ::IO::PosixPathSeparator) / source.m_sourceName;
|
||||
|
||||
// It's common for Open 3D Engine game projects and scan folders to be in a subfolder
|
||||
// of the engine install. To improve readability of the source files, strip out
|
||||
@@ -78,34 +77,35 @@ namespace AssetProcessor
|
||||
AzFramework::StringFunc::Replace(fullPath.Native(), m_assetRoot.absolutePath().toUtf8(), "");
|
||||
}
|
||||
|
||||
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
AzFramework::StringFunc::Tokenize(fullPath.c_str(), tokens, AZ_CORRECT_DATABASE_SEPARATOR, false, true);
|
||||
|
||||
if (tokens.empty())
|
||||
if (fullPath.empty())
|
||||
{
|
||||
AZ_Warning("AssetProcessor", false, "Source id %s has an invalid name: %s",
|
||||
source.m_sourceGuid.ToString<AZStd::string>().c_str(), source.m_sourceName.c_str());
|
||||
AZ_Warning(
|
||||
"AssetProcessor", false, "Source id %s has an invalid name: %s", source.m_sourceGuid.ToString<AZStd::string>().c_str(),
|
||||
source.m_sourceName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndex newIndicesStart;
|
||||
|
||||
AssetTreeItem* parentItem = m_root.get();
|
||||
AZStd::string fullFolderName;
|
||||
for (int i = 0; i < tokens.size() - 1; ++i)
|
||||
AZ::IO::Path currentFullFolderPath;
|
||||
const AZ::IO::PathView filename = fullPath.Filename();
|
||||
const AZ::IO::PathView fullPathWithoutFilename = fullPath.RemoveFilename();
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> currentPath;
|
||||
for (auto pathIt = fullPathWithoutFilename.begin(); pathIt != fullPathWithoutFilename.end(); ++pathIt)
|
||||
{
|
||||
AzFramework::StringFunc::AssetDatabasePath::Join(fullFolderName.c_str(), tokens[i].c_str(), fullFolderName);
|
||||
AssetTreeItem* nextParent = parentItem->GetChildFolder(tokens[i].c_str());
|
||||
currentPath = pathIt->FixedMaxPathString();
|
||||
currentFullFolderPath /= currentPath;
|
||||
AssetTreeItem* nextParent = parentItem->GetChildFolder(currentPath.c_str());
|
||||
if (!nextParent)
|
||||
{
|
||||
if (!modelIsResetting)
|
||||
{
|
||||
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
|
||||
}
|
||||
nextParent = parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(nullptr, nullptr, fullFolderName, tokens[i].c_str(), true));
|
||||
m_sourceToTreeItem[fullFolderName] = nextParent;
|
||||
nextParent = parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(nullptr, nullptr, currentFullFolderPath.Native(), currentPath.c_str(), true));
|
||||
m_sourceToTreeItem[currentFullFolderPath.Native()] = nextParent;
|
||||
// Folders don't have source IDs, don't add to m_sourceIdToTreeItem
|
||||
if (!modelIsResetting)
|
||||
{
|
||||
@@ -117,12 +117,12 @@ namespace AssetProcessor
|
||||
|
||||
if (!modelIsResetting)
|
||||
{
|
||||
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
|
||||
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
|
||||
}
|
||||
|
||||
m_sourceToTreeItem[source.m_sourceName] =
|
||||
parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(&source, &scanFolder, source.m_sourceName, tokens[tokens.size() - 1].c_str(), false));
|
||||
parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(&source, &scanFolder, source.m_sourceName, AZStd::fixed_string<AZ::IO::MaxPathLength>(filename.Native()).c_str(), false));
|
||||
m_sourceIdToTreeItem[source.m_sourceID] = m_sourceToTreeItem[source.m_sourceName];
|
||||
if (!modelIsResetting)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,8 @@ namespace AssetProcessor
|
||||
public:
|
||||
using GetRelativeProductPathFromFullSourceOrProductPathRequest = AzFramework::AssetSystem::GetRelativeProductPathFromFullSourceOrProductPathRequest;
|
||||
using GetRelativeProductPathFromFullSourceOrProductPathResponse = AzFramework::AssetSystem::GetRelativeProductPathFromFullSourceOrProductPathResponse;
|
||||
using GenerateRelativeSourcePathRequest = AzFramework::AssetSystem::GenerateRelativeSourcePathRequest;
|
||||
using GenerateRelativeSourcePathResponse = AzFramework::AssetSystem::GenerateRelativeSourcePathResponse;
|
||||
using GetFullSourcePathFromRelativeProductPathRequest = AzFramework::AssetSystem::GetFullSourcePathFromRelativeProductPathRequest;
|
||||
using GetFullSourcePathFromRelativeProductPathResponse = AzFramework::AssetSystem::GetFullSourcePathFromRelativeProductPathResponse;
|
||||
};
|
||||
@@ -88,34 +90,34 @@ namespace AssetProcessor
|
||||
//AZ_TracePrintf("test", "-------------------------\n");
|
||||
}
|
||||
|
||||
void ComputeFingerprints(unsigned int& fingerprintForPC, unsigned int& fingerprintForES3, PlatformConfiguration& config, QString scanFolderPath, QString relPath)
|
||||
void ComputeFingerprints(unsigned int& fingerprintForPC, unsigned int& fingerprintForANDROID, PlatformConfiguration& config, QString scanFolderPath, QString relPath)
|
||||
{
|
||||
QString extraInfoForPC;
|
||||
QString extraInfoForES3;
|
||||
QString extraInfoForANDROID;
|
||||
RecognizerPointerContainer output;
|
||||
QString filePath = scanFolderPath + "/" + relPath;
|
||||
config.GetMatchingRecognizers(filePath, output);
|
||||
for (const AssetRecognizer* assetRecogniser : output)
|
||||
{
|
||||
extraInfoForPC.append(assetRecogniser->m_platformSpecs["pc"].m_extraRCParams);
|
||||
extraInfoForES3.append(assetRecogniser->m_platformSpecs["es3"].m_extraRCParams);
|
||||
extraInfoForANDROID.append(assetRecogniser->m_platformSpecs["android"].m_extraRCParams);
|
||||
extraInfoForPC.append(assetRecogniser->m_version);
|
||||
extraInfoForES3.append(assetRecogniser->m_version);
|
||||
extraInfoForANDROID.append(assetRecogniser->m_version);
|
||||
}
|
||||
|
||||
//Calculating fingerprints for the file for pc and es3 platforms
|
||||
//Calculating fingerprints for the file for pc and android platforms
|
||||
AZ::Uuid sourceId = AZ::Uuid("{2206A6E0-FDBC-45DE-B6FE-C2FC63020BD5}");
|
||||
JobEntry jobEntryPC(scanFolderPath, relPath, relPath, 0, { "pc", {"desktop", "renderer"} }, "", 0, 1, sourceId);
|
||||
JobEntry jobEntryES3(scanFolderPath, relPath, relPath, 0, { "es3", {"mobile", "renderer"} }, "", 0, 2, sourceId);
|
||||
JobEntry jobEntryANDROID(scanFolderPath, relPath, relPath, 0, { "android", {"mobile", "renderer"} }, "", 0, 2, sourceId);
|
||||
|
||||
JobDetails jobDetailsPC;
|
||||
jobDetailsPC.m_extraInformationForFingerprinting = extraInfoForPC.toUtf8().constData();
|
||||
jobDetailsPC.m_jobEntry = jobEntryPC;
|
||||
JobDetails jobDetailsES3;
|
||||
jobDetailsES3.m_extraInformationForFingerprinting = extraInfoForES3.toUtf8().constData();
|
||||
jobDetailsES3.m_jobEntry = jobEntryES3;
|
||||
JobDetails jobDetailsANDROID;
|
||||
jobDetailsANDROID.m_extraInformationForFingerprinting = extraInfoForANDROID.toUtf8().constData();
|
||||
jobDetailsANDROID.m_jobEntry = jobEntryANDROID;
|
||||
fingerprintForPC = AssetUtilities::GenerateFingerprint(jobDetailsPC);
|
||||
fingerprintForES3 = AssetUtilities::GenerateFingerprint(jobDetailsES3);
|
||||
fingerprintForANDROID = AssetUtilities::GenerateFingerprint(jobDetailsANDROID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +242,7 @@ namespace AssetProcessor
|
||||
|
||||
PlatformConfiguration config;
|
||||
config.EnablePlatform({ "pc",{ "desktop", "renderer" } }, true);
|
||||
config.EnablePlatform({ "es3",{ "mobile", "renderer" } }, true);
|
||||
config.EnablePlatform({ "android",{ "mobile", "renderer" } }, true);
|
||||
config.EnablePlatform({ "fandago",{ "console", "renderer" } }, false);
|
||||
AZStd::vector<AssetBuilderSDK::PlatformInfo> platforms;
|
||||
config.PopulatePlatformsForScanFolder(platforms);
|
||||
@@ -259,9 +261,9 @@ namespace AssetProcessor
|
||||
|
||||
AssetRecognizer rec;
|
||||
AssetPlatformSpec specpc;
|
||||
AssetPlatformSpec speces3;
|
||||
AssetPlatformSpec specandroid;
|
||||
|
||||
speces3.m_extraRCParams = "somerandomparam";
|
||||
specandroid.m_extraRCParams = "somerandomparam";
|
||||
rec.m_name = "random files";
|
||||
rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.random", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
@@ -269,13 +271,13 @@ namespace AssetProcessor
|
||||
UNIT_TEST_EXPECT_TRUE(mockAppManager.RegisterAssetRecognizerAsBuilder(rec));
|
||||
|
||||
specpc.m_extraRCParams = ""; // blank must work
|
||||
speces3.m_extraRCParams = "testextraparams";
|
||||
specandroid.m_extraRCParams = "testextraparams";
|
||||
|
||||
const char* builderTxt1Name = "txt files";
|
||||
rec.m_name = builderTxt1Name;
|
||||
rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
rec.m_platformSpecs.insert("es3", speces3);
|
||||
rec.m_platformSpecs.insert("android", specandroid);
|
||||
|
||||
config.AddRecognizer(rec);
|
||||
|
||||
@@ -305,21 +307,21 @@ namespace AssetProcessor
|
||||
rec.m_testLockSource = false;
|
||||
|
||||
specpc.m_extraRCParams = "pcparams";
|
||||
speces3.m_extraRCParams = "es3params";
|
||||
specandroid.m_extraRCParams = "androidparams";
|
||||
|
||||
rec.m_name = "xxx files";
|
||||
rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.xxx", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
rec.m_platformSpecs.insert("es3", speces3);
|
||||
rec.m_platformSpecs.insert("android", specandroid);
|
||||
config.AddRecognizer(rec);
|
||||
mockAppManager.RegisterAssetRecognizerAsBuilder(rec);
|
||||
|
||||
// two recognizers for the same pattern.
|
||||
rec.m_name = "xxx files 2 (builder2)";
|
||||
specpc.m_extraRCParams = "pcparams2";
|
||||
speces3.m_extraRCParams = "es3params2";
|
||||
specandroid.m_extraRCParams = "androidparams2";
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
rec.m_platformSpecs.insert("es3", speces3);
|
||||
rec.m_platformSpecs.insert("android", specandroid);
|
||||
config.AddRecognizer(rec);
|
||||
mockAppManager.RegisterAssetRecognizerAsBuilder(rec);
|
||||
|
||||
@@ -330,7 +332,7 @@ namespace AssetProcessor
|
||||
ignore_rec.m_name = "ignore files";
|
||||
ignore_rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.ignore", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
ignore_rec.m_platformSpecs.insert("pc", specpc);
|
||||
ignore_rec.m_platformSpecs.insert("es3", ignore_spec);
|
||||
ignore_rec.m_platformSpecs.insert("android", ignore_spec);
|
||||
config.AddRecognizer(ignore_rec);
|
||||
mockAppManager.RegisterAssetRecognizerAsBuilder(ignore_rec);
|
||||
|
||||
@@ -432,7 +434,7 @@ namespace AssetProcessor
|
||||
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 1); // 1, since we have one recognizer for .ignore, but the 'es3' platform is marked as skip
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 1); // 1, since we have one recognizer for .ignore, but the 'android' platform is marked as skip
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
|
||||
|
||||
@@ -455,16 +457,16 @@ namespace AssetProcessor
|
||||
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and es3,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and android,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
|
||||
|
||||
QList<int> es3JobsIndex;
|
||||
QList<int> androidJobsIndex;
|
||||
QList<int> pcJobsIndex;
|
||||
for (int checkIdx = 0; checkIdx < 4; ++checkIdx)
|
||||
{
|
||||
@@ -662,19 +664,19 @@ namespace AssetProcessor
|
||||
// ---------- test successes ----------
|
||||
|
||||
|
||||
QStringList es3outs;
|
||||
es3outs.push_back(cacheRoot.filePath(QString("es3/basefile.arc1")));
|
||||
es3outs.push_back(cacheRoot.filePath(QString("es3/basefile.arc2")));
|
||||
QStringList androidouts;
|
||||
androidouts.push_back(cacheRoot.filePath(QString("android/basefile.arc1")));
|
||||
androidouts.push_back(cacheRoot.filePath(QString("android/basefile.arc2")));
|
||||
|
||||
// feed it the messages its waiting for (create the files)
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs[0], "products."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs[1], "products."))
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts[0], "products."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts[1], "products."))
|
||||
|
||||
//Invoke Asset Processed for es3 platform , txt files job description
|
||||
//Invoke Asset Processed for android platform , txt files job description
|
||||
AssetBuilderSDK::ProcessJobResponse response;
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData(), AZ::Uuid::CreateNull(), 1));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[1].toUtf8().constData(), AZ::Uuid::CreateNull(), 2));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData(), AZ::Uuid::CreateNull(), 1));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[1].toUtf8().constData(), AZ::Uuid::CreateNull(), 2));
|
||||
|
||||
// make sure legacy SubIds get stored in the DB and in asset response messages.
|
||||
// also make sure they don't get filed for the wrong asset.
|
||||
@@ -693,8 +695,8 @@ namespace AssetProcessor
|
||||
UNIT_TEST_EXPECT_TRUE(changedInputResults.size() == 1);
|
||||
|
||||
// always RELATIVE, always with the product name.
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[1].m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "android");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[1].m_platform == "android");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_data == "basefile.arc1");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[1].m_data == "basefile.arc2");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_type == AzFramework::AssetSystem::AssetNotificationMessage::AssetChanged);
|
||||
@@ -793,14 +795,14 @@ namespace AssetProcessor
|
||||
changedInputResults.clear();
|
||||
assetMessages.clear();
|
||||
|
||||
es3outs.clear();
|
||||
es3outs.push_back(cacheRoot.filePath(QString("es3/basefile.azm")));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs[0], "products."));
|
||||
androidouts.clear();
|
||||
androidouts.push_back(cacheRoot.filePath(QString("android/basefile.azm")));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts[0], "products."));
|
||||
|
||||
//Invoke Asset Processed for es3 platform , txt files2 job description
|
||||
//Invoke Asset Processed for android platform , txt files2 job description
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData()));
|
||||
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[1].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
@@ -812,7 +814,7 @@ namespace AssetProcessor
|
||||
UNIT_TEST_EXPECT_TRUE(changedInputResults.size() == 1);
|
||||
|
||||
// always RELATIVE, always with the product name.
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "android");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_data == "basefile.azm");
|
||||
|
||||
changedInputResults.clear();
|
||||
@@ -1002,11 +1004,11 @@ namespace AssetProcessor
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
// --------- same result as above ----------
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and es3,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and android,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_computedFingerprint != 0);
|
||||
@@ -1025,25 +1027,25 @@ namespace AssetProcessor
|
||||
|
||||
// this time make different products:
|
||||
|
||||
QStringList oldes3outs;
|
||||
QStringList oldandroidouts;
|
||||
QStringList oldpcouts;
|
||||
oldes3outs = es3outs;
|
||||
oldandroidouts = androidouts;
|
||||
oldpcouts.append(pcouts);
|
||||
QStringList es3outs2;
|
||||
QStringList androidouts2;
|
||||
QStringList pcouts2;
|
||||
es3outs.clear();
|
||||
androidouts.clear();
|
||||
pcouts.clear();
|
||||
es3outs.push_back(cacheRoot.filePath(QString("es3/basefilea.arc1")));
|
||||
es3outs2.push_back(cacheRoot.filePath(QString("es3/basefilea.azm")));
|
||||
// note that the ES3 outs have changed
|
||||
androidouts.push_back(cacheRoot.filePath(QString("android/basefilea.arc1")));
|
||||
androidouts2.push_back(cacheRoot.filePath(QString("android/basefilea.azm")));
|
||||
// note that the android outs have changed
|
||||
// but the pc outs are still the same.
|
||||
pcouts.push_back(cacheRoot.filePath(QString("pc/basefile.arc1")));
|
||||
pcouts2.push_back(cacheRoot.filePath(QString("pc/basefile.azm")));
|
||||
|
||||
// feed it the messages its waiting for (create the files)
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(pcouts[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs2[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts2[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(pcouts2[0], "newfile."));
|
||||
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents, 50);
|
||||
@@ -1055,12 +1057,12 @@ namespace AssetProcessor
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[0].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs2[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts2[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[1].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
@@ -1083,12 +1085,12 @@ namespace AssetProcessor
|
||||
// The files removed should be the ones we did not emit this time
|
||||
// note that order isn't guarantee but an example output it this
|
||||
|
||||
// [0] Removed: ES3, basefile.arc1
|
||||
// [1] Removed: ES3, basefile.arc2
|
||||
// [2] Changed: ES3, basefilea.arc1 (added)
|
||||
// [0] Removed: ANDROID, basefile.arc1
|
||||
// [1] Removed: ANDROID, basefile.arc2
|
||||
// [2] Changed: ANDROID, basefilea.arc1 (added)
|
||||
|
||||
// [3] Removed: ES3, basefile.azm
|
||||
// [4] Changed: ES3, basefilea.azm (added)
|
||||
// [3] Removed: ANDROID, basefile.azm
|
||||
// [4] Changed: ANDROID, basefilea.azm (added)
|
||||
|
||||
// [5] changed: PC, basefile.arc1 (changed)
|
||||
// [6] changed: PC, basefile.azm (changed)
|
||||
@@ -1110,18 +1112,18 @@ namespace AssetProcessor
|
||||
if (element.m_data == "basefilea.arc1")
|
||||
{
|
||||
UNIT_TEST_EXPECT_TRUE(element.m_type == AzFramework::AssetSystem::AssetNotificationMessage::AssetChanged);
|
||||
UNIT_TEST_EXPECT_TRUE(element.m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(element.m_platform == "android");
|
||||
}
|
||||
|
||||
if (element.m_data == "basefile.arc2")
|
||||
{
|
||||
UNIT_TEST_EXPECT_TRUE(element.m_type == AzFramework::AssetSystem::AssetNotificationMessage::AssetRemoved);
|
||||
UNIT_TEST_EXPECT_TRUE(element.m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(element.m_platform == "android");
|
||||
}
|
||||
}
|
||||
|
||||
// original products must no longer exist since it should have found and deleted them!
|
||||
for (QString outFile: oldes3outs)
|
||||
for (QString outFile: oldandroidouts)
|
||||
{
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(outFile));
|
||||
}
|
||||
@@ -1145,11 +1147,11 @@ namespace AssetProcessor
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
// --------- same result as above ----------
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // pc and es3
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // pc and android
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_computedFingerprint != 0);
|
||||
@@ -1169,12 +1171,12 @@ namespace AssetProcessor
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[0].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs2[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts2[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[1].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
@@ -1205,11 +1207,11 @@ namespace AssetProcessor
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
// --------- same result as above ----------
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and es3,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and android,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_computedFingerprint != 0);
|
||||
@@ -1220,12 +1222,12 @@ namespace AssetProcessor
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[0].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs2[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts2[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[1].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
@@ -1243,9 +1245,9 @@ namespace AssetProcessor
|
||||
|
||||
// deleting the fingerprint file should not have erased the products
|
||||
UNIT_TEST_EXPECT_TRUE(QFile::exists(pcouts[0]));
|
||||
UNIT_TEST_EXPECT_TRUE(QFile::exists(es3outs[0]));
|
||||
UNIT_TEST_EXPECT_TRUE(QFile::exists(androidouts[0]));
|
||||
UNIT_TEST_EXPECT_TRUE(QFile::exists(pcouts2[0]));
|
||||
UNIT_TEST_EXPECT_TRUE(QFile::exists(es3outs2[0]));
|
||||
UNIT_TEST_EXPECT_TRUE(QFile::exists(androidouts2[0]));
|
||||
|
||||
changedInputResults.clear();
|
||||
assetMessages.clear();
|
||||
@@ -1304,9 +1306,9 @@ namespace AssetProcessor
|
||||
}
|
||||
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(pcouts[0]));
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(es3outs[0]));
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(androidouts[0]));
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(pcouts2[0]));
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(es3outs2[0]));
|
||||
UNIT_TEST_EXPECT_FALSE(QFile::exists(androidouts2[0]));
|
||||
|
||||
changedInputResults.clear();
|
||||
assetMessages.clear();
|
||||
@@ -1321,28 +1323,28 @@ namespace AssetProcessor
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
// --------- same result as above ----------
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and es3,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and android,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_computedFingerprint != 0);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs2[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts2[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(pcouts2[0], "newfile."));
|
||||
|
||||
// send both done messages simultaneously!
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[0].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs2[0].toUtf8().constData()));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts2[0].toUtf8().constData()));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[1].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
// send one failure only for PC :
|
||||
@@ -1420,12 +1422,12 @@ namespace AssetProcessor
|
||||
UNIT_TEST_EXPECT_TRUE(changedInputResults.size() == 3);
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages.size() == 3);
|
||||
|
||||
// which should be for the ES3:
|
||||
// which should be for the ANDROID:
|
||||
UNIT_TEST_EXPECT_TRUE(AssetUtilities::NormalizeFilePath(changedInputResults[0].first) == absolutePath);
|
||||
|
||||
// always RELATIVE, always with the product name.
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_data == "basefilea.arc1" || assetMessages[0].m_data == "basefilea.azm");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "android");
|
||||
|
||||
for (auto& payload : payloadList)
|
||||
{
|
||||
@@ -1526,28 +1528,28 @@ namespace AssetProcessor
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
// --------- same result as above ----------
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and es3,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and android,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_computedFingerprint != 0);
|
||||
|
||||
es3outs.clear();
|
||||
es3outs2.clear();
|
||||
androidouts.clear();
|
||||
androidouts2.clear();
|
||||
pcouts.clear();
|
||||
pcouts2.clear();
|
||||
es3outs.push_back(cacheRoot.filePath(QString("es3/basefilez.arc2")));
|
||||
es3outs2.push_back(cacheRoot.filePath(QString("es3/basefileaz.azm2")));
|
||||
// note that the ES3 outs have changed
|
||||
androidouts.push_back(cacheRoot.filePath(QString("android/basefilez.arc2")));
|
||||
androidouts2.push_back(cacheRoot.filePath(QString("android/basefileaz.azm2")));
|
||||
// note that the android outs have changed
|
||||
// but the pc outs are still the same.
|
||||
pcouts.push_back(cacheRoot.filePath(QString("pc/basefile.arc2")));
|
||||
pcouts2.push_back(cacheRoot.filePath(QString("pc/basefile.azm2")));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(pcouts[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(es3outs2[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(androidouts2[0], "newfile."));
|
||||
UNIT_TEST_EXPECT_TRUE(CreateDummyFile(pcouts2[0], "newfile."));
|
||||
changedInputResults.clear();
|
||||
assetMessages.clear();
|
||||
@@ -1555,12 +1557,12 @@ namespace AssetProcessor
|
||||
// send all the done messages simultaneously:
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs[0].toUtf8().constData(), AZ::Uuid::CreateNull(), 1));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts[0].toUtf8().constData(), AZ::Uuid::CreateNull(), 1));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[0].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(es3outs2[0].toUtf8().constData(), AZ::Uuid::CreateNull(), 2));
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(androidouts2[0].toUtf8().constData(), AZ::Uuid::CreateNull(), 2));
|
||||
QMetaObject::invokeMethod(&apm, "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResults[1].m_jobEntry), Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
|
||||
|
||||
response.m_outputProducts.clear();
|
||||
@@ -1620,11 +1622,11 @@ namespace AssetProcessor
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
// --------- same result as above ----------
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and es3,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // 2 each for pc and android,since we have two recognizer for .txt file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_computedFingerprint != 0);
|
||||
@@ -1645,9 +1647,9 @@ namespace AssetProcessor
|
||||
absolutePath = watchFolderPath + "/" + relativePathFromWatchFolder;
|
||||
|
||||
unsigned int fingerprintForPC = 0;
|
||||
unsigned int fingerprintForES3 = 0;
|
||||
unsigned int fingerprintForANDROID = 0;
|
||||
|
||||
ComputeFingerprints(fingerprintForPC, fingerprintForES3, config, watchFolderPath, relativePathFromWatchFolder);
|
||||
ComputeFingerprints(fingerprintForPC, fingerprintForANDROID, config, watchFolderPath, relativePathFromWatchFolder);
|
||||
|
||||
processResults.clear();
|
||||
QMetaObject::invokeMethod(&apm, "AssessModifiedFile", Qt::QueuedConnection, Q_ARG(QString, absolutePath));
|
||||
@@ -1655,11 +1657,11 @@ namespace AssetProcessor
|
||||
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // // 2 each for pc and es3,since we have two recognizer for .xxx file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // // 2 each for pc and android,since we have two recognizer for .xxx file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
|
||||
@@ -1681,11 +1683,11 @@ namespace AssetProcessor
|
||||
// we never actually submitted any fingerprints or indicated success, so the same number of jobs should occur as before
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // // 2 each for pc and es3,since we have two recognizer for .xxx file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 4); // // 2 each for pc and android,since we have two recognizer for .xxx file
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[2].m_jobEntry.m_platformInfo.m_identifier == processResults[3].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[2].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[3].m_jobEntry.m_platformInfo.m_identifier == "pc"));
|
||||
|
||||
@@ -1705,7 +1707,7 @@ namespace AssetProcessor
|
||||
// now re-perform the same test, this time only the pc ones should re-appear.
|
||||
// this should happen because we're changing the extra params, which should be part of the fingerprint
|
||||
// if this unit test fails, check to make sure that the extra params are being ingested into the fingerprint computation functions
|
||||
// and also make sure that the jobs that are for the remaining es3 platform don't change.
|
||||
// and also make sure that the jobs that are for the remaining android platform don't change.
|
||||
|
||||
// store the UUID so that we can insert the new one with the same UUID
|
||||
AZStd::shared_ptr<InternalMockBuilder> builderTxt2Builder;
|
||||
@@ -1743,12 +1745,12 @@ namespace AssetProcessor
|
||||
// ---------------------
|
||||
|
||||
unsigned int newfingerprintForPC = 0;
|
||||
unsigned int newfingerprintForES3 = 0;
|
||||
unsigned int newfingerprintForANDROID = 0;
|
||||
|
||||
ComputeFingerprints(newfingerprintForPC, newfingerprintForES3, config, watchFolderPath, relativePathFromWatchFolder);
|
||||
ComputeFingerprints(newfingerprintForPC, newfingerprintForANDROID, config, watchFolderPath, relativePathFromWatchFolder);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(newfingerprintForPC != fingerprintForPC);//Fingerprints should be different
|
||||
UNIT_TEST_EXPECT_TRUE(newfingerprintForES3 == fingerprintForES3);//Fingerprints are same
|
||||
UNIT_TEST_EXPECT_TRUE(newfingerprintForANDROID == fingerprintForANDROID);//Fingerprints are same
|
||||
|
||||
config.RemoveRecognizer("xxx files 2 (builder2)");
|
||||
mockAppManager.UnRegisterAssetRecognizerAsBuilder("xxx files 2 (builder2)");
|
||||
@@ -1763,18 +1765,18 @@ namespace AssetProcessor
|
||||
absolutePath = AssetUtilities::NormalizeFilePath(absolutePath);
|
||||
QMetaObject::invokeMethod(&apm, "AssessModifiedFile", Qt::QueuedConnection, Q_ARG(QString, absolutePath));
|
||||
UNIT_TEST_EXPECT_TRUE(BlockUntil(idling, 5000));
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 2); // pc and es3
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 2); // pc and android
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier != processResults[1].m_jobEntry.m_platformInfo.m_identifier);
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "pc") || (processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "pc") || (processResults[1].m_jobEntry.m_platformInfo.m_identifier == "es3"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[0].m_jobEntry.m_platformInfo.m_identifier == "pc") || (processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
UNIT_TEST_EXPECT_TRUE((processResults[1].m_jobEntry.m_platformInfo.m_identifier == "pc") || (processResults[1].m_jobEntry.m_platformInfo.m_identifier == "android"));
|
||||
|
||||
unsigned int newfingerprintForPCAfterVersionChange = 0;
|
||||
unsigned int newfingerprintForES3AfterVersionChange = 0;
|
||||
unsigned int newfingerprintForANDROIDAfterVersionChange = 0;
|
||||
|
||||
ComputeFingerprints(newfingerprintForPCAfterVersionChange, newfingerprintForES3AfterVersionChange, config, watchFolderPath, relativePathFromWatchFolder);
|
||||
ComputeFingerprints(newfingerprintForPCAfterVersionChange, newfingerprintForANDROIDAfterVersionChange, config, watchFolderPath, relativePathFromWatchFolder);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE((newfingerprintForPCAfterVersionChange != fingerprintForPC) || (newfingerprintForPCAfterVersionChange != newfingerprintForPC));//Fingerprints should be different
|
||||
UNIT_TEST_EXPECT_TRUE((newfingerprintForES3AfterVersionChange != fingerprintForES3) || (newfingerprintForES3AfterVersionChange != newfingerprintForES3));//Fingerprints should be different
|
||||
UNIT_TEST_EXPECT_TRUE((newfingerprintForANDROIDAfterVersionChange != fingerprintForANDROID) || (newfingerprintForANDROIDAfterVersionChange != newfingerprintForANDROID));//Fingerprints should be different
|
||||
|
||||
//------Test for Files which are excluded
|
||||
processResults.clear();
|
||||
@@ -1919,7 +1921,7 @@ namespace AssetProcessor
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 0); // nothing to process
|
||||
|
||||
// we are aware that 4 products went missing (es3 and pc versions of the 2 files since we renamed the SOURCE folder)
|
||||
// we are aware that 4 products went missing (android and pc versions of the 2 files since we renamed the SOURCE folder)
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages.size() == 4);
|
||||
for (auto element : assetMessages)
|
||||
{
|
||||
@@ -2178,8 +2180,8 @@ namespace AssetProcessor
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[2].m_assetId != AZ::Data::AssetId());
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[3].m_assetId != AZ::Data::AssetId());
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[1].m_platform == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[0].m_platform == "android");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[1].m_platform == "android");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[2].m_platform == "pc");
|
||||
UNIT_TEST_EXPECT_TRUE(assetMessages[3].m_platform == "pc");
|
||||
|
||||
@@ -2212,12 +2214,12 @@ namespace AssetProcessor
|
||||
mockAppManager.UnRegisterAllBuilders();
|
||||
|
||||
AssetRecognizer abt_rec1;
|
||||
AssetPlatformSpec abt_speces3;
|
||||
AssetPlatformSpec abt_specandroid;
|
||||
abt_rec1.m_name = "UnitTestTextBuilder1";
|
||||
abt_rec1.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
//abt_rec1.m_regexp.setPatternSyntax(QRegExp::Wildcard);
|
||||
//abt_rec1.m_regexp.setPattern("*.txt");
|
||||
abt_rec1.m_platformSpecs.insert("es3", speces3);
|
||||
abt_rec1.m_platformSpecs.insert("android", specandroid);
|
||||
mockAppManager.RegisterAssetRecognizerAsBuilder(abt_rec1);
|
||||
|
||||
AssetRecognizer abt_rec2;
|
||||
@@ -2266,8 +2268,8 @@ namespace AssetProcessor
|
||||
|
||||
sortAssetToProcessResultList(processResults);
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 2); // 1 for pc and es3
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(processResults.size() == 2); // 1 for pc and android
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[0].m_jobEntry.m_platformInfo.m_identifier == "android");
|
||||
UNIT_TEST_EXPECT_TRUE(processResults[1].m_jobEntry.m_platformInfo.m_identifier == "pc");
|
||||
UNIT_TEST_EXPECT_TRUE(QString::compare(processResults[0].m_jobEntry.GetAbsoluteSourcePath(), absolutePath, Qt::CaseInsensitive) == 0);
|
||||
UNIT_TEST_EXPECT_TRUE(QString::compare(processResults[1].m_jobEntry.GetAbsoluteSourcePath(), absolutePath, Qt::CaseInsensitive) == 0);
|
||||
|
||||
@@ -17,16 +17,16 @@ void ConnectionUnitTest::StartTest()
|
||||
m_testConnection.SetAssetPlatformsString("pc");
|
||||
AzFramework::AssetSystem::AssetNotificationMessage testMessage;
|
||||
EXPECT_CALL(m_testConnection, Send(testing::_, testing::_)).Times(0);
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "osx_gl");
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "mac");
|
||||
EXPECT_CALL(m_testConnection, Send(testing::_, testing::_)).Times(1);
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "pc");
|
||||
m_testConnection.SetAssetPlatformsString("pc,es3");
|
||||
m_testConnection.SetAssetPlatformsString("pc,android");
|
||||
EXPECT_CALL(m_testConnection, Send(testing::_, testing::_)).Times(1);
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "pc");
|
||||
EXPECT_CALL(m_testConnection, Send(testing::_, testing::_)).Times(0);
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "osx_gl");
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "mac");
|
||||
EXPECT_CALL(m_testConnection, Send(testing::_, testing::_)).Times(1);
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "es3");
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "android");
|
||||
EXPECT_CALL(m_testConnection, Send(testing::_, testing::_)).Times(0);
|
||||
// Intended partial string match test - shouldn't send
|
||||
m_testConnection.SendPerPlatform(0, testMessage, "es");
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace AssetProcessor
|
||||
{
|
||||
}
|
||||
|
||||
bool Initialize([[maybe_unused]] const QString& systemRoot, [[maybe_unused]] const QString& rcExecutableFullPath) override
|
||||
bool Initialize() override
|
||||
{
|
||||
m_initialize++;
|
||||
return m_initializeResult;
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace AssetProcessor
|
||||
|
||||
size_t SendPerPlatform(unsigned int serial, const AzFramework::AssetSystem::BaseAssetProcessorMessage& message, const QString& platform) override
|
||||
{
|
||||
if (QString::compare(platform, "pc", Qt::CaseInsensitive) == 0 || QString::compare(platform, "es3", Qt::CaseInsensitive) == 0)
|
||||
if (QString::compare(platform, "pc", Qt::CaseInsensitive) == 0 || QString::compare(platform, "android", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
return Send(serial, message);
|
||||
}
|
||||
@@ -72,7 +72,7 @@ namespace AssetProcessor
|
||||
|
||||
size_t SendRawPerPlatform(unsigned int type, unsigned int serial, const QByteArray& data, const QString& platform) override
|
||||
{
|
||||
if (QString::compare(platform, "pc", Qt::CaseInsensitive) == 0 || QString::compare(platform, "es3", Qt::CaseInsensitive) == 0)
|
||||
if (QString::compare(platform, "pc", Qt::CaseInsensitive) == 0 || QString::compare(platform, "android", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
return SendRaw(type, serial, data);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ void PlatformConfigurationTests::StartTest()
|
||||
|
||||
PlatformConfiguration config;
|
||||
config.EnablePlatform({ "pc",{ "desktop", "host" } }, true);
|
||||
config.EnablePlatform({ "es3",{ "mobile", "android" } }, true);
|
||||
config.EnablePlatform({ "android",{ "mobile", "android" } }, true);
|
||||
config.EnablePlatform({ "fandago",{ "console" } }, false);
|
||||
AZStd::vector<AssetBuilderSDK::PlatformInfo> platforms;
|
||||
config.PopulatePlatformsForScanFolder(platforms);
|
||||
@@ -88,15 +88,15 @@ void PlatformConfigurationTests::StartTest()
|
||||
|
||||
AssetRecognizer rec;
|
||||
AssetPlatformSpec specpc;
|
||||
AssetPlatformSpec speces3;
|
||||
AssetPlatformSpec specandroid;
|
||||
AssetPlatformSpec specfandago;
|
||||
specpc.m_extraRCParams = ""; // blank must work
|
||||
speces3.m_extraRCParams = "testextraparams";
|
||||
specandroid.m_extraRCParams = "testextraparams";
|
||||
|
||||
rec.m_name = "txt files";
|
||||
rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
|
||||
rec.m_platformSpecs.insert("pc", specpc);
|
||||
rec.m_platformSpecs.insert("es3", speces3);
|
||||
rec.m_platformSpecs.insert("android", specandroid);
|
||||
rec.m_platformSpecs.insert("fandago", specfandago);
|
||||
config.AddRecognizer(rec);
|
||||
|
||||
@@ -111,7 +111,7 @@ void PlatformConfigurationTests::StartTest()
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(config.GetEnabledPlatforms().size() == 2);
|
||||
UNIT_TEST_EXPECT_TRUE(config.GetEnabledPlatforms()[0].m_identifier == "pc");
|
||||
UNIT_TEST_EXPECT_TRUE(config.GetEnabledPlatforms()[1].m_identifier == "es3");
|
||||
UNIT_TEST_EXPECT_TRUE(config.GetEnabledPlatforms()[1].m_identifier == "android");
|
||||
|
||||
UNIT_TEST_EXPECT_TRUE(config.GetScanFolderCount() == 11);
|
||||
UNIT_TEST_EXPECT_FALSE(config.GetScanFolderAt(0).IsRoot());
|
||||
|
||||
@@ -239,14 +239,14 @@ void RCcontrollerUnitTests::RunRCControllerTests()
|
||||
createdJobs.push_back(job);
|
||||
}
|
||||
|
||||
// double them up for "es3" to make sure that platform is respected
|
||||
// double them up for "android" to make sure that platform is respected
|
||||
for (QString name : tempJobNames)
|
||||
{
|
||||
AZ::Uuid uuidOfSource = AZ::Uuid::CreateName(name.toUtf8().constData());
|
||||
RCJob* job0 = new RCJob(rcJobListModel);
|
||||
AssetProcessor::JobDetails jobDetails;
|
||||
jobDetails.m_jobEntry.m_databaseSourceName = jobDetails.m_jobEntry.m_pathRelativeToWatchFolder = name;
|
||||
jobDetails.m_jobEntry.m_platformInfo = { "es3" ,{ "mobile", "renderer" } };
|
||||
jobDetails.m_jobEntry.m_platformInfo = { "android" ,{ "mobile", "renderer" } };
|
||||
jobDetails.m_jobEntry.m_jobKey = "Compile Other Stuff";
|
||||
jobDetails.m_jobEntry.m_sourceFileUUID = uuidOfSource;
|
||||
job0->Init(jobDetails);
|
||||
@@ -490,7 +490,7 @@ void RCcontrollerUnitTests::RunRCControllerTests()
|
||||
UNIT_TEST_EXPECT_FALSE(gotJobsInQueueCall);
|
||||
|
||||
// submit same job but different platform:
|
||||
details.m_jobEntry = JobEntry("d:/test", "test1.txt", "test1.txt", AZ::Uuid("{7954065D-CFD1-4666-9E4C-3F36F417C7AC}"), { "es3" ,{ "mobile", "renderer" } }, "Test Job", 1234, 3, sourceId);
|
||||
details.m_jobEntry = JobEntry("d:/test", "test1.txt", "test1.txt", AZ::Uuid("{7954065D-CFD1-4666-9E4C-3F36F417C7AC}"), { "android" ,{ "mobile", "renderer" } }, "Test Job", 1234, 3, sourceId);
|
||||
m_rcController.JobSubmitted(details);
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace UnitTestUtils
|
||||
{
|
||||
void SleepForMinimumFileSystemTime()
|
||||
{
|
||||
// note that on OSX, the file system has a resolution of 1 second, and since we're using modtime for a bunch of things,
|
||||
// note that on Mac, the file system has a resolution of 1 second, and since we're using modtime for a bunch of things,
|
||||
// not the actual hash files, we have to wait different amount depending on the OS.
|
||||
#ifdef AZ_PLATFORM_WINDOWS
|
||||
int milliseconds = 1;
|
||||
|
||||
@@ -622,13 +622,14 @@ bool ApplicationManager::Activate()
|
||||
{
|
||||
if (!AssetUtilities::ComputeAssetRoot(m_systemRoot))
|
||||
{
|
||||
AZ_Error(AssetProcessor::ConsoleChannel, false, "Unable to compute the asset root for the project, this application cannot launch until this is fixed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto projectName = AssetUtilities::ComputeProjectName();
|
||||
if (projectName.isEmpty())
|
||||
{
|
||||
AZ_Error(AssetProcessor::ConsoleChannel, false, "Unable to detect name of current game project. Is bootstrap.cfg appropriately configured?");
|
||||
AZ_Error(AssetProcessor::ConsoleChannel, false, "Unable to detect name of current game project. Configure your game project name to launch this application.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1191,6 +1191,7 @@ bool ApplicationManagerBase::Activate()
|
||||
QDir projectCache;
|
||||
if (!AssetUtilities::ComputeProjectCacheRoot(projectCache))
|
||||
{
|
||||
AZ_Error("AssetProcessor", false, "Could not compute project cache root, please configure your project correctly to launch Asset Processor.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1200,22 +1201,27 @@ bool ApplicationManagerBase::Activate()
|
||||
// Shutdown if the disk has less than 128MB of free space
|
||||
if (!CheckSufficientDiskSpace(projectCache.absolutePath(), 128 * 1024 * 1024, true))
|
||||
{
|
||||
// CheckSufficientDiskSpace reports an error if disk space is low.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool appInited = InitApplicationServer();
|
||||
if (!appInited)
|
||||
{
|
||||
AZ_Error(
|
||||
"AssetProcessor", false, "InitApplicationServer failed, something internal to Asset Processor has failed, please report this to support if you encounter this error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!InitAssetDatabase())
|
||||
{
|
||||
// AssetDatabaseConnection::OpenDatabase reports any errors it encounters.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ApplicationManager::Activate())
|
||||
{
|
||||
// ApplicationManager::Activate() reports any errors it encounters.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1230,6 +1236,7 @@ bool ApplicationManagerBase::Activate()
|
||||
m_isCurrentlyLoadingGems = true;
|
||||
if (!ActivateModules())
|
||||
{
|
||||
// ActivateModules reports any errors it encounters.
|
||||
m_isCurrentlyLoadingGems = false;
|
||||
return false;
|
||||
}
|
||||
@@ -1299,6 +1306,7 @@ bool ApplicationManagerBase::Activate()
|
||||
{
|
||||
if (!m_applicationServer->startListening())
|
||||
{
|
||||
// startListening reports any errors it encounters.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -5,11 +5,11 @@
|
||||
"Platform pc": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform osx_gl": {
|
||||
"Platform mac": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platforms": {
|
||||
"es3": "enabled"
|
||||
"android": "enabled"
|
||||
},
|
||||
"ScanFolder Game": {
|
||||
"watch": "@PROJECTROOT@",
|
||||
|
||||
Vendored
+1
-1
@@ -5,7 +5,7 @@
|
||||
"Platform pc": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform osx_gl": {
|
||||
"Platform mac": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"RC i_caf": {
|
||||
|
||||
Vendored
+1
-1
@@ -5,7 +5,7 @@
|
||||
"Platform pc": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform osx_gl": {
|
||||
"Platform mac": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"ScanFolder Game": {
|
||||
|
||||
+5
-5
@@ -5,17 +5,17 @@
|
||||
"Platform pc": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform es3": {
|
||||
"Platform android": {
|
||||
"tags": "android,mobile,renderer"
|
||||
},
|
||||
"Platform osx_gl": {
|
||||
"Platform mac": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform server": {
|
||||
"tags": "server"
|
||||
},
|
||||
"Platforms": {
|
||||
"es3": "enabled",
|
||||
"android": "enabled",
|
||||
"server": "enabled"
|
||||
},
|
||||
"Jobs": {
|
||||
@@ -56,7 +56,7 @@
|
||||
"glob": "*.i_caf",
|
||||
"params": "defaultparams",
|
||||
"server": "skip",
|
||||
"es3": "mobile",
|
||||
"android": "mobile",
|
||||
"priority": 5,
|
||||
"checkServer": true
|
||||
},
|
||||
@@ -68,7 +68,7 @@
|
||||
"RC mov": {
|
||||
"glob": "*.mov",
|
||||
"params": "copy",
|
||||
"es3": "platformspecificoverride",
|
||||
"android": "platformspecificoverride",
|
||||
"renderer": "rendererparams"
|
||||
},
|
||||
"RC rend": {
|
||||
|
||||
+7
-7
@@ -5,13 +5,13 @@
|
||||
"Platform pc": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform es3": {
|
||||
"Platform android": {
|
||||
"tags": "android,mobile,renderer"
|
||||
},
|
||||
"Platform ios": {
|
||||
"tags": "mobile,renderer"
|
||||
},
|
||||
"Platform osx_gl": {
|
||||
"Platform mac": {
|
||||
"tags": "tools,renderer"
|
||||
},
|
||||
"Platform server": {
|
||||
@@ -21,7 +21,7 @@
|
||||
"tags": "console,renderer"
|
||||
},
|
||||
"Platforms": {
|
||||
"es3": "enabled",
|
||||
"android": "enabled",
|
||||
"ios": "enabled",
|
||||
"server": "enabled"
|
||||
},
|
||||
@@ -54,14 +54,14 @@
|
||||
"display": "folder1output",
|
||||
"recursive": 1,
|
||||
"order": 50000,
|
||||
"include": "es3"
|
||||
"include": "android"
|
||||
},
|
||||
"ScanFolder Folder2": {
|
||||
"watch": "@ENGINEROOT@/Folder2",
|
||||
"display": "folder2output",
|
||||
"recursive": 1,
|
||||
"order": 60000,
|
||||
"exclude": "es3"
|
||||
"exclude": "android"
|
||||
},
|
||||
"ScanFolder Folder3": {
|
||||
"watch": "@ENGINEROOT@/Folder3",
|
||||
@@ -80,7 +80,7 @@
|
||||
"glob": "*.i_caf",
|
||||
"params": "defaultparams",
|
||||
"server": "skip",
|
||||
"es3": "mobile",
|
||||
"android": "mobile",
|
||||
"test": "copy",
|
||||
"priority": 5
|
||||
},
|
||||
@@ -92,7 +92,7 @@
|
||||
"RC mov": {
|
||||
"glob": "*.mov",
|
||||
"params": "copy",
|
||||
"es3": "platformspecificoverride",
|
||||
"android": "platformspecificoverride",
|
||||
"renderer": "rendererparams"
|
||||
},
|
||||
"RC rend": {
|
||||
|
||||
@@ -14,8 +14,6 @@ add_subdirectory(AssetProcessor)
|
||||
add_subdirectory(AWSNativeSDKInit)
|
||||
add_subdirectory(AzTestRunner)
|
||||
add_subdirectory(CrashHandler)
|
||||
add_subdirectory(CryCommonTools)
|
||||
add_subdirectory(CryXML)
|
||||
add_subdirectory(News)
|
||||
add_subdirectory(PythonBindingsExample)
|
||||
add_subdirectory(RemoteConsole)
|
||||
|
||||
@@ -1,56 +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.
|
||||
#
|
||||
|
||||
if (NOT PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
|
||||
ly_add_target(
|
||||
NAME CryCommonTools STATIC
|
||||
NAMESPACE Legacy
|
||||
FILES_CMAKE
|
||||
crycommontools_files.cmake
|
||||
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
.
|
||||
${pal_dir}
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::lz4
|
||||
3rdParty::zlib
|
||||
3rdParty::zstd
|
||||
AZ::AzCore
|
||||
PUBLIC
|
||||
Legacy::CryCommon
|
||||
AZ::AzFramework
|
||||
)
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
ly_add_target(
|
||||
NAME CryCommonTools.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE Legacy
|
||||
FILES_CMAKE
|
||||
crycommontools_tests_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
UnitTests
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Legacy::CryCommonTools
|
||||
AZ::AzTest
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME Legacy::CryCommonTools.Tests
|
||||
)
|
||||
endif()
|
||||
@@ -1,18 +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.
|
||||
*
|
||||
*/
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_COLLADASHARED_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_COLLADASHARED_H
|
||||
#pragma once
|
||||
|
||||
static const char* g_LumberyardExportNodeTag = "LumberyardExportNode";
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_COLLADASHARED_H
|
||||
@@ -1,514 +0,0 @@
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
// Taken from http://tog.acm.org/GraphicsGems/gemsiv/polar_decomp/Decompose.c
|
||||
|
||||
/**** Decompose.c ****/
|
||||
/* Ken Shoemake, 1993 */
|
||||
#include <math.h>
|
||||
#include "Decompose.h"
|
||||
|
||||
#pragma warning(disable:4244) // conversion from 'double' to 'float', possible loss of data
|
||||
#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float'
|
||||
|
||||
namespace decomp {
|
||||
|
||||
/******* Matrix Preliminaries *******/
|
||||
|
||||
/** Fill out 3x3 matrix to 4x4 **/
|
||||
#define mat_pad(A) (A[W][X]=A[X][W]=A[W][Y]=A[Y][W]=A[W][Z]=A[Z][W]=0,A[W][W]=1)
|
||||
|
||||
/** Copy nxn matrix A to C using "gets" for assignment **/
|
||||
#define mat_copy(C,gets,A,n) {int i,j; for(i=0;i<n;i++) for(j=0;j<n;j++)\
|
||||
C[i][j] gets (A[i][j]);}
|
||||
|
||||
/** Copy transpose of nxn matrix A to C using "gets" for assignment **/
|
||||
#define mat_tpose(AT,gets,A,n) {int i,j; for(i=0;i<n;i++) for(j=0;j<n;j++)\
|
||||
AT[i][j] gets (A[j][i]);}
|
||||
|
||||
/** Assign nxn matrix C the element-wise combination of A and B using "op" **/
|
||||
#define mat_binop(C,gets,A,op,B,n) {int i,j; for(i=0;i<n;i++) for(j=0;j<n;j++)\
|
||||
C[i][j] gets (A[i][j]) op (B[i][j]);}
|
||||
|
||||
/** Multiply the upper left 3x3 parts of A and B to get AB **/
|
||||
void mat_mult(HMatrix A, HMatrix B, HMatrix AB)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++)
|
||||
AB[i][j] = A[i][0] * B[0][j] + A[i][1] * B[1][j] + A[i][2] * B[2][j];
|
||||
}
|
||||
|
||||
/** Return dot product of length 3 vectors va and vb **/
|
||||
float vdot(float* va, float* vb)
|
||||
{
|
||||
return (va[0] * vb[0] + va[1] * vb[1] + va[2] * vb[2]);
|
||||
}
|
||||
|
||||
/** Set v to cross product of length 3 vectors va and vb **/
|
||||
void vcross(float* va, float* vb, float* v)
|
||||
{
|
||||
v[0] = va[1] * vb[2] - va[2] * vb[1];
|
||||
v[1] = va[2] * vb[0] - va[0] * vb[2];
|
||||
v[2] = va[0] * vb[1] - va[1] * vb[0];
|
||||
}
|
||||
|
||||
/** Set MadjT to transpose of inverse of M times determinant of M **/
|
||||
void adjoint_transpose(HMatrix M, HMatrix MadjT)
|
||||
{
|
||||
vcross(M[1], M[2], MadjT[0]);
|
||||
vcross(M[2], M[0], MadjT[1]);
|
||||
vcross(M[0], M[1], MadjT[2]);
|
||||
}
|
||||
|
||||
/******* Quaternion Preliminaries *******/
|
||||
|
||||
/* Construct a (possibly non-unit) quaternion from real components. */
|
||||
Quat Qt_(float x, float y, float z, float w)
|
||||
{
|
||||
Quat qq;
|
||||
qq.x = x; qq.y = y; qq.z = z; qq.w = w;
|
||||
return (qq);
|
||||
}
|
||||
|
||||
/* Return conjugate of quaternion. */
|
||||
Quat Qt_Conj(Quat q)
|
||||
{
|
||||
Quat qq;
|
||||
qq.x = -q.x; qq.y = -q.y; qq.z = -q.z; qq.w = q.w;
|
||||
return (qq);
|
||||
}
|
||||
|
||||
/* Return quaternion product qL * qR. Note: order is important!
|
||||
* To combine rotations, use the product Mul(qSecond, qFirst),
|
||||
* which gives the effect of rotating by qFirst then qSecond. */
|
||||
Quat Qt_Mul(Quat qL, Quat qR)
|
||||
{
|
||||
Quat qq;
|
||||
qq.w = qL.w * qR.w - qL.x * qR.x - qL.y * qR.y - qL.z * qR.z;
|
||||
qq.x = qL.w * qR.x + qL.x * qR.w + qL.y * qR.z - qL.z * qR.y;
|
||||
qq.y = qL.w * qR.y + qL.y * qR.w + qL.z * qR.x - qL.x * qR.z;
|
||||
qq.z = qL.w * qR.z + qL.z * qR.w + qL.x * qR.y - qL.y * qR.x;
|
||||
return (qq);
|
||||
}
|
||||
|
||||
/* Return product of quaternion q by scalar w. */
|
||||
Quat Qt_Scale(Quat q, float w)
|
||||
{
|
||||
Quat qq;
|
||||
qq.w = q.w * w; qq.x = q.x * w; qq.y = q.y * w; qq.z = q.z * w;
|
||||
return (qq);
|
||||
}
|
||||
|
||||
/* Construct a unit quaternion from rotation matrix. Assumes matrix is
|
||||
* used to multiply column vector on the left: vnew = mat vold. Works
|
||||
* correctly for right-handed coordinate system and right-handed rotations.
|
||||
* Translation and perspective components ignored. */
|
||||
Quat Qt_FromMatrix(HMatrix mat)
|
||||
{
|
||||
/* This algorithm avoids near-zero divides by looking for a large component
|
||||
* - first w, then x, y, or z. When the trace is greater than zero,
|
||||
* |w| is greater than 1/2, which is as small as a largest component can be.
|
||||
* Otherwise, the largest diagonal entry corresponds to the largest of |x|,
|
||||
* |y|, or |z|, one of which must be larger than |w|, and at least 1/2. */
|
||||
Quat qu;
|
||||
double tr, s;
|
||||
|
||||
tr = mat[X][X] + mat[Y][Y] + mat[Z][Z];
|
||||
if (tr >= 0.0) {
|
||||
s = sqrt(tr + mat[W][W]);
|
||||
qu.w = s * 0.5;
|
||||
s = 0.5 / s;
|
||||
qu.x = (mat[Z][Y] - mat[Y][Z]) * s;
|
||||
qu.y = (mat[X][Z] - mat[Z][X]) * s;
|
||||
qu.z = (mat[Y][X] - mat[X][Y]) * s;
|
||||
} else {
|
||||
int h = X;
|
||||
if (mat[Y][Y] > mat[X][X]) h = Y;
|
||||
if (mat[Z][Z] > mat[h][h]) h = Z;
|
||||
switch (h) {
|
||||
#define caseMacro(i,j,k,I,J,K) \
|
||||
case I:\
|
||||
s = sqrt( (mat[I][I] - (mat[J][J]+mat[K][K])) + mat[W][W] );\
|
||||
qu.i = s*0.5;\
|
||||
s = 0.5 / s;\
|
||||
qu.j = (mat[I][J] + mat[J][I]) * s;\
|
||||
qu.k = (mat[K][I] + mat[I][K]) * s;\
|
||||
qu.w = (mat[K][J] - mat[J][K]) * s;\
|
||||
break
|
||||
caseMacro(x, y, z, X, Y, Z);
|
||||
caseMacro(y, z, x, Y, Z, X);
|
||||
caseMacro(z, x, y, Z, X, Y);
|
||||
}
|
||||
}
|
||||
if (mat[W][W] != 1.0) qu = Qt_Scale(qu, 1 / sqrt(mat[W][W]));
|
||||
return (qu);
|
||||
}
|
||||
/******* Decomp Auxiliaries *******/
|
||||
|
||||
static HMatrix mat_id = { {1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} };
|
||||
|
||||
/** Compute either the 1 or infinity norm of M, depending on tpose **/
|
||||
float mat_norm(HMatrix M, int tpose)
|
||||
{
|
||||
int i;
|
||||
float sum, max;
|
||||
max = 0.0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (tpose) sum = fabs(M[0][i]) + fabs(M[1][i]) + fabs(M[2][i]);
|
||||
else sum = fabs(M[i][0]) + fabs(M[i][1]) + fabs(M[i][2]);
|
||||
if (max < sum) max = sum;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
float norm_inf(HMatrix M) { return mat_norm(M, 0); }
|
||||
float norm_one(HMatrix M) { return mat_norm(M, 1); }
|
||||
|
||||
/** Return index of column of M containing maximum abs entry, or -1 if M=0 **/
|
||||
int find_max_col(HMatrix M)
|
||||
{
|
||||
float abs, max;
|
||||
int i, j, col;
|
||||
max = 0.0; col = -1;
|
||||
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) {
|
||||
abs = M[i][j]; if (abs < 0.0) abs = -abs;
|
||||
if (abs > max) { max = abs; col = j; }
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
/** Setup u for Household reflection to zero all v components but first **/
|
||||
void make_reflector(float* v, float* u)
|
||||
{
|
||||
float s = sqrt(vdot(v, v));
|
||||
u[0] = v[0]; u[1] = v[1];
|
||||
u[2] = v[2] + ((v[2] < 0.0) ? -s : s);
|
||||
s = sqrt(2.0 / vdot(u, u));
|
||||
u[0] = u[0] * s; u[1] = u[1] * s; u[2] = u[2] * s;
|
||||
}
|
||||
|
||||
/** Apply Householder reflection represented by u to column vectors of M **/
|
||||
void reflect_cols(HMatrix M, float* u)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++) {
|
||||
float s = u[0] * M[0][i] + u[1] * M[1][i] + u[2] * M[2][i];
|
||||
for (j = 0; j < 3; j++) M[j][i] -= u[j] * s;
|
||||
}
|
||||
}
|
||||
/** Apply Householder reflection represented by u to row vectors of M **/
|
||||
void reflect_rows(HMatrix M, float* u)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++) {
|
||||
float s = vdot(u, M[i]);
|
||||
for (j = 0; j < 3; j++) M[i][j] -= u[j] * s;
|
||||
}
|
||||
}
|
||||
|
||||
/** Find orthogonal factor Q of rank 1 (or less) M **/
|
||||
void do_rank1(HMatrix M, HMatrix Q)
|
||||
{
|
||||
float v1[3], v2[3], s;
|
||||
int col;
|
||||
mat_copy(Q, =, mat_id, 4);
|
||||
/* If rank(M) is 1, we should find a non-zero column in M */
|
||||
col = find_max_col(M);
|
||||
if (col < 0) return; /* Rank is 0 */
|
||||
v1[0] = M[0][col]; v1[1] = M[1][col]; v1[2] = M[2][col];
|
||||
make_reflector(v1, v1); reflect_cols(M, v1);
|
||||
v2[0] = M[2][0]; v2[1] = M[2][1]; v2[2] = M[2][2];
|
||||
make_reflector(v2, v2); reflect_rows(M, v2);
|
||||
s = M[2][2];
|
||||
if (s < 0.0) Q[2][2] = -1.0;
|
||||
reflect_cols(Q, v1); reflect_rows(Q, v2);
|
||||
}
|
||||
|
||||
/** Find orthogonal factor Q of rank 2 (or less) M using adjoint transpose **/
|
||||
void do_rank2(HMatrix M, HMatrix MadjT, HMatrix Q)
|
||||
{
|
||||
float v1[3], v2[3];
|
||||
float w, x, y, z, c, s, d;
|
||||
int col;
|
||||
/* If rank(M) is 2, we should find a non-zero column in MadjT */
|
||||
col = find_max_col(MadjT);
|
||||
if (col < 0) { do_rank1(M, Q); return; } /* Rank<2 */
|
||||
v1[0] = MadjT[0][col]; v1[1] = MadjT[1][col]; v1[2] = MadjT[2][col];
|
||||
make_reflector(v1, v1); reflect_cols(M, v1);
|
||||
vcross(M[0], M[1], v2);
|
||||
make_reflector(v2, v2); reflect_rows(M, v2);
|
||||
w = M[0][0]; x = M[0][1]; y = M[1][0]; z = M[1][1];
|
||||
if (w * z > x* y) {
|
||||
c = z + w; s = y - x; d = sqrt(c * c + s * s); c = c / d; s = s / d;
|
||||
Q[0][0] = Q[1][1] = c; Q[0][1] = -(Q[1][0] = s);
|
||||
} else {
|
||||
c = z - w; s = y + x; d = sqrt(c * c + s * s); c = c / d; s = s / d;
|
||||
Q[0][0] = -(Q[1][1] = c); Q[0][1] = Q[1][0] = s;
|
||||
}
|
||||
Q[0][2] = Q[2][0] = Q[1][2] = Q[2][1] = 0.0; Q[2][2] = 1.0;
|
||||
reflect_cols(Q, v1); reflect_rows(Q, v2);
|
||||
}
|
||||
|
||||
|
||||
/******* Polar Decomposition *******/
|
||||
|
||||
/* Polar Decomposition of 3x3 matrix in 4x4,
|
||||
* M = QS. See Nicholas Higham and Robert S. Schreiber,
|
||||
* Fast Polar Decomposition of An Arbitrary Matrix,
|
||||
* Technical Report 88-942, October 1988,
|
||||
* Department of Computer Science, Cornell University.
|
||||
*/
|
||||
float polar_decomp(HMatrix M, HMatrix Q, HMatrix S)
|
||||
{
|
||||
#define TOL 1.0e-6
|
||||
HMatrix Mk, MadjTk, Ek;
|
||||
float det, M_one, M_inf, MadjT_one, MadjT_inf, E_one, gamma, g1, g2;
|
||||
int i, j;
|
||||
mat_tpose(Mk, =, M, 3);
|
||||
M_one = norm_one(Mk); M_inf = norm_inf(Mk);
|
||||
do {
|
||||
adjoint_transpose(Mk, MadjTk);
|
||||
det = vdot(Mk[0], MadjTk[0]);
|
||||
if (det == 0.0) { do_rank2(Mk, MadjTk, Mk); break; }
|
||||
MadjT_one = norm_one(MadjTk); MadjT_inf = norm_inf(MadjTk);
|
||||
gamma = sqrt(sqrt((MadjT_one * MadjT_inf) / (M_one * M_inf)) / fabs(det));
|
||||
g1 = gamma * 0.5;
|
||||
g2 = 0.5 / (gamma * det);
|
||||
mat_copy(Ek, =, Mk, 3);
|
||||
mat_binop(Mk, =, g1 * Mk, +, g2 * MadjTk, 3);
|
||||
mat_copy(Ek, -=, Mk, 3);
|
||||
E_one = norm_one(Ek);
|
||||
M_one = norm_one(Mk); M_inf = norm_inf(Mk);
|
||||
} while (E_one > (M_one * TOL));
|
||||
mat_tpose(Q, =, Mk, 3); mat_pad(Q);
|
||||
mat_mult(Mk, M, S); mat_pad(S);
|
||||
for (i = 0; i < 3; i++) for (j = i; j < 3; j++)
|
||||
S[i][j] = S[j][i] = 0.5 * (S[i][j] + S[j][i]);
|
||||
return (det);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******* Spectral Decomposition *******/
|
||||
|
||||
/* Compute the spectral decomposition of symmetric positive semi-definite S.
|
||||
* Returns rotation in U and scale factors in result, so that if K is a diagonal
|
||||
* matrix of the scale factors, then S = U K (U transpose). Uses Jacobi method.
|
||||
* See Gene H. Golub and Charles F. Van Loan. Matrix Computations. Hopkins 1983.
|
||||
*/
|
||||
HVect spect_decomp(HMatrix S, HMatrix U)
|
||||
{
|
||||
HVect kv;
|
||||
double Diag[3], OffD[3]; /* OffD is off-diag (by omitted index) */
|
||||
double g, h, fabsh, fabsOffDi, t, theta, c, s, tau, ta, OffDq, a, b;
|
||||
static char nxt[] = { Y,Z,X };
|
||||
int sweep, i, j;
|
||||
mat_copy(U, =, mat_id, 4);
|
||||
Diag[X] = S[X][X]; Diag[Y] = S[Y][Y]; Diag[Z] = S[Z][Z];
|
||||
OffD[X] = S[Y][Z]; OffD[Y] = S[Z][X]; OffD[Z] = S[X][Y];
|
||||
for (sweep = 20; sweep > 0; sweep--) {
|
||||
float sm = fabs(OffD[X]) + fabs(OffD[Y]) + fabs(OffD[Z]);
|
||||
if (sm == 0.0) break;
|
||||
for (i = Z; i >= X; i--) {
|
||||
int p = nxt[i]; int q = nxt[p];
|
||||
fabsOffDi = fabs(OffD[i]);
|
||||
g = 100.0 * fabsOffDi;
|
||||
if (fabsOffDi > 0.0) {
|
||||
h = Diag[q] - Diag[p];
|
||||
fabsh = fabs(h);
|
||||
if (fabsh + g == fabsh) {
|
||||
t = OffD[i] / h;
|
||||
} else {
|
||||
theta = 0.5 * h / OffD[i];
|
||||
t = 1.0 / (fabs(theta) + sqrt(theta * theta + 1.0));
|
||||
if (theta < 0.0) t = -t;
|
||||
}
|
||||
c = 1.0 / sqrt(t * t + 1.0); s = t * c;
|
||||
tau = s / (c + 1.0);
|
||||
ta = t * OffD[i]; OffD[i] = 0.0;
|
||||
Diag[p] -= ta; Diag[q] += ta;
|
||||
OffDq = OffD[q];
|
||||
OffD[q] -= s * (OffD[p] + tau * OffD[q]);
|
||||
OffD[p] += s * (OffDq - tau * OffD[p]);
|
||||
for (j = Z; j >= X; j--) {
|
||||
a = U[j][p]; b = U[j][q];
|
||||
U[j][p] -= s * (b + tau * a);
|
||||
U[j][q] += s * (a - tau * b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
kv.x = Diag[X]; kv.y = Diag[Y]; kv.z = Diag[Z]; kv.w = 1.0;
|
||||
return (kv);
|
||||
}
|
||||
|
||||
/******* Spectral Axis Adjustment *******/
|
||||
|
||||
/* Given a unit quaternion, q, and a scale vector, k, find a unit quaternion, p,
|
||||
* which permutes the axes and turns freely in the plane of duplicate scale
|
||||
* factors, such that q p has the largest possible w component, i.e. the
|
||||
* smallest possible angle. Permutes k's components to go with q p instead of q.
|
||||
* See Ken Shoemake and Tom Duff. Matrix Animation and Polar Decomposition.
|
||||
* Proceedings of Graphics Interface 1992. Details on p. 262-263.
|
||||
*/
|
||||
Quat snuggle(Quat q, HVect* k)
|
||||
{
|
||||
#define SQRTHALF (0.7071067811865475244f)
|
||||
#define sgn(n,v) ((n)?-(v):(v))
|
||||
#define swap(a,i,j) {a[3]=a[i]; a[i]=a[j]; a[j]=a[3];}
|
||||
#define cycle(a,p) if (p) {a[3]=a[0]; a[0]=a[1]; a[1]=a[2]; a[2]=a[3];}\
|
||||
else {a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; a[0]=a[3];}
|
||||
Quat p;
|
||||
float ka[4];
|
||||
int i, turn = -1;
|
||||
ka[X] = k->x; ka[Y] = k->y; ka[Z] = k->z;
|
||||
if (ka[X] == ka[Y]) { if (ka[X] == ka[Z]) turn = W; else turn = Z; }
|
||||
else { if (ka[X] == ka[Z]) turn = Y; else if (ka[Y] == ka[Z]) turn = X; }
|
||||
if (turn >= 0) {
|
||||
Quat qtoz, qp;
|
||||
unsigned neg[3], win;
|
||||
double mag[3], t;
|
||||
static Quat qxtoz = { 0,SQRTHALF,0,SQRTHALF };
|
||||
static Quat qytoz = { SQRTHALF,0,0,SQRTHALF };
|
||||
static Quat qppmm = { 0.5, 0.5,-0.5,-0.5 };
|
||||
static Quat qpppp = { 0.5, 0.5, 0.5, 0.5 };
|
||||
static Quat qmpmm = { -0.5, 0.5,-0.5,-0.5 };
|
||||
static Quat qpppm = { 0.5, 0.5, 0.5,-0.5 };
|
||||
static Quat q0001 = { 0.0, 0.0, 0.0, 1.0 };
|
||||
static Quat q1000 = { 1.0, 0.0, 0.0, 0.0 };
|
||||
switch (turn) {
|
||||
default: return (Qt_Conj(q));
|
||||
case X: q = Qt_Mul(q, qtoz = qxtoz); swap(ka, X, Z) break;
|
||||
case Y: q = Qt_Mul(q, qtoz = qytoz); swap(ka, Y, Z) break;
|
||||
case Z: qtoz = q0001; break;
|
||||
}
|
||||
q = Qt_Conj(q);
|
||||
mag[0] = (double)q.z * q.z + (double)q.w * q.w - 0.5;
|
||||
mag[1] = (double)q.x * q.z - (double)q.y * q.w;
|
||||
mag[2] = (double)q.y * q.z + (double)q.x * q.w;
|
||||
for (i = 0; i < 3; i++) if (neg[i] = (mag[i] < 0.0)) mag[i] = -mag[i];
|
||||
if (mag[0] > mag[1]) { if (mag[0] > mag[2]) win = 0; else win = 2; }
|
||||
else { if (mag[1] > mag[2]) win = 1; else win = 2; }
|
||||
switch (win) {
|
||||
case 0: if (neg[0]) p = q1000; else p = q0001; break;
|
||||
case 1: if (neg[1]) p = qppmm; else p = qpppp; cycle(ka, 0) break;
|
||||
case 2: if (neg[2]) p = qmpmm; else p = qpppm; cycle(ka, 1) break;
|
||||
}
|
||||
qp = Qt_Mul(q, p);
|
||||
t = sqrt(mag[win] + 0.5);
|
||||
p = Qt_Mul(p, Qt_(0.0, 0.0, -qp.z / t, qp.w / t));
|
||||
p = Qt_Mul(qtoz, Qt_Conj(p));
|
||||
} else {
|
||||
float qa[4], pa[4];
|
||||
unsigned lo, hi, neg[4], par = 0;
|
||||
double all, big, two;
|
||||
qa[0] = q.x; qa[1] = q.y; qa[2] = q.z; qa[3] = q.w;
|
||||
for (i = 0; i < 4; i++) {
|
||||
pa[i] = 0.0;
|
||||
if (neg[i] = (qa[i] < 0.0)) qa[i] = -qa[i];
|
||||
par ^= neg[i];
|
||||
}
|
||||
/* Find two largest components, indices in hi and lo */
|
||||
if (qa[0] > qa[1]) lo = 0; else lo = 1;
|
||||
if (qa[2] > qa[3]) hi = 2; else hi = 3;
|
||||
if (qa[lo] > qa[hi]) {
|
||||
if (qa[lo ^ 1] > qa[hi]) { hi = lo; lo ^= 1; }
|
||||
else { hi ^= lo; lo ^= hi; hi ^= lo; }
|
||||
} else {if (qa[hi^1]>qa[lo]) lo = hi^1;}
|
||||
all = (qa[0] + qa[1] + qa[2] + qa[3]) * 0.5;
|
||||
two = (qa[hi] + qa[lo]) * SQRTHALF;
|
||||
big = qa[hi];
|
||||
if (all > two) {
|
||||
if (all > big) {/*all*/
|
||||
{int i; for (i = 0; i < 4; i++) pa[i] = sgn(neg[i], 0.5); }
|
||||
cycle(ka, par)
|
||||
} else {/*big*/ pa[hi] = sgn(neg[hi],1.0);}
|
||||
} else {
|
||||
if (two > big) {/*two*/
|
||||
pa[hi] = sgn(neg[hi], SQRTHALF); pa[lo] = sgn(neg[lo], SQRTHALF);
|
||||
if (lo > hi) { hi ^= lo; lo ^= hi; hi ^= lo; }
|
||||
if (hi == W) { hi = "\001\002\000"[lo]; lo = 3 - hi - lo; }
|
||||
swap(ka, hi, lo)
|
||||
} else {/*big*/ pa[hi] = sgn(neg[hi],1.0);}
|
||||
}
|
||||
p.x = -pa[0]; p.y = -pa[1]; p.z = -pa[2]; p.w = pa[3];
|
||||
}
|
||||
k->x = ka[X]; k->y = ka[Y]; k->z = ka[Z];
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******* Decompose Affine Matrix *******/
|
||||
|
||||
/* Decompose 4x4 affine matrix A as TFRUK(U transpose), where t contains the
|
||||
* translation components, q contains the rotation R, u contains U, k contains
|
||||
* scale factors, and f contains the sign of the determinant.
|
||||
* Assumes A transforms column vectors in right-handed coordinates.
|
||||
* See Ken Shoemake and Tom Duff. Matrix Animation and Polar Decomposition.
|
||||
* Proceedings of Graphics Interface 1992.
|
||||
*/
|
||||
void decomp_affine(HMatrix A, AffineParts* parts)
|
||||
{
|
||||
HMatrix Q, S, U;
|
||||
Quat p;
|
||||
float det;
|
||||
parts->t = Qt_(A[X][W], A[Y][W], A[Z][W], 0);
|
||||
det = polar_decomp(A, Q, S);
|
||||
if (det < 0.0) {
|
||||
mat_copy(Q, =, -Q, 3);
|
||||
parts->f = -1;
|
||||
} else parts->f = 1;
|
||||
parts->q = Qt_FromMatrix(Q);
|
||||
parts->k = spect_decomp(S, U);
|
||||
parts->u = Qt_FromMatrix(U);
|
||||
p = snuggle(parts->u, &parts->k);
|
||||
parts->u = Qt_Mul(parts->u, p);
|
||||
}
|
||||
|
||||
/******* Invert Affine Decomposition *******/
|
||||
|
||||
/* Compute inverse of affine decomposition.
|
||||
*/
|
||||
void invert_affine(AffineParts* parts, AffineParts* inverse)
|
||||
{
|
||||
Quat t, p;
|
||||
inverse->f = parts->f;
|
||||
inverse->q = Qt_Conj(parts->q);
|
||||
inverse->u = Qt_Mul(parts->q, parts->u);
|
||||
inverse->k.x = (parts->k.x == 0.0) ? 0.0 : 1.0 / parts->k.x;
|
||||
inverse->k.y = (parts->k.y == 0.0) ? 0.0 : 1.0 / parts->k.y;
|
||||
inverse->k.z = (parts->k.z == 0.0) ? 0.0 : 1.0 / parts->k.z;
|
||||
inverse->k.w = parts->k.w;
|
||||
t = Qt_(-parts->t.x, -parts->t.y, -parts->t.z, 0);
|
||||
t = Qt_Mul(Qt_Conj(inverse->u), Qt_Mul(t, inverse->u));
|
||||
t = Qt_(inverse->k.x * t.x, inverse->k.y * t.y, inverse->k.z * t.z, 0);
|
||||
p = Qt_Mul(inverse->q, inverse->u);
|
||||
t = Qt_Mul(p, Qt_Mul(t, Qt_Conj(p)));
|
||||
inverse->t = (inverse->f > 0.0) ? t : Qt_(-t.x, -t.y, -t.z, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
namespace decomp {
|
||||
// Taken from http://tog.acm.org/GraphicsGems/gemsiv/polar_decomp/Decompose.h
|
||||
|
||||
/**** Decompose.h - Basic declarations ****/
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_DECOMPOSE_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_DECOMPOSE_H
|
||||
#pragma once
|
||||
|
||||
typedef struct {float x, y, z, w;} Quat; /* Quaternion */
|
||||
enum QuatPart {X, Y, Z, W};
|
||||
typedef Quat HVect; /* Homogeneous 3D vector */
|
||||
typedef float HMatrix[4][4]; /* Right-handed, for column vectors */
|
||||
typedef struct {
|
||||
HVect t; /* Translation components */
|
||||
Quat q; /* Essential rotation */
|
||||
Quat u; /* Stretch rotation */
|
||||
HVect k; /* Stretch factors */
|
||||
float f; /* Sign of determinant */
|
||||
} AffineParts;
|
||||
float polar_decomp(HMatrix M, HMatrix Q, HMatrix S);
|
||||
HVect spect_decomp(HMatrix S, HMatrix U);
|
||||
Quat snuggle(Quat q, HVect *k);
|
||||
void decomp_affine(HMatrix A, AffineParts *parts);
|
||||
void invert_affine(AffineParts *parts, AffineParts *inverse);
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_DECOMPOSE_H
|
||||
|
||||
}
|
||||
@@ -1,43 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXCEPTIONS_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXCEPTIONS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
class BaseException
|
||||
: public std::exception
|
||||
{
|
||||
public:
|
||||
BaseException(const string& msg)
|
||||
: msg(msg) {}
|
||||
virtual const char* what() const throw () {return msg.c_str(); }
|
||||
|
||||
private:
|
||||
string msg;
|
||||
};
|
||||
|
||||
template <typename Tag>
|
||||
class Exception
|
||||
: public BaseException
|
||||
{
|
||||
public:
|
||||
Exception(const string& msg)
|
||||
: BaseException(msg) {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXCEPTIONS_H
|
||||
@@ -1,297 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AnimationData.h"
|
||||
|
||||
AnimationData::AnimationData(int modelCount, float fps, float startTime)
|
||||
: m_entries(modelCount)
|
||||
, m_frameCount(0)
|
||||
, m_startTime(startTime)
|
||||
, m_fps(fps)
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationData::SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3])
|
||||
{
|
||||
State& state = m_entries[modelIndex].samples[frameIndex];
|
||||
state.translation[0] = translation[0];
|
||||
state.translation[1] = translation[1];
|
||||
state.translation[2] = translation[2];
|
||||
state.rotation[0] = rotation[0];
|
||||
state.rotation[1] = rotation[1];
|
||||
state.rotation[2] = rotation[2];
|
||||
state.scale[0] = scale[0];
|
||||
state.scale[1] = scale[1];
|
||||
state.scale[2] = scale[2];
|
||||
}
|
||||
|
||||
void AnimationData::SetFrameCount(int frameCount)
|
||||
{
|
||||
m_frameCount = frameCount;
|
||||
for (int modelIndex = 0, modelCount = int(m_entries.size()); modelIndex < modelCount; ++modelIndex)
|
||||
{
|
||||
m_entries[modelIndex].samples.resize(frameCount);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationData::SetModelFlags(int modelIndex, unsigned modelFlags)
|
||||
{
|
||||
m_entries[modelIndex].flags = modelFlags;
|
||||
}
|
||||
|
||||
void AnimationData::GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const
|
||||
{
|
||||
translation = m_entries[modelIndex].samples[frameIndex].translation;
|
||||
rotation = m_entries[modelIndex].samples[frameIndex].rotation;
|
||||
scale = m_entries[modelIndex].samples[frameIndex].scale;
|
||||
}
|
||||
|
||||
void AnimationData::GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const
|
||||
{
|
||||
translation = m_entries[modelIndex].samples[frameIndex].translation;
|
||||
}
|
||||
|
||||
void AnimationData::GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const
|
||||
{
|
||||
rotation = m_entries[modelIndex].samples[frameIndex].rotation;
|
||||
}
|
||||
|
||||
void AnimationData::GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const
|
||||
{
|
||||
scale = m_entries[modelIndex].samples[frameIndex].scale;
|
||||
}
|
||||
|
||||
int AnimationData::GetFrameCount() const
|
||||
{
|
||||
return m_frameCount;
|
||||
}
|
||||
|
||||
unsigned AnimationData::GetModelFlags(int modelIndex) const
|
||||
{
|
||||
return m_entries[modelIndex].flags;
|
||||
}
|
||||
|
||||
AnimationData::State::State()
|
||||
{
|
||||
translation[0] = translation[1] = translation[2] = 0.0f;
|
||||
rotation[0] = rotation[1] = rotation[2] = 0.0f;
|
||||
scale[0] = scale[1] = scale[2] = 1.0f;
|
||||
}
|
||||
|
||||
AnimationData::ModelEntry::ModelEntry()
|
||||
: flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
NonSkeletalAnimationData::NonSkeletalAnimationData(int modelCount)
|
||||
: m_entries(modelCount)
|
||||
{
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetModelFlags(int modelIndex, unsigned modelFlags)
|
||||
{
|
||||
m_entries[modelIndex].flags = modelFlags;
|
||||
}
|
||||
|
||||
unsigned NonSkeletalAnimationData::GetModelFlags(int modelIndex) const
|
||||
{
|
||||
return m_entries[modelIndex].flags;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameTimePos(int modelIndex, int frameIndex, float time)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesPos[frameIndex];
|
||||
state.time = time;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameDataPos(int modelIndex, int frameIndex, float translation[3])
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesPos[frameIndex];
|
||||
state.data[0] = translation[0];
|
||||
state.data[1] = translation[1];
|
||||
state.data[2] = translation[2];
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameCountPos(int modelIndex, int frameCount)
|
||||
{
|
||||
m_entries[modelIndex].samplesPos.resize(frameCount);
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameTimeRot(int modelIndex, int frameIndex, float time)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesRot[frameIndex];
|
||||
state.time = time;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3])
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesRot[frameIndex];
|
||||
state.data[0] = rotation[0];
|
||||
state.data[1] = rotation[1];
|
||||
state.data[2] = rotation[2];
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameCountRot(int modelIndex, int frameCount)
|
||||
{
|
||||
m_entries[modelIndex].samplesRot.resize(frameCount);
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameTimeScl(int modelIndex, int frameIndex, float time)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesScl[frameIndex];
|
||||
state.time = time;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameDataScl(int modelIndex, int frameIndex, float scale[3])
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesScl[frameIndex];
|
||||
state.data[0] = scale[0];
|
||||
state.data[1] = scale[1];
|
||||
state.data[2] = scale[2];
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameCountScl(int modelIndex, int frameCount)
|
||||
{
|
||||
m_entries[modelIndex].samplesScl.resize(frameCount);
|
||||
}
|
||||
|
||||
float NonSkeletalAnimationData::GetFrameTimePos(int modelIndex, int frameIndex) const
|
||||
{
|
||||
return m_entries[modelIndex].samplesPos[frameIndex].time;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const
|
||||
{
|
||||
translation = m_entries[modelIndex].samplesPos[frameIndex].data;
|
||||
}
|
||||
|
||||
int NonSkeletalAnimationData::GetFrameCountPos(int modelIndex) const
|
||||
{
|
||||
return int(m_entries[modelIndex].samplesPos.size());
|
||||
}
|
||||
|
||||
float NonSkeletalAnimationData::GetFrameTimeRot(int modelIndex, int frameIndex) const
|
||||
{
|
||||
return m_entries[modelIndex].samplesRot[frameIndex].time;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const
|
||||
{
|
||||
rotation = m_entries[modelIndex].samplesRot[frameIndex].data;
|
||||
}
|
||||
|
||||
int NonSkeletalAnimationData::GetFrameCountRot(int modelIndex) const
|
||||
{
|
||||
return int(m_entries[modelIndex].samplesRot.size());
|
||||
}
|
||||
|
||||
float NonSkeletalAnimationData::GetFrameTimeScl(int modelIndex, int frameIndex) const
|
||||
{
|
||||
return m_entries[modelIndex].samplesScl[frameIndex].time;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const
|
||||
{
|
||||
scale = m_entries[modelIndex].samplesScl[frameIndex].data;
|
||||
}
|
||||
|
||||
int NonSkeletalAnimationData::GetFrameCountScl(int modelIndex) const
|
||||
{
|
||||
return int(m_entries[modelIndex].samplesScl.size());
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameTCBPos(int modelIndex, int frameIndex, IAnimationData::TCB tcb)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesPos[frameIndex];
|
||||
state.tcb = tcb;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameTCBRot(int modelIndex, int frameIndex, IAnimationData::TCB tcb)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesRot[frameIndex];
|
||||
state.tcb = tcb;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameTCBScl(int modelIndex, int frameIndex, IAnimationData::TCB tcb)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesScl[frameIndex];
|
||||
state.tcb = tcb;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameEaseInOutPos(int modelIndex, int frameIndex, IAnimationData::Ease ease)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesPos[frameIndex];
|
||||
state.ease = ease;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameEaseInOutRot(int modelIndex, int frameIndex, IAnimationData::Ease ease)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesRot[frameIndex];
|
||||
state.ease = ease;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::SetFrameEaseInOutScl(int modelIndex, int frameIndex, IAnimationData::Ease ease)
|
||||
{
|
||||
State& state = m_entries[modelIndex].samplesScl[frameIndex];
|
||||
state.ease = ease;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameTCBPos(int modelIndex, int frameIndex, IAnimationData::TCB& tcb) const
|
||||
{
|
||||
const State& state = m_entries[modelIndex].samplesPos[frameIndex];
|
||||
tcb = state.tcb;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameTCBRot(int modelIndex, int frameIndex, IAnimationData::TCB& tcb) const
|
||||
{
|
||||
const State& state = m_entries[modelIndex].samplesRot[frameIndex];
|
||||
tcb = state.tcb;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameTCBScl(int modelIndex, int frameIndex, IAnimationData::TCB& tcb) const
|
||||
{
|
||||
const State& state = m_entries[modelIndex].samplesScl[frameIndex];
|
||||
tcb = state.tcb;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameEaseInOutPos(int modelIndex, int frameIndex, IAnimationData::Ease& ease) const
|
||||
{
|
||||
const State& state = m_entries[modelIndex].samplesPos[frameIndex];
|
||||
ease = state.ease;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameEaseInOutRot(int modelIndex, int frameIndex, IAnimationData::Ease& ease) const
|
||||
{
|
||||
const State& state = m_entries[modelIndex].samplesRot[frameIndex];
|
||||
ease = state.ease;
|
||||
}
|
||||
|
||||
void NonSkeletalAnimationData::GetFrameEaseInOutScl(int modelIndex, int frameIndex, IAnimationData::Ease& ease) const
|
||||
{
|
||||
const State& state = m_entries[modelIndex].samplesScl[frameIndex];
|
||||
ease = state.ease;
|
||||
}
|
||||
|
||||
|
||||
NonSkeletalAnimationData::State::State()
|
||||
{
|
||||
time = 0.0f;
|
||||
data[0] = data[1] = data[2] = 0.0f;
|
||||
}
|
||||
|
||||
NonSkeletalAnimationData::ModelEntry::ModelEntry()
|
||||
: flags(0)
|
||||
{
|
||||
}
|
||||
@@ -1,211 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ANIMATIONDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ANIMATIONDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IAnimationData.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Animation data class for skeletal animations
|
||||
// It has a same count of samples for all models(bones)
|
||||
// and always has translation/rotation/scaling data together as a set.
|
||||
class AnimationData
|
||||
: public IAnimationData
|
||||
{
|
||||
public:
|
||||
AnimationData(int modelCount, float fps, float startTime);
|
||||
virtual ~AnimationData() {}
|
||||
|
||||
// IAnimationData
|
||||
virtual void SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3]);
|
||||
virtual void SetFrameCount(int frameCount);
|
||||
virtual void SetModelFlags(int modelIndex, unsigned modelFlags);
|
||||
|
||||
virtual void SetFrameTimePos(int modelIndex, int frameIndex, float time)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameDataPos(int modelIndex, int frameIndex, float translation[3])
|
||||
{ assert(0); }
|
||||
virtual void SetFrameCountPos(int modelIndex, int frameCount)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameTimeRot(int modelIndex, int frameIndex, float time)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3])
|
||||
{ assert(0); }
|
||||
virtual void SetFrameCountRot(int modelIndex, int frameCount)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameTimeScl(int modelIndex, int frameIndex, float time)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameDataScl(int modelIndex, int frameIndex, float scale[3])
|
||||
{ assert(0); }
|
||||
virtual void SetFrameCountScl(int modelIndex, int frameCount)
|
||||
{ assert(0); }
|
||||
|
||||
virtual void GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const;
|
||||
virtual int GetFrameCount() const;
|
||||
virtual unsigned GetModelFlags(int modelIndex) const;
|
||||
|
||||
virtual float GetFrameTimePos(int modelIndex, int frameIndex) const
|
||||
{ return m_startTime + frameIndex / m_fps; }
|
||||
virtual void GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const;
|
||||
virtual int GetFrameCountPos(int) const
|
||||
{ return GetFrameCount(); }
|
||||
virtual float GetFrameTimeRot(int modelIndex, int frameIndex) const
|
||||
{ return m_startTime + frameIndex / m_fps; }
|
||||
virtual void GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const;
|
||||
virtual int GetFrameCountRot(int) const
|
||||
{ return GetFrameCount(); }
|
||||
virtual float GetFrameTimeScl(int modelIndex, int frameIndex) const
|
||||
{ return m_startTime + frameIndex / m_fps; }
|
||||
virtual void GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const;
|
||||
virtual int GetFrameCountScl(int) const
|
||||
{ return GetFrameCount(); }
|
||||
|
||||
// TCB & Ease-In/-Out not supported for the skeletal animation.
|
||||
virtual void SetFrameTCBPos(int modelIndex, int frameIndex, TCB tcb)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameTCBRot(int modelIndex, int frameIndex, TCB tcb)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameTCBScl(int modelIndex, int frameIndex, TCB tcb)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease ease)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease ease)
|
||||
{ assert(0); }
|
||||
virtual void SetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease ease)
|
||||
{ assert(0); }
|
||||
virtual void GetFrameTCBPos(int modelIndex, int frameIndex, TCB& tcb) const
|
||||
{ assert(0); }
|
||||
virtual void GetFrameTCBRot(int modelIndex, int frameIndex, TCB& tcb) const
|
||||
{ assert(0); }
|
||||
virtual void GetFrameTCBScl(int modelIndex, int frameIndex, TCB& tcb) const
|
||||
{ assert(0); }
|
||||
virtual void GetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease& ease) const
|
||||
{ assert(0); }
|
||||
virtual void GetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease& ease) const
|
||||
{ assert(0); }
|
||||
virtual void GetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease& ease) const
|
||||
{ assert(0); }
|
||||
|
||||
private:
|
||||
struct State
|
||||
{
|
||||
public:
|
||||
State();
|
||||
float translation[3];
|
||||
float rotation[3];
|
||||
float scale[3];
|
||||
};
|
||||
|
||||
struct ModelEntry
|
||||
{
|
||||
ModelEntry();
|
||||
|
||||
unsigned flags;
|
||||
std::vector<State> samples;
|
||||
};
|
||||
|
||||
std::vector<ModelEntry> m_entries;
|
||||
int m_frameCount;
|
||||
float m_startTime;
|
||||
float m_fps;
|
||||
};
|
||||
|
||||
// Animation data class for non-skeletal animations
|
||||
// It can have different counts of samples for each model
|
||||
// and each channel of transformation data.
|
||||
class NonSkeletalAnimationData
|
||||
: public IAnimationData
|
||||
{
|
||||
public:
|
||||
NonSkeletalAnimationData(int modelCount);
|
||||
virtual ~NonSkeletalAnimationData() {}
|
||||
|
||||
// IAnimationData
|
||||
virtual void SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3])
|
||||
{ assert(0); }
|
||||
virtual void SetFrameCount(int frameCount)
|
||||
{ assert(0); }
|
||||
virtual void SetModelFlags(int modelIndex, unsigned modelFlags);
|
||||
|
||||
virtual void SetFrameTimePos(int modelIndex, int frameIndex, float time);
|
||||
virtual void SetFrameDataPos(int modelIndex, int frameIndex, float translation[3]);
|
||||
virtual void SetFrameCountPos(int modelIndex, int frameCount);
|
||||
virtual void SetFrameTimeRot(int modelIndex, int frameIndex, float time);
|
||||
virtual void SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3]);
|
||||
virtual void SetFrameCountRot(int modelIndex, int frameCount);
|
||||
virtual void SetFrameTimeScl(int modelIndex, int frameIndex, float time);
|
||||
virtual void SetFrameDataScl(int modelIndex, int frameIndex, float scale[3]);
|
||||
virtual void SetFrameCountScl(int modelIndex, int frameCount);
|
||||
|
||||
virtual void GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const
|
||||
{ assert(0); }
|
||||
virtual int GetFrameCount() const
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
virtual unsigned GetModelFlags(int modelIndex) const;
|
||||
|
||||
virtual float GetFrameTimePos(int modelIndex, int frameIndex) const;
|
||||
virtual void GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const;
|
||||
virtual int GetFrameCountPos(int) const;
|
||||
virtual float GetFrameTimeRot(int modelIndex, int frameIndex) const;
|
||||
virtual void GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const;
|
||||
virtual int GetFrameCountRot(int) const;
|
||||
virtual float GetFrameTimeScl(int modelIndex, int frameIndex) const;
|
||||
virtual void GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const;
|
||||
virtual int GetFrameCountScl(int) const;
|
||||
|
||||
virtual void SetFrameTCBPos(int modelIndex, int frameIndex, TCB tcb);
|
||||
virtual void SetFrameTCBRot(int modelIndex, int frameIndex, TCB tcb);
|
||||
virtual void SetFrameTCBScl(int modelIndex, int frameIndex, TCB tcb);
|
||||
virtual void SetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease ease);
|
||||
virtual void SetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease ease);
|
||||
virtual void SetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease ease);
|
||||
|
||||
virtual void GetFrameTCBPos(int modelIndex, int frameIndex, TCB& tcb) const;
|
||||
virtual void GetFrameTCBRot(int modelIndex, int frameIndex, TCB& tcb) const;
|
||||
virtual void GetFrameTCBScl(int modelIndex, int frameIndex, TCB& tcb) const;
|
||||
virtual void GetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease& ease) const;
|
||||
virtual void GetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease& ease) const;
|
||||
virtual void GetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease& ease) const;
|
||||
|
||||
private:
|
||||
struct State
|
||||
{
|
||||
public:
|
||||
State();
|
||||
float time;
|
||||
float data[3];
|
||||
TCB tcb;
|
||||
Ease ease;
|
||||
};
|
||||
|
||||
struct ModelEntry
|
||||
{
|
||||
ModelEntry();
|
||||
|
||||
unsigned flags;
|
||||
std::vector<State> samplesPos;
|
||||
std::vector<State> samplesRot;
|
||||
std::vector<State> samplesScl;
|
||||
};
|
||||
|
||||
std::vector<ModelEntry> m_entries;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ANIMATIONDATA_H
|
||||
@@ -1,57 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "CBAHelpers.h"
|
||||
#include "../PathHelpers.h"
|
||||
#include "StringHelpers.h"
|
||||
|
||||
static string FindRootContainingFileGoingUpwards(const char* filePath, const char* filePathToLookFor, IPakSystem* pakSystem)
|
||||
{
|
||||
// Here we just search upwards from the current directory, looking for a directory that
|
||||
// contains a file at the relative path "Animations/Animations.cba". This is designed to
|
||||
// handle root Game paths that differ from the default "Game".
|
||||
string rootDirCandidate = PathHelpers::GetDirectory(filePath);
|
||||
string rootDir;
|
||||
while (!rootDirCandidate.empty())
|
||||
{
|
||||
string cbaCandidatePath = PathHelpers::Join(rootDirCandidate, filePathToLookFor);
|
||||
if (PakSystemFile* file = pakSystem->Open(cbaCandidatePath.c_str(), "r"))
|
||||
{
|
||||
// File exists, we have found the correct root path.
|
||||
pakSystem->Close(file);
|
||||
|
||||
rootDir = rootDirCandidate;
|
||||
break;
|
||||
}
|
||||
|
||||
string previousCandidate = rootDirCandidate;
|
||||
rootDirCandidate = PathHelpers::GetDirectory(rootDirCandidate);
|
||||
if (rootDirCandidate == previousCandidate)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (rootDir.empty() ? rootDir : PathHelpers::Join(rootDir, filePathToLookFor));
|
||||
}
|
||||
|
||||
string CBAHelpers::FindCBAFileForFile(const char* filePath, IPakSystem* pakSystem)
|
||||
{
|
||||
return FindRootContainingFileGoingUpwards(filePath, "Animations/Animations.cba", pakSystem);
|
||||
}
|
||||
|
||||
string CBAHelpers::FindSkeletonListForFile(const char* filePath, IPakSystem* pakSystem)
|
||||
{
|
||||
return FindRootContainingFileGoingUpwards(filePath, "Animations/SkeletonList.xml", pakSystem);
|
||||
}
|
||||
@@ -1,556 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ColladaExportWriter.h"
|
||||
#include "ColladaWriter.h"
|
||||
#include "IExportSource.h"
|
||||
#include "PathHelpers.h"
|
||||
#include "ResourceCompilerHelper.h"
|
||||
#include "SettingsManagerHelpers.h"
|
||||
#include "IExportContext.h"
|
||||
#include "ProgressRange.h"
|
||||
#include "XMLWriter.h"
|
||||
#include "XMLPakFileSink.h"
|
||||
#include "ISettings.h"
|
||||
#include "SingleAnimationExportSourceAdapter.h"
|
||||
#include "GeometryExportSourceAdapter.h"
|
||||
#include "ModelData.h"
|
||||
#include "MaterialData.h"
|
||||
#include "GeometryFileData.h"
|
||||
#include "FileUtil.h"
|
||||
#include "CBAHelpers.h"
|
||||
#include "ModuleHelpers.h"
|
||||
#include "PropertyHelpers.h"
|
||||
#include "StringHelpers.h"
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
|
||||
namespace
|
||||
{
|
||||
class ResourceCompilerLogListener
|
||||
: public IResourceCompilerListener
|
||||
{
|
||||
public:
|
||||
ResourceCompilerLogListener(IExportContext* context)
|
||||
: m_context(context)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void OnRCMessage(IResourceCompilerListener::MessageSeverity severity, const char* text)
|
||||
{
|
||||
ILogger::ESeverity outSeverity;
|
||||
switch (severity)
|
||||
{
|
||||
case IResourceCompilerListener::MessageSeverity_Debug:
|
||||
case IResourceCompilerListener::MessageSeverity_Info: // normal RC text should just be debug
|
||||
outSeverity = ILogger::eSeverity_Debug;
|
||||
break;
|
||||
case IResourceCompilerListener::MessageSeverity_Warning:
|
||||
outSeverity = ILogger::eSeverity_Warning;
|
||||
break;
|
||||
case IResourceCompilerListener::MessageSeverity_Error:
|
||||
outSeverity = ILogger::eSeverity_Error;
|
||||
break;
|
||||
default:
|
||||
outSeverity = ILogger::eSeverity_Error;
|
||||
break;
|
||||
}
|
||||
|
||||
m_context->Log(outSeverity, "%s", text);
|
||||
}
|
||||
|
||||
private:
|
||||
IExportContext* m_context;
|
||||
};
|
||||
}
|
||||
|
||||
void ColladaExportWriter::Export(IExportSource* source, IExportContext* context)
|
||||
{
|
||||
// Create an object to report on our progress to the export context.
|
||||
ProgressRange progressRange(context, &IExportContext::SetProgress);
|
||||
CResourceCompilerHelper compiler; // we need a real instance of this specific implementation.
|
||||
|
||||
// Log build information.
|
||||
context->Log(ILogger::eSeverity_Info, "Exporter build created on " __DATE__);
|
||||
|
||||
#ifdef STLPORT
|
||||
context->Log(ILogger::eSeverity_Info, "Using STLport C++ Standard Library implementation");
|
||||
#else //STLPORT
|
||||
context->Log(ILogger::eSeverity_Info, "Using Microsoft (tm) C++ Standard Library implementation");
|
||||
#endif //STLPORT
|
||||
|
||||
#if defined(_DEBUG)
|
||||
context->Log(ILogger::eSeverity_Info, "******DEBUG BUILD******");
|
||||
#else //_DEBUG
|
||||
context->Log(ILogger::eSeverity_Info, "Release build.");
|
||||
#endif //_DEBUG
|
||||
|
||||
context->Log(ILogger::eSeverity_Debug, "Bit count == %d.", (sizeof(void*) * 8));
|
||||
|
||||
std::string exePath = StringHelpers::ConvertString<string>(ModuleHelpers::GetCurrentModulePath(ModuleHelpers::CurrentModuleSpecifier_Executable));
|
||||
context->Log(ILogger::eSeverity_Debug, "Application path: %s", exePath.c_str());
|
||||
|
||||
std::string exporterPath = StringHelpers::ConvertString<string>(ModuleHelpers::GetCurrentModulePath(ModuleHelpers::CurrentModuleSpecifier_Library));
|
||||
context->Log(ILogger::eSeverity_Debug, "Exporter path: %s", exporterPath.c_str());
|
||||
|
||||
bool const bExportCompressed = (GetSetting<int>(context->GetSettings(), "ExportCompressedCOLLADA", 1)) != 0;
|
||||
context->Log(ILogger::eSeverity_Debug, "ExportCompressedCOLLADA key: %d", (bExportCompressed ? 1 : 0));
|
||||
|
||||
std::string const exportExtension = bExportCompressed ? ".dae.zip" : ".dae";
|
||||
|
||||
// Log the start time.
|
||||
{
|
||||
char buf[1024];
|
||||
std::time_t t = std::time(0);
|
||||
std::strftime(buf, sizeof(buf) / sizeof(buf[0]), "%H:%M:%S on %a, %d/%m/%Y", std::localtime(&t));
|
||||
context->Log(ILogger::eSeverity_Info, "Export begun at %s", buf);
|
||||
}
|
||||
|
||||
// Select the name of the directory to export to.
|
||||
std::string const originalExportDirectory = source->GetExportDirectory();
|
||||
if (originalExportDirectory.empty())
|
||||
{
|
||||
throw IExportContext::NeedSaveError("Scene must be saved before exporting.");
|
||||
}
|
||||
|
||||
GeometryFileData geometryFileData;
|
||||
std::vector<std::string> colladaGeometryFileNameList;
|
||||
std::vector<std::string> assetGeometryFileNameList;
|
||||
typedef std::vector<std::pair<std::pair<int, int>, std::string> > AnimationFileNameList;
|
||||
AnimationFileNameList animationFileNameList;
|
||||
AnimationFileNameList animationCompileFileNameList;
|
||||
{
|
||||
CurrentTaskScope currentTask(context, "dae");
|
||||
|
||||
// Choose the files to which to export all the animations.
|
||||
std::list<SingleAnimationExportSourceAdapter> animationExportSources;
|
||||
std::list<GeometryExportSourceAdapter> geometryExportSources;
|
||||
typedef std::vector<std::pair<std::string, IExportSource*> > ExportList;
|
||||
ExportList exportList;
|
||||
std::vector<int> geometryFileIndices;
|
||||
{
|
||||
ProgressRange readProgressRange(progressRange, 0.2f);
|
||||
|
||||
source->ReadGeometryFiles(context, &geometryFileData);
|
||||
|
||||
for (int geometryFileIndex = 0; geometryFileIndex < geometryFileData.GetGeometryFileCount(); ++geometryFileIndex)
|
||||
{
|
||||
const std::string geometryFileName = geometryFileData.GetGeometryFileName(geometryFileIndex);
|
||||
|
||||
IGeometryFileData::SProperties properties = geometryFileData.GetProperties(geometryFileIndex);
|
||||
if (properties.filetypeInt == CRY_FILE_TYPE_CAF)
|
||||
{
|
||||
// LDS: This is a temporary fix for some old hacky code that would activate a deprecated compression path during export
|
||||
// It needs a proper fix by tearing out the old compression code and moving the system to the new i_caf system by default.
|
||||
// See for http://docs.cryengine.com/display/SDKDOC3/Transition+from+CBA+to+AnimSettings details.
|
||||
properties.filetypeInt = CRY_FILE_TYPE_INTERMEDIATE_CAF;
|
||||
geometryFileData.SetProperties(geometryFileIndex, properties);
|
||||
}
|
||||
|
||||
bool const hasGeometry = (properties.filetypeInt != CRY_FILE_TYPE_CAF &&
|
||||
properties.filetypeInt != CRY_FILE_TYPE_INTERMEDIATE_CAF);
|
||||
|
||||
if (hasGeometry && !geometryFileName.empty())
|
||||
{
|
||||
geometryFileIndices.push_back(geometryFileIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!geometryFileIndices.empty())
|
||||
{
|
||||
std::string name = PathHelpers::RemoveExtension(PathHelpers::GetFilename(source->GetDCCFileName()));
|
||||
std::replace(name.begin(), name.end(), ' ', '_');
|
||||
std::string const colladaPath = PathHelpers::Join(originalExportDirectory, name + exportExtension);
|
||||
colladaGeometryFileNameList.push_back(colladaPath);
|
||||
|
||||
geometryExportSources.push_back(GeometryExportSourceAdapter(source, &geometryFileData, geometryFileIndices));
|
||||
exportList.push_back(std::make_pair(colladaPath, &geometryExportSources.back()));
|
||||
}
|
||||
|
||||
for (int geometryFileIndex = 0; geometryFileIndex < geometryFileData.GetGeometryFileCount(); ++geometryFileIndex)
|
||||
{
|
||||
std::string const geometryFileName = geometryFileData.GetGeometryFileName(geometryFileIndex);
|
||||
int const fileTypeInt = geometryFileData.GetProperties(geometryFileIndex).filetypeInt;
|
||||
std::string customExportPath = geometryFileData.GetProperties(geometryFileIndex).customExportPath;
|
||||
bool const hasGeometry = (fileTypeInt != CRY_FILE_TYPE_CAF &&
|
||||
fileTypeInt != CRY_FILE_TYPE_INTERMEDIATE_CAF);
|
||||
|
||||
if (hasGeometry && !geometryFileName.empty())
|
||||
{
|
||||
std::string extension = "missingextension";
|
||||
if (fileTypeInt == CRY_FILE_TYPE_CGF)
|
||||
{
|
||||
extension = "cgf";
|
||||
}
|
||||
else if ((fileTypeInt == CRY_FILE_TYPE_CGA) || (fileTypeInt == (CRY_FILE_TYPE_CGA | CRY_FILE_TYPE_ANM)))
|
||||
{
|
||||
extension = "cga";
|
||||
}
|
||||
else if (fileTypeInt == CRY_FILE_TYPE_ANM)
|
||||
{
|
||||
extension = "anm";
|
||||
}
|
||||
else if (fileTypeInt == CRY_FILE_TYPE_CHR ||
|
||||
(fileTypeInt == (CRY_FILE_TYPE_CHR | CRY_FILE_TYPE_CAF)) ||
|
||||
(fileTypeInt == (CRY_FILE_TYPE_CHR | CRY_FILE_TYPE_INTERMEDIATE_CAF)))
|
||||
{
|
||||
extension = "chr";
|
||||
}
|
||||
else if (fileTypeInt == CRY_FILE_TYPE_SKIN)
|
||||
{
|
||||
extension = "skin";
|
||||
}
|
||||
|
||||
std::string safeGeometryFileName = geometryFileName;
|
||||
std::replace(safeGeometryFileName.begin(), safeGeometryFileName.end(), ' ', '_');
|
||||
std::string finalFileName;
|
||||
if (customExportPath.size() > 0)
|
||||
{
|
||||
if (PathHelpers::IsRelative(customExportPath))
|
||||
{
|
||||
std::string const assetRelativePath = PathHelpers::Join(originalExportDirectory, customExportPath);
|
||||
finalFileName = PathHelpers::Join(assetRelativePath, safeGeometryFileName + "." + extension);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Warning, "An absolute path was specified for export of node %s (%s) - This is unlikely to be correct", geometryFileName.c_str(), customExportPath.c_str());
|
||||
finalFileName = PathHelpers::Join(customExportPath, safeGeometryFileName + "." + extension);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no relative path, just export it in the original directory.
|
||||
finalFileName = PathHelpers::Join(originalExportDirectory, safeGeometryFileName + "." + extension);
|
||||
}
|
||||
if (finalFileName.size() > 0)
|
||||
{
|
||||
assetGeometryFileNameList.push_back(finalFileName);
|
||||
if (!FileUtil::EnsureDirectoryExists(PathHelpers::GetDirectory(finalFileName).c_str()))
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Unable to create directory for %s", finalFileName.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((fileTypeInt & (CRY_FILE_TYPE_CAF | CRY_FILE_TYPE_INTERMEDIATE_CAF)) != 0)
|
||||
{
|
||||
for (int animationIndex = 0; animationIndex < source->GetAnimationCount(); ++animationIndex)
|
||||
{
|
||||
std::string const animationName = source->GetAnimationName(&geometryFileData, geometryFileIndex, animationIndex);
|
||||
|
||||
// Animations beginning with an underscore should be ignored.
|
||||
bool const ignoreAnimation = animationName.empty() || (animationName[0] == '_');
|
||||
|
||||
if (!ignoreAnimation)
|
||||
{
|
||||
std::string safeAnimationName = animationName;
|
||||
std::replace(safeAnimationName.begin(), safeAnimationName.end(), ' ', '_');
|
||||
|
||||
std::string exportPath = PathHelpers::Join(originalExportDirectory, safeAnimationName + exportExtension);
|
||||
animationFileNameList.push_back(std::make_pair(std::make_pair(animationIndex, geometryFileIndex), exportPath));
|
||||
if (fileTypeInt & CRY_FILE_TYPE_CAF)
|
||||
{
|
||||
animationCompileFileNameList.push_back(std::make_pair(std::make_pair(animationIndex, geometryFileIndex), exportPath));
|
||||
}
|
||||
animationExportSources.push_back(SingleAnimationExportSourceAdapter(source, &geometryFileData, geometryFileIndex, animationIndex));
|
||||
exportList.push_back(std::make_pair(exportPath, &animationExportSources.back()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export the COLLADA file to the chosen file.
|
||||
{
|
||||
ProgressRange exportProgressRange(progressRange, 0.6f);
|
||||
|
||||
size_t const daeCount = exportList.size();
|
||||
float const daeProgressRangeSlice = 1.0f / (daeCount > 0 ? daeCount : 1);
|
||||
for (ExportList::iterator itFile = exportList.begin(); itFile != exportList.end(); ++itFile)
|
||||
{
|
||||
const std::string& colladaFileName = (*itFile).first;
|
||||
IExportSource* fileExportSource = (*itFile).second;
|
||||
|
||||
ProgressRange animationExportProgressRange(exportProgressRange, daeProgressRangeSlice);
|
||||
|
||||
try
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Info, "Exporting to file '%s'", colladaFileName.c_str());
|
||||
|
||||
// Try to create the directory for the file.
|
||||
if (!FileUtil::EnsureDirectoryExists(PathHelpers::GetDirectory(colladaFileName).c_str()))
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Unable to create directory for %s", colladaFileName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
|
||||
if (bExportCompressed)
|
||||
{
|
||||
IPakSystem* pakSystem = (context ? context->GetPakSystem() : 0);
|
||||
if (!pakSystem)
|
||||
{
|
||||
throw IExportContext::PakSystemError("No pak system provided.");
|
||||
}
|
||||
|
||||
std::string const archivePath = colladaFileName;
|
||||
std::string archiveRelativePath = colladaFileName.substr(0, colladaFileName.length() - exportExtension.length()) + ".dae";
|
||||
archiveRelativePath = PathHelpers::GetFilename(archiveRelativePath);
|
||||
|
||||
XMLPakFileSink sink(pakSystem, archivePath, archiveRelativePath);
|
||||
ok = ColladaWriter::Write(fileExportSource, context, &sink, animationExportProgressRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLFileSink fileSink(colladaFileName);
|
||||
ok = ColladaWriter::Write(fileExportSource, context, &fileSink, animationExportProgressRange);
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
// FIXME: erase the resulting file somehow
|
||||
context->Log(ILogger::eSeverity_Error, "Failed to export '%s'", colladaFileName.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (IXMLSink::OpenFailedError e)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Unable to open output file: %s", e.what());
|
||||
return;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Unexpected crash in COLLADA exporter");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the RC path. If a custom one isn't specified then fall back to the registry method as per the default.
|
||||
wchar_t resourceCompilerPath[512];
|
||||
{
|
||||
const std::string resourceCompilerPathString = source->GetResourceCompilerPath();
|
||||
if (!resourceCompilerPathString.empty())
|
||||
{
|
||||
SettingsManagerHelpers::ConvertUtf8ToUtf16(resourceCompilerPathString.c_str(), SettingsManagerHelpers::CWCharBuffer(resourceCompilerPath, sizeof(resourceCompilerPath)));
|
||||
}
|
||||
}
|
||||
|
||||
// Run the resource compiler on the COLLADA file to generate uncompressed CAFs.
|
||||
{
|
||||
ProgressRange compilerProgressRange(progressRange, 0.075f);
|
||||
|
||||
CurrentTaskScope currentTask(context, "rc");
|
||||
|
||||
size_t const daeCount = animationFileNameList.size();
|
||||
float const animationProgressRangeSlice = 1.0f / (daeCount > 0 ? daeCount : 1);
|
||||
for (AnimationFileNameList::iterator itFile = animationFileNameList.begin(); itFile != animationFileNameList.end(); ++itFile)
|
||||
{
|
||||
std::string colladaFileName = (*itFile).second;
|
||||
int geometryFileIndex = itFile->first.second;
|
||||
|
||||
std::string expectedCAFPath;
|
||||
{
|
||||
bool isIntermediateCAF = (geometryFileData.GetProperties(geometryFileIndex).filetypeInt & CRY_FILE_TYPE_INTERMEDIATE_CAF) != 0;
|
||||
string nameWithoutExtension = colladaFileName.substr(0, colladaFileName.length() - exportExtension.length());
|
||||
expectedCAFPath = nameWithoutExtension + (isIntermediateCAF ? ".i_caf" : ".caf");
|
||||
}
|
||||
|
||||
if (FileUtil::FileExists(expectedCAFPath.c_str()))
|
||||
{
|
||||
if (!DeleteFileA(expectedCAFPath.c_str()))
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Failed to remove existing animation file: %s", expectedCAFPath.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
string arguments = "/refresh";
|
||||
|
||||
ProgressRange animationCompileProgressRange(compilerProgressRange, animationProgressRangeSlice);
|
||||
ResourceCompilerLogListener listener(context);
|
||||
|
||||
context->Log(ILogger::eSeverity_Info, "Calling RC to generate uncompressed CAF file: %s", colladaFileName.c_str());
|
||||
CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler( // actual instance of compiler used
|
||||
colladaFileName.c_str(),
|
||||
arguments.c_str(),
|
||||
&listener,
|
||||
true, false, false, 0, resourceCompilerPath);
|
||||
|
||||
if (result != CResourceCompilerHelper::eRcCallResult_success)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result));
|
||||
continue;
|
||||
}
|
||||
|
||||
context->Log(ILogger::eSeverity_Debug, "RC finished: %s", colladaFileName.c_str());
|
||||
if (!FileUtil::FileExists(expectedCAFPath.c_str()))
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Following Animation file is expected to be created by RC: %s", expectedCAFPath.c_str());
|
||||
context->Log(ILogger::eSeverity_Error, "Do you have an old RC version?");
|
||||
}
|
||||
|
||||
#if !defined(_DEBUG)
|
||||
// Delete the Collada file.
|
||||
DeleteFileA(colladaFileName.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Run the resource compiler on the COLLADA file to generate the geometry assets.
|
||||
{
|
||||
ProgressRange compilerProgressRange(progressRange, 0.075f);
|
||||
|
||||
CurrentTaskScope currentTask(context, "rc");
|
||||
|
||||
size_t const daeCount = colladaGeometryFileNameList.size();
|
||||
float const assetProgressRangeSlice = 1.0f / (daeCount > 0 ? daeCount : 1);
|
||||
for (size_t i = 0; i < daeCount; ++i)
|
||||
{
|
||||
const std::string& colladaFileName = colladaGeometryFileNameList[i];
|
||||
|
||||
ProgressRange assetCompileProgressRange(compilerProgressRange, assetProgressRangeSlice);
|
||||
ResourceCompilerLogListener listener(context);
|
||||
context->Log(ILogger::eSeverity_Info, "Calling RC to generate raw asset file: %s", colladaFileName.c_str());
|
||||
CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler(
|
||||
colladaFileName.c_str(),
|
||||
"/refresh",
|
||||
&listener,
|
||||
true, false, false, 0, resourceCompilerPath);
|
||||
|
||||
#if !defined(_DEBUG)
|
||||
// Delete the Collada file.
|
||||
DeleteFileA(colladaFileName.c_str());
|
||||
#endif
|
||||
|
||||
if (result == CResourceCompilerHelper::eRcCallResult_success)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Debug, "RC finished: %s", colladaFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Create an RC helper - do it outside the loop, since it queries the registry on construction.
|
||||
ResourceCompilerLogListener listener(context);
|
||||
|
||||
// Check the registry to see whether we should compress the animations or not.
|
||||
int processAnimations = GetSetting<int>(context->GetSettings(), "CompressCAFs", 1);
|
||||
|
||||
if (!processAnimations)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Warning, "CompressCAFs registry key set to 0 - not compressing CAFs");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run the resource compiler again on the generated CAF files to compress/process them.
|
||||
context->Log(ILogger::eSeverity_Debug, "CompressCAFs not set or set to 1 - compressing CAFs");
|
||||
|
||||
CurrentTaskScope currentTask(context, "compress");
|
||||
ProgressRange compressRange(progressRange, 0.025f);
|
||||
|
||||
size_t const cafCount = animationCompileFileNameList.size();
|
||||
float const animationProgressRangeSlice = 1.0f / (cafCount > 0 ? cafCount : 1);
|
||||
for (AnimationFileNameList::iterator itFile = animationCompileFileNameList.begin(); itFile != animationCompileFileNameList.end(); ++itFile)
|
||||
{
|
||||
std::string colladaFileName = (*itFile).second;
|
||||
ProgressRange animationProgressRange(compressRange, animationProgressRangeSlice);
|
||||
|
||||
// Assume the RC generated the CAF file using the take name and adding .CAF.
|
||||
std::string cafPath = colladaFileName.substr(0, colladaFileName.length() - exportExtension.length()) + ".caf";
|
||||
std::string cbaPath = StringHelpers::ConvertString<string>(CBAHelpers::FindCBAFileForFile(cafPath.c_str(), context->GetPakSystem()));
|
||||
|
||||
if (cbaPath.empty())
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "Unable to find CBA file for file \"%s\" (looked for a root game directory that contains a relative path of \"Animations/Animations.cba\"", cafPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[2048];
|
||||
sprintf(buffer, "/file=\"%s\" /refresh /SkipDba", cafPath.c_str());
|
||||
context->Log(ILogger::eSeverity_Info, "Calling RC to compress CAF file: (CBA file = %s) %s", cbaPath.c_str(), buffer);
|
||||
CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler(cbaPath.c_str(), buffer, &listener, true, resourceCompilerPathType, false, false, 0, resourceCompilerPath);
|
||||
if (result == CResourceCompilerHelper::eRcCallResult_success)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Debug, "RC finished: %s %s", cbaPath.c_str(), buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the registry to see whether we should optimize the geometry files or not.
|
||||
int optimizeGeometry = GetSetting<int>(context->GetSettings(), "OptimizeAssets", 1);
|
||||
|
||||
// Run the resource compiler again on the generated geometry files to compress/process them.
|
||||
// TODO: This should not be necessary, the RC should be modified so that assets are automatically
|
||||
// compressed when exported from COLLADA.
|
||||
if (!optimizeGeometry)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Warning, "OptimizeAssets registry key set to 0 - not compressing CAFs");
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Debug, "OptimizeAssets not set or set to 1 - optimizing geometry");
|
||||
|
||||
CurrentTaskScope currentTask(context, "compress");
|
||||
ProgressRange compressRange(progressRange, 0.025f);
|
||||
|
||||
size_t const assetCount = assetGeometryFileNameList.size();
|
||||
float const assetProgressRangeSlice = 1.0f / (assetCount > 0 ? assetCount : 1);
|
||||
for (size_t i = 0; i < assetCount; ++i)
|
||||
{
|
||||
const std::string& assetFileName = assetGeometryFileNameList[i];
|
||||
ProgressRange animationProgressRange(compressRange, assetProgressRangeSlice);
|
||||
|
||||
// note: we skip some asset types because we know that they are "optimized" already
|
||||
if (StringHelpers::EndsWithIgnoreCase(assetFileName, ".anm") || StringHelpers::EndsWithIgnoreCase(assetFileName, ".chr") || StringHelpers::EndsWithIgnoreCase(assetFileName, ".skin"))
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Info, "Calling RC to optimize asset \"%s\"", assetFileName.c_str());
|
||||
CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler(assetFileName.c_str(), "/refresh", &listener, true, resourceCompilerPathType, false, false, 0, resourceCompilerPath);
|
||||
if (result == CResourceCompilerHelper::eRcCallResult_success)
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Debug, "RC finished: %s", assetFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log the end time.
|
||||
{
|
||||
char buf[1024];
|
||||
std::time_t t = std::time(0);
|
||||
std::strftime(buf, sizeof(buf) / sizeof(buf[0]), "%H:%M:%S on %a, %d/%m/%Y", std::localtime(&t));
|
||||
context->Log(ILogger::eSeverity_Info, "Export finished at %s", buf);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,32 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAWRITER_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAWRITER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
class IExportSource;
|
||||
class IExportContext;
|
||||
class ProgressRange;
|
||||
class IXMLSink;
|
||||
|
||||
class ColladaWriter
|
||||
{
|
||||
public:
|
||||
static bool Write(IExportSource* source, IExportContext* context, IXMLSink* sink, ProgressRange& progressRange);
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAWRITER_H
|
||||
@@ -1,66 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ExportFileType.h"
|
||||
#include "StringHelpers.h"
|
||||
|
||||
|
||||
struct SFileTypeInfo
|
||||
{
|
||||
int type;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
SFileTypeInfo s_fileTypes[] =
|
||||
{
|
||||
{ CRY_FILE_TYPE_CGF, "cgf" },
|
||||
{ CRY_FILE_TYPE_CGA, "cga" },
|
||||
{ CRY_FILE_TYPE_CHR, "chr" },
|
||||
{ CRY_FILE_TYPE_CAF, "caf" },
|
||||
{ CRY_FILE_TYPE_ANM, "anm" },
|
||||
{ CRY_FILE_TYPE_CHR | CRY_FILE_TYPE_CAF, "chrcaf" },
|
||||
{ CRY_FILE_TYPE_CGA | CRY_FILE_TYPE_ANM, "cgaanm" },
|
||||
{ CRY_FILE_TYPE_SKIN, "skin" },
|
||||
{ CRY_FILE_TYPE_INTERMEDIATE_CAF, "i_caf" },
|
||||
};
|
||||
|
||||
static const int s_fileTypeCount = (sizeof(s_fileTypes) / sizeof(s_fileTypes[0]));
|
||||
|
||||
|
||||
const char* ExportFileTypeHelpers::CryFileTypeToString(int const cryFileType)
|
||||
{
|
||||
for (int i = 0; i < s_fileTypeCount; ++i)
|
||||
{
|
||||
if (s_fileTypes[i].type == cryFileType)
|
||||
{
|
||||
return s_fileTypes[i].name;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
int ExportFileTypeHelpers::StringToCryFileType(const char* str)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
for (int i = 0; i < s_fileTypeCount; ++i)
|
||||
{
|
||||
if (_stricmp(str, s_fileTypes[i].name) == 0)
|
||||
{
|
||||
return s_fileTypes[i].type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CRY_FILE_TYPE_NONE;
|
||||
}
|
||||
@@ -1,42 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTFILETYPE_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTFILETYPE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
enum CryFileType
|
||||
{
|
||||
CRY_FILE_TYPE_NONE = 0x0000,
|
||||
CRY_FILE_TYPE_CGF = 0x0001,
|
||||
CRY_FILE_TYPE_CGA = 0x0002,
|
||||
CRY_FILE_TYPE_CHR = 0x0004,
|
||||
CRY_FILE_TYPE_CAF = 0x0008,
|
||||
CRY_FILE_TYPE_ANM = 0x0010,
|
||||
CRY_FILE_TYPE_SKIN = 0x0020,
|
||||
CRY_FILE_TYPE_INTERMEDIATE_CAF = 0x0040,
|
||||
//START: Add Skinned Geometry (.CGF) export type (for touch bending vegetation)
|
||||
CRY_FILE_TYPE_SKIN_CGF = 0x0080,
|
||||
//END: Add Skinned Geometry (.CGF) export type (for touch bending vegetation)
|
||||
};
|
||||
|
||||
namespace ExportFileTypeHelpers
|
||||
{
|
||||
const char* CryFileTypeToString(int cryFileType);
|
||||
int StringToCryFileType(const char* str);
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTFILETYPE_H
|
||||
|
||||
@@ -1,83 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTHELPERS_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTHELPERS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace ExportHelpers
|
||||
{
|
||||
inline void GenerateTextureCoordinates(float* const res_s, float* const res_t, const float x, const float y, const float z)
|
||||
{
|
||||
const float ax = ::fabs(x);
|
||||
const float ay = ::fabs(y);
|
||||
const float az = ::fabs(z);
|
||||
|
||||
float s = 0.0f;
|
||||
float t = 0.0f;
|
||||
|
||||
if (ax > 1e-3f || ay > 1e-3f || az > 1e-3f)
|
||||
{
|
||||
if (ax > ay)
|
||||
{
|
||||
if (ax > az)
|
||||
{
|
||||
// X rules
|
||||
s = y / ax;
|
||||
t = z / ax;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Z rules
|
||||
s = x / az;
|
||||
t = y / az;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ax <= ay
|
||||
if (ay > az)
|
||||
{
|
||||
// Y rules
|
||||
s = x / ay;
|
||||
t = z / ay;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Z rules
|
||||
s = x / az;
|
||||
t = y / az;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now the texture coordinates are in the range [-1,1].
|
||||
// We want normalized [0,1] texture coordinates.
|
||||
s = (s + 1) * 0.5f;
|
||||
t = (t + 1) * 0.5f;
|
||||
|
||||
if (res_s)
|
||||
{
|
||||
*res_s = s;
|
||||
}
|
||||
if (res_t)
|
||||
{
|
||||
*res_t = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTHELPERS_H
|
||||
@@ -1,130 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ExportSourceDecoratorBase.h"
|
||||
|
||||
ExportSourceDecoratorBase::ExportSourceDecoratorBase(IExportSource* source)
|
||||
: source(source)
|
||||
{
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::GetMetaData(SExportMetaData& metaData) const
|
||||
{
|
||||
this->source->GetMetaData(metaData);
|
||||
}
|
||||
|
||||
std::string ExportSourceDecoratorBase::GetDCCFileName() const
|
||||
{
|
||||
return this->source->GetDCCFileName();
|
||||
}
|
||||
|
||||
std::string ExportSourceDecoratorBase::GetExportDirectory() const
|
||||
{
|
||||
return this->source->GetExportDirectory();
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData)
|
||||
{
|
||||
this->source->ReadGeometryFiles(context, geometryFileData);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadMaterials(IExportContext* context, const IGeometryFileData* const geometryFileData, IMaterialData* materialData)
|
||||
{
|
||||
return this->source->ReadMaterials(context, geometryFileData, materialData);
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData)
|
||||
{
|
||||
this->source->ReadModels(geometryFileData, geometryFileIndex, modelData);
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* const modelData, int modelIndex, ISkeletonData* skeletonData)
|
||||
{
|
||||
this->source->ReadSkinning(context, skinningData, modelData, modelIndex, skeletonData);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadSkeleton(const IGeometryFileData* const geometryFileData, int geometryFileIndex, const IModelData* const modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData)
|
||||
{
|
||||
return this->source->ReadSkeleton(geometryFileData, geometryFileIndex, modelData, modelIndex, materialData, skeletonData);
|
||||
}
|
||||
|
||||
int ExportSourceDecoratorBase::GetAnimationCount() const
|
||||
{
|
||||
return this->source->GetAnimationCount();
|
||||
}
|
||||
|
||||
std::string ExportSourceDecoratorBase::GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const
|
||||
{
|
||||
return this->source->GetAnimationName(geometryFileData, geometryFileIndex, animationIndex);
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const
|
||||
{
|
||||
this->source->GetAnimationTimeSpan(start, stop, animationIndex);
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const
|
||||
{
|
||||
this->source->ReadAnimationFlags(context, animationData, geometryFileData, modelData, modelIndex, skeletonData, animationIndex);
|
||||
}
|
||||
|
||||
IAnimationData* ExportSourceDecoratorBase::ReadAnimation(IExportContext* context, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const
|
||||
{
|
||||
return this->source->ReadAnimation(context, geometryFileData, modelData, modelIndex, skeletonData, animationIndex, fps);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* const modelData, const IMaterialData* const materialData, int modelIndex)
|
||||
{
|
||||
return this->source->ReadGeometry(context, geometry, modelData, materialData, modelIndex);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, const IModelData* const modelData, const IMaterialData* const materialData, int modelIndex) const
|
||||
{
|
||||
return this->source->ReadGeometryMaterialData(context, geometryMaterialData, modelData, materialData, modelIndex);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadBoneGeometry(IExportContext* context, IGeometryData* geometry, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* const materialData)
|
||||
{
|
||||
return this->source->ReadBoneGeometry(context, geometry, skeletonData, boneIndex, materialData);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadBoneGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* const materialData) const
|
||||
{
|
||||
return this->source->ReadBoneGeometryMaterialData(context, geometryMaterialData, skeletonData, boneIndex, materialData);
|
||||
}
|
||||
|
||||
void ExportSourceDecoratorBase::ReadMorphs(IExportContext* context, IMorphData* morphData, const IModelData* const modelData, int modelIndex)
|
||||
{
|
||||
this->source->ReadMorphs(context, morphData, modelData, modelIndex);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::ReadMorphGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* const modelData, int modelIndex, const IMorphData* const morphData, int morphIndex, const IMaterialData* materialData)
|
||||
{
|
||||
return this->source->ReadMorphGeometry(context, geometry, modelData, modelIndex, morphData, morphIndex, materialData);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::HasValidPosController(const IModelData* modelData, int modelIndex) const
|
||||
{
|
||||
return this->source->HasValidPosController(modelData, modelIndex);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::HasValidRotController(const IModelData* modelData, int modelIndex) const
|
||||
{
|
||||
return this->source->HasValidRotController(modelData, modelIndex);
|
||||
}
|
||||
|
||||
bool ExportSourceDecoratorBase::HasValidSclController(const IModelData* modelData, int modelIndex) const
|
||||
{
|
||||
return this->source->HasValidSclController(modelData, modelIndex);
|
||||
}
|
||||
@@ -1,54 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSOURCEDECORATORBASE_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSOURCEDECORATORBASE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IExportSource.h"
|
||||
|
||||
class ExportSourceDecoratorBase
|
||||
: public IExportSource
|
||||
{
|
||||
public:
|
||||
ExportSourceDecoratorBase(IExportSource* source);
|
||||
|
||||
virtual std::string GetResourceCompilerPath() const { return std::string(""); };
|
||||
virtual void GetMetaData(SExportMetaData& metaData) const;
|
||||
virtual std::string GetDCCFileName() const;
|
||||
virtual std::string GetExportDirectory() const;
|
||||
virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData);
|
||||
virtual bool ReadMaterials(IExportContext* context, const IGeometryFileData* geometryFileData, IMaterialData* materialData);
|
||||
virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData);
|
||||
virtual void ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* modelData, int modelIndex, ISkeletonData* skeletonData);
|
||||
virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData);
|
||||
virtual int GetAnimationCount() const;
|
||||
virtual std::string GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const;
|
||||
virtual void GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const;
|
||||
virtual void ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const;
|
||||
virtual IAnimationData* ReadAnimation(IExportContext* context, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const;
|
||||
virtual bool ReadGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, const IMaterialData* materialData, int modelIndex);
|
||||
virtual bool ReadGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, const IModelData* modelData, const IMaterialData* materialData, int modelIndex) const;
|
||||
virtual bool ReadBoneGeometry(IExportContext* context, IGeometryData* geometry, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData);
|
||||
virtual bool ReadBoneGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData) const;
|
||||
virtual void ReadMorphs(IExportContext* context, IMorphData* morphData, const IModelData* modelData, int modelIndex);
|
||||
virtual bool ReadMorphGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, int modelIndex, const IMorphData* morphData, int morphIndex, const IMaterialData* materialData);
|
||||
virtual bool HasValidPosController(const IModelData* modelData, int modelIndex) const;
|
||||
virtual bool HasValidRotController(const IModelData* modelData, int modelIndex) const;
|
||||
virtual bool HasValidSclController(const IModelData* modelData, int modelIndex) const;
|
||||
protected:
|
||||
IExportSource* source;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSOURCEDECORATORBASE_H
|
||||
@@ -1,215 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ExportStatusWindow.h"
|
||||
#include "UI/Win32GUI.h"
|
||||
#include "StringHelpers.h"
|
||||
#include <process.h>
|
||||
#include <Windows.h>
|
||||
|
||||
enum
|
||||
{
|
||||
WM_USER_TASK_FINISHED = WM_USER + 53,
|
||||
WM_USER_ACCEPTED
|
||||
};
|
||||
|
||||
struct ThreadData
|
||||
{
|
||||
ExportStatusWindow* statusWindow;
|
||||
void (ExportStatusWindow::* initialize)(int width, int height, const std::vector<std::pair<std::string, std::string> >& tasks);
|
||||
void (ExportStatusWindow::* run)();
|
||||
int width;
|
||||
int height;
|
||||
const std::vector<std::pair<std::string, std::string> >* tasks;
|
||||
HANDLE initializedSemaphore;
|
||||
};
|
||||
unsigned int __stdcall ThreadFunc(void* threadDataMemory)
|
||||
{
|
||||
ThreadData* data = static_cast<ThreadData*>(threadDataMemory);
|
||||
ExportStatusWindow* statusWindow = data->statusWindow;
|
||||
void (ExportStatusWindow::* initialize)(int width, int height, const std::vector<std::pair<std::string, std::string> >& tasks) = data->initialize;
|
||||
void (ExportStatusWindow::* run)() = data->run;
|
||||
int width = data->width;
|
||||
int height = data->height;
|
||||
const std::vector<std::pair<std::string, std::string> >& tasks = *data->tasks;
|
||||
HANDLE initializedSemaphore = data->initializedSemaphore;
|
||||
|
||||
// Initialize the data.
|
||||
(statusWindow->*initialize)(width, height, tasks);
|
||||
|
||||
// Let the creating thread know that we have read the data - it is
|
||||
// now safe for it to clear it.
|
||||
ReleaseSemaphore(initializedSemaphore, 1, 0);
|
||||
|
||||
// Perform the main thread processing.
|
||||
(statusWindow->*run)();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
|
||||
ExportStatusWindow::ExportStatusWindow(int width, int height, const std::vector<std::pair<std::string, std::string> >& tasks)
|
||||
: m_threadHandle(0)
|
||||
, m_warningsEncountered(false)
|
||||
, m_errorsEncountered(false)
|
||||
, m_waitState(WaitState_WarningsAndErrors)
|
||||
, m_okButtonSpacer(0, 0, 2000, 0)
|
||||
, m_okButton(_T("OK"), this, &ExportStatusWindow::OkPressed)
|
||||
, m_okButtonLayout(Layout::DirectionHorizontal)
|
||||
{
|
||||
OutputDebugString(_T("Showing status window.\n"));
|
||||
|
||||
Win32GUI::Initialize();
|
||||
|
||||
HANDLE initializedSemaphore = CreateSemaphore(0, 0, 1, 0);
|
||||
|
||||
// Create a thread to handle the message pump for the window.
|
||||
ThreadData threadData;
|
||||
threadData.statusWindow = this;
|
||||
threadData.initialize = &ExportStatusWindow::Initialize;
|
||||
threadData.run = &ExportStatusWindow::Run;
|
||||
threadData.width = width;
|
||||
threadData.height = height;
|
||||
threadData.tasks = &tasks;
|
||||
threadData.initializedSemaphore = initializedSemaphore;
|
||||
m_threadHandle = (HANDLE)_beginthreadex(
|
||||
0, //void *security,
|
||||
0, //unsigned stack_size,
|
||||
ThreadFunc, //unsigned ( *start_address )( void * ),
|
||||
&threadData, //void *arglist,
|
||||
0, //unsigned initflag,
|
||||
0); //unsigned *thrdaddr
|
||||
|
||||
// Wait until the thread has read the data, since once we return the data will be lost.
|
||||
WaitForSingleObject(initializedSemaphore, INFINITE);
|
||||
CloseHandle(initializedSemaphore);
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
ExportStatusWindow::~ExportStatusWindow()
|
||||
{
|
||||
OutputDebugString(_T("Hiding status window.\n"));
|
||||
|
||||
// Tell the thread to exit and then wait for it to do so.
|
||||
if (HWND hwnd = (HWND)m_frameWindow.GetHWND())
|
||||
{
|
||||
PostMessage(hwnd, WM_USER_TASK_FINISHED, 0, 0);
|
||||
m_okButton.Enable(true);
|
||||
WaitForSingleObject((HANDLE)m_threadHandle, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
void ExportStatusWindow::Initialize(int width, int height, const std::vector<std::pair<std::string, std::string> >& tasks)
|
||||
{
|
||||
OutputDebugString(_T("Beginning status window thread.\n"));
|
||||
|
||||
for (int taskIndex = 0, taskCount = int(tasks.size()); taskIndex < taskCount; ++taskIndex)
|
||||
{
|
||||
m_taskList.AddTask(tasks[taskIndex].first, tasks[taskIndex].second);
|
||||
}
|
||||
|
||||
m_okButtonLayout.AddComponent(&m_okButtonSpacer);
|
||||
m_okButtonLayout.AddComponent(&m_okButton);
|
||||
m_okButton.Enable(false);
|
||||
|
||||
m_frameWindow.AddComponent(&m_taskList);
|
||||
m_frameWindow.AddComponent(&m_progressBar);
|
||||
m_frameWindow.AddComponent(&m_logWindow);
|
||||
m_frameWindow.AddComponent(&m_okButtonLayout);
|
||||
m_frameWindow.Show(true, width, height);
|
||||
}
|
||||
|
||||
void ExportStatusWindow::Run()
|
||||
{
|
||||
MSG msg;
|
||||
BOOL status;
|
||||
bool waitingAcceptance = false;
|
||||
while ((status = GetMessage(&msg, HWND(0), UINT(0), UINT(0))) != 0)
|
||||
{
|
||||
if (status == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (msg.message == WM_USER_TASK_FINISHED)
|
||||
{
|
||||
if (m_waitState == WaitState_Always ||
|
||||
(m_waitState == WaitState_WarningsAndErrors && m_warningsEncountered || m_errorsEncountered) ||
|
||||
(m_waitState == WaitState_ErrorsOnly && m_errorsEncountered))
|
||||
{
|
||||
waitingAcceptance = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (waitingAcceptance && msg.message == WM_USER_ACCEPTED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
m_frameWindow.Show(false, 0, 0);
|
||||
OutputDebugString(_T("Ending status window thread.\n"));
|
||||
}
|
||||
|
||||
void ExportStatusWindow::OkPressed()
|
||||
{
|
||||
if (HWND hwnd = (HWND)m_frameWindow.GetHWND())
|
||||
{
|
||||
PostMessage(hwnd, WM_USER_ACCEPTED, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ExportStatusWindow::SetWaitState(WaitState state)
|
||||
{
|
||||
m_waitState = state;
|
||||
}
|
||||
|
||||
void ExportStatusWindow::AddTask(const std::string& id, const std::string& description)
|
||||
{
|
||||
m_taskList.AddTask(id, description);
|
||||
}
|
||||
|
||||
void ExportStatusWindow::SetCurrentTask(const std::string& id)
|
||||
{
|
||||
m_taskList.SetCurrentTask(id);
|
||||
}
|
||||
|
||||
void ExportStatusWindow::SetProgress(float progress)
|
||||
{
|
||||
TCHAR buffer[2048];
|
||||
_sntprintf_s(buffer, sizeof(buffer), _TRUNCATE, _T("%.1f%% complete - exporting scene."), progress * 100);
|
||||
m_frameWindow.SetCaption(buffer);
|
||||
m_progressBar.SetProgress(progress);
|
||||
}
|
||||
|
||||
void ExportStatusWindow::Log(ILogger::ESeverity eSeverity, const char* message)
|
||||
{
|
||||
if (eSeverity == ILogger::eSeverity_Error)
|
||||
{
|
||||
m_errorsEncountered = true;
|
||||
}
|
||||
else if (eSeverity == ILogger::eSeverity_Warning)
|
||||
{
|
||||
m_warningsEncountered = true;
|
||||
}
|
||||
|
||||
m_logWindow.Log(eSeverity, StringHelpers::ConvertString<tstring>(message).c_str());
|
||||
}
|
||||
@@ -1,67 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSTATUSWINDOW_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSTATUSWINDOW_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "UI/FrameWindow.h"
|
||||
#include "UI/ProgressBar.h"
|
||||
#include "UI/TaskList.h"
|
||||
#include "UI/LogWindow.h"
|
||||
#include "UI/Spacer.h"
|
||||
#include "UI/Layout.h"
|
||||
#include "UI/PushButton.h"
|
||||
#include "ILogger.h"
|
||||
|
||||
class ExportStatusWindow
|
||||
{
|
||||
public:
|
||||
enum WaitState
|
||||
{
|
||||
WaitState_WarningsAndErrors,
|
||||
WaitState_ErrorsOnly,
|
||||
WaitState_Always,
|
||||
WaitState_Never,
|
||||
};
|
||||
|
||||
ExportStatusWindow(int width, int height, const std::vector<std::pair<std::string, std::string> >& tasks);
|
||||
~ExportStatusWindow();
|
||||
|
||||
void SetWaitState(WaitState state);
|
||||
|
||||
void AddTask(const std::string& id, const std::string& description);
|
||||
void SetCurrentTask(const std::string& id);
|
||||
void SetProgress(float progress);
|
||||
void Log(ILogger::ESeverity eSeverity, const char* message);
|
||||
|
||||
private:
|
||||
void Initialize(int width, int height, const std::vector<std::pair<std::string, std::string> >& tasks);
|
||||
void Run();
|
||||
void OkPressed();
|
||||
|
||||
FrameWindow m_frameWindow;
|
||||
TaskList m_taskList;
|
||||
ProgressBar m_progressBar;
|
||||
Spacer m_okButtonSpacer;
|
||||
PushButton m_okButton;
|
||||
Layout m_okButtonLayout;
|
||||
LogWindow m_logWindow;
|
||||
void* m_threadHandle;
|
||||
bool m_warningsEncountered;
|
||||
bool m_errorsEncountered;
|
||||
WaitState m_waitState;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSTATUSWINDOW_H
|
||||
@@ -1,82 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "GeometryData.h"
|
||||
|
||||
GeometryData::GeometryData()
|
||||
{
|
||||
}
|
||||
|
||||
int GeometryData::AddPosition(float x, float y, float z)
|
||||
{
|
||||
int positionIndex = int(this->positions.size());
|
||||
this->positions.push_back(Vector(x, y, z));
|
||||
return positionIndex;
|
||||
}
|
||||
|
||||
int GeometryData::AddNormal(float x, float y, float z)
|
||||
{
|
||||
int normalIndex = int(this->normals.size());
|
||||
this->normals.push_back(Vector(x, y, z));
|
||||
return normalIndex;
|
||||
}
|
||||
|
||||
int GeometryData::AddTextureCoordinate(float u, float v)
|
||||
{
|
||||
int textureCoordinateIndex = int(this->textureCoordinates.size());
|
||||
this->textureCoordinates.push_back(TextureCoordinate(u, v));
|
||||
return textureCoordinateIndex;
|
||||
}
|
||||
|
||||
int GeometryData::AddVertexColor(float r, float g, float b, float a)
|
||||
{
|
||||
int vertexColorIndex = int(this->vertexColors.size());
|
||||
this->vertexColors.push_back(VertexColor(r, g, b, a));
|
||||
return vertexColorIndex;
|
||||
}
|
||||
|
||||
int GeometryData::AddPolygon(const int* indices, int mtlID)
|
||||
{
|
||||
int polygonIndex = int(this->polygons.size());
|
||||
this->polygons.push_back(Polygon(mtlID,
|
||||
Polygon::Vertex(indices[0], indices[1], indices[2], indices[3]),
|
||||
Polygon::Vertex(indices[4], indices[5], indices[6], indices[7]),
|
||||
Polygon::Vertex(indices[8], indices[9], indices[10], indices[11])));
|
||||
return polygonIndex;
|
||||
}
|
||||
|
||||
int GeometryData::GetNumberOfPositions() const
|
||||
{
|
||||
return (int)this->positions.size();
|
||||
}
|
||||
|
||||
int GeometryData::GetNumberOfNormals() const
|
||||
{
|
||||
return (int)this->normals.size();
|
||||
}
|
||||
|
||||
int GeometryData::GetNumberOfTextureCoordinates() const
|
||||
{
|
||||
return (int)this->textureCoordinates.size();
|
||||
}
|
||||
|
||||
int GeometryData::GetNumberOfVertexColors() const
|
||||
{
|
||||
return (int)this->vertexColors.size();
|
||||
}
|
||||
|
||||
int GeometryData::GetNumberOfPolygons() const
|
||||
{
|
||||
return (int)this->polygons.size();
|
||||
}
|
||||
@@ -1,102 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IGeometryData.h"
|
||||
#include <vector>
|
||||
|
||||
class GeometryData
|
||||
: public IGeometryData
|
||||
{
|
||||
public:
|
||||
GeometryData();
|
||||
|
||||
// IGeometryData
|
||||
virtual int AddPosition(float x, float y, float z);
|
||||
virtual int AddNormal(float x, float y, float z);
|
||||
virtual int AddTextureCoordinate(float u, float v);
|
||||
virtual int AddVertexColor(float r, float g, float b, float a);
|
||||
|
||||
virtual int AddPolygon(const int* indices, int mtlID);
|
||||
|
||||
virtual int GetNumberOfPositions() const;
|
||||
virtual int GetNumberOfNormals() const;
|
||||
virtual int GetNumberOfTextureCoordinates() const;
|
||||
virtual int GetNumberOfVertexColors() const;
|
||||
|
||||
virtual int GetNumberOfPolygons() const;
|
||||
|
||||
struct Vector
|
||||
{
|
||||
Vector(float x, float y, float z)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, z(z) {}
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
struct TextureCoordinate
|
||||
{
|
||||
TextureCoordinate(float u, float v)
|
||||
: u(u)
|
||||
, v(v) {}
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct VertexColor
|
||||
{
|
||||
VertexColor(float r, float g, float b, float a)
|
||||
: r(r)
|
||||
, g(g)
|
||||
, b(b)
|
||||
, a(a) {}
|
||||
float r, g, b, a;
|
||||
};
|
||||
|
||||
struct Polygon
|
||||
{
|
||||
struct Vertex
|
||||
{
|
||||
Vertex() {}
|
||||
Vertex(int positionIndex, int normalIndex, int textureCoordinateIndex, int vertexColorIndex)
|
||||
: positionIndex(positionIndex)
|
||||
, normalIndex(normalIndex)
|
||||
, textureCoordinateIndex(textureCoordinateIndex)
|
||||
, vertexColorIndex(vertexColorIndex) {}
|
||||
int positionIndex, normalIndex, textureCoordinateIndex, vertexColorIndex;
|
||||
};
|
||||
|
||||
Polygon(int mtlID, const Vertex& v0, const Vertex& v1, const Vertex& v2)
|
||||
: mtlID(mtlID)
|
||||
{
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
}
|
||||
|
||||
int mtlID;
|
||||
Vertex v[3];
|
||||
};
|
||||
|
||||
std::vector<Vector> positions;
|
||||
std::vector<Vector> normals;
|
||||
std::vector<TextureCoordinate> textureCoordinates;
|
||||
std::vector<VertexColor> vertexColors;
|
||||
std::vector<Polygon> polygons;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYDATA_H
|
||||
@@ -1,54 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "GeometryExportSourceAdapter.h"
|
||||
#include "IGeometryFileData.h"
|
||||
#include <cassert>
|
||||
|
||||
GeometryExportSourceAdapter::GeometryExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryFileData, const std::vector<int>& geometryFileIndices)
|
||||
: ExportSourceDecoratorBase(source)
|
||||
, m_geometryFileData(geometryFileData)
|
||||
, m_geometryFileIndices(geometryFileIndices)
|
||||
{
|
||||
assert(m_geometryFileIndices.size() <= m_geometryFileData->GetGeometryFileCount());
|
||||
for (size_t i = 0; i < m_geometryFileIndices.size(); ++i)
|
||||
{
|
||||
int const geometryFileIndex = m_geometryFileIndices[i];
|
||||
assert(geometryFileIndex >= 0 && geometryFileIndex < m_geometryFileData->GetGeometryFileCount());
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryExportSourceAdapter::ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData)
|
||||
{
|
||||
for (size_t i = 0; i < m_geometryFileIndices.size(); ++i)
|
||||
{
|
||||
int const geometryFileIndex = m_geometryFileIndices[i];
|
||||
int const newGeometryFileIndex = geometryFileData->AddGeometryFile(
|
||||
m_geometryFileData->GetGeometryFileHandle(geometryFileIndex),
|
||||
m_geometryFileData->GetGeometryFileName(geometryFileIndex),
|
||||
m_geometryFileData->GetProperties(geometryFileIndex));
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryExportSourceAdapter::ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData)
|
||||
{
|
||||
assert(geometryFileIndex >= 0 && geometryFileIndex < m_geometryFileIndices.size());
|
||||
this->source->ReadModels(m_geometryFileData, m_geometryFileIndices[geometryFileIndex], modelData);
|
||||
}
|
||||
|
||||
bool GeometryExportSourceAdapter::ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData)
|
||||
{
|
||||
assert(geometryFileIndex >= 0 && geometryFileIndex < m_geometryFileIndices.size());
|
||||
return this->source->ReadSkeleton(m_geometryFileData, m_geometryFileIndices[geometryFileIndex], modelData, modelIndex, materialData, skeletonData);
|
||||
}
|
||||
@@ -1,36 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYEXPORTSOURCEADAPTER_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYEXPORTSOURCEADAPTER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ExportSourceDecoratorBase.h"
|
||||
|
||||
class GeometryExportSourceAdapter
|
||||
: public ExportSourceDecoratorBase
|
||||
{
|
||||
public:
|
||||
GeometryExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryFileData, const std::vector<int>& geometryFileIndices);
|
||||
|
||||
virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData);
|
||||
virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData);
|
||||
virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData);
|
||||
|
||||
private:
|
||||
IGeometryFileData* m_geometryFileData;
|
||||
std::vector<int> m_geometryFileIndices;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYEXPORTSOURCEADAPTER_H
|
||||
@@ -1,59 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "GeometryFileData.h"
|
||||
|
||||
int GeometryFileData::AddGeometryFile(const void* handle, const char* name, const SProperties& properties)
|
||||
{
|
||||
const int geometryFileIndex = int(m_geometryFiles.size());
|
||||
m_geometryFiles.push_back(GeometryFileEntry(handle, name, properties));
|
||||
return geometryFileIndex;
|
||||
}
|
||||
|
||||
int GeometryFileData::GetGeometryFileCount() const
|
||||
{
|
||||
return int(m_geometryFiles.size());
|
||||
}
|
||||
|
||||
const void* GeometryFileData::GetGeometryFileHandle(int geometryFileIndex) const
|
||||
{
|
||||
return m_geometryFiles[geometryFileIndex].handle;
|
||||
}
|
||||
|
||||
const char* GeometryFileData::GetGeometryFileName(int geometryFileIndex) const
|
||||
{
|
||||
return m_geometryFiles[geometryFileIndex].name.c_str();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const IGeometryFileData::SProperties& GeometryFileData::GetProperties(int geometryFileIndex) const
|
||||
{
|
||||
if (size_t(geometryFileIndex) >= m_geometryFiles.size())
|
||||
{
|
||||
assert(0);
|
||||
static SProperties badValue;
|
||||
return badValue;
|
||||
}
|
||||
return m_geometryFiles[geometryFileIndex].properties;
|
||||
}
|
||||
|
||||
void GeometryFileData::SetProperties(int geometryFileIndex, const IGeometryFileData::SProperties& properties)
|
||||
{
|
||||
if (size_t(geometryFileIndex) >= m_geometryFiles.size())
|
||||
{
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
m_geometryFiles[geometryFileIndex].properties = properties;
|
||||
}
|
||||
@@ -1,52 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYFILEDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYFILEDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IGeometryFileData.h"
|
||||
#include "STLHelpers.h"
|
||||
|
||||
class GeometryFileData
|
||||
: public IGeometryFileData
|
||||
{
|
||||
public:
|
||||
// IGeometryFileData
|
||||
virtual int AddGeometryFile(const void* handle, const char* name, const SProperties& properties);
|
||||
virtual const SProperties& GetProperties(int geometryFileIndex) const;
|
||||
virtual void SetProperties(int geometryFileIndex, const SProperties& properties);
|
||||
virtual int GetGeometryFileCount() const;
|
||||
virtual const void* GetGeometryFileHandle(int geometryFileIndex) const;
|
||||
virtual const char* GetGeometryFileName(int geometryFileIndex) const;
|
||||
|
||||
private:
|
||||
struct GeometryFileEntry
|
||||
{
|
||||
GeometryFileEntry(const void* a_handle, const char* a_name, const SProperties& a_properties)
|
||||
: handle(a_handle)
|
||||
, name(a_name)
|
||||
, properties(a_properties)
|
||||
{
|
||||
}
|
||||
|
||||
const void* handle;
|
||||
std::string name;
|
||||
SProperties properties;
|
||||
};
|
||||
|
||||
std::vector<GeometryFileEntry> m_geometryFiles;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYFILEDATA_H
|
||||
@@ -1,36 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "GeometryMaterialData.h"
|
||||
|
||||
void GeometryMaterialData::AddUsedMaterialIndex(int materialIndex)
|
||||
{
|
||||
std::map<int, int>::iterator usedMaterialPos = m_usedMaterialIndexIndexMap.find(materialIndex);
|
||||
if (usedMaterialPos == m_usedMaterialIndexIndexMap.end())
|
||||
{
|
||||
int materialIndexIndex = int(m_usedMaterialIndices.size());
|
||||
m_usedMaterialIndices.push_back(materialIndex);
|
||||
m_usedMaterialIndexIndexMap.insert(std::make_pair(materialIndex, materialIndexIndex));
|
||||
}
|
||||
}
|
||||
|
||||
int GeometryMaterialData::GetUsedMaterialCount() const
|
||||
{
|
||||
return int(m_usedMaterialIndices.size());
|
||||
}
|
||||
|
||||
int GeometryMaterialData::GetUsedMaterialIndex(int usedMaterialIndex) const
|
||||
{
|
||||
return m_usedMaterialIndices[usedMaterialIndex];
|
||||
}
|
||||
@@ -1,35 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYMATERIALDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYMATERIALDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IGeometryMaterialData.h"
|
||||
|
||||
class GeometryMaterialData
|
||||
: public IGeometryMaterialData
|
||||
{
|
||||
public:
|
||||
// IGeometryMaterialData
|
||||
virtual void AddUsedMaterialIndex(int materialIndex);
|
||||
virtual int GetUsedMaterialCount() const;
|
||||
virtual int GetUsedMaterialIndex(int usedMaterialIndex) const;
|
||||
|
||||
private:
|
||||
std::vector<int> m_usedMaterialIndices;
|
||||
std::map<int, int> m_usedMaterialIndexIndexMap;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYMATERIALDATA_H
|
||||
@@ -1,41 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_HELPERDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_HELPERDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
struct SHelperData
|
||||
{
|
||||
public:
|
||||
enum EHelperType
|
||||
{
|
||||
eHelperType_UNKNOWN,
|
||||
eHelperType_Point,
|
||||
eHelperType_Dummy
|
||||
};
|
||||
|
||||
public:
|
||||
SHelperData()
|
||||
: m_eHelperType(eHelperType_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
EHelperType m_eHelperType;
|
||||
float m_boundBoxMin[3]; // used for eHelperType_Dummy only
|
||||
float m_boundBoxMax[3]; // used for eHelperType_Dummy only
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_HELPERDATA_H
|
||||
@@ -1,96 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IANIMATIONDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IANIMATIONDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class IAnimationData
|
||||
{
|
||||
public:
|
||||
virtual ~IAnimationData() {}
|
||||
|
||||
virtual void SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3]) = 0;
|
||||
virtual void SetFrameCount(int frameCount) = 0;
|
||||
|
||||
virtual void SetFrameTimePos(int modelIndex, int frameIndex, float time) = 0;
|
||||
virtual void SetFrameDataPos(int modelIndex, int frameIndex, float translation[3]) = 0;
|
||||
virtual void SetFrameCountPos(int modelIndex, int frameCount) = 0;
|
||||
virtual void SetFrameTimeRot(int modelIndex, int frameIndex, float time) = 0;
|
||||
virtual void SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3]) = 0;
|
||||
virtual void SetFrameCountRot(int modelIndex, int frameCount) = 0;
|
||||
virtual void SetFrameTimeScl(int modelIndex, int frameIndex, float time) = 0;
|
||||
virtual void SetFrameDataScl(int modelIndex, int frameIndex, float scale[3]) = 0;
|
||||
virtual void SetFrameCountScl(int modelIndex, int frameCount) = 0;
|
||||
|
||||
// For TCB & Ease-In/-Out support
|
||||
struct TCB
|
||||
{
|
||||
float tension;
|
||||
float continuity;
|
||||
float bias;
|
||||
|
||||
TCB()
|
||||
: tension(0)
|
||||
, continuity(0)
|
||||
, bias(0) {}
|
||||
};
|
||||
struct Ease
|
||||
{
|
||||
float in;
|
||||
float out;
|
||||
|
||||
Ease()
|
||||
: in(0)
|
||||
, out(0) {}
|
||||
};
|
||||
virtual void SetFrameTCBPos(int modelIndex, int frameIndex, TCB tcb) = 0;
|
||||
virtual void SetFrameTCBRot(int modelIndex, int frameIndex, TCB tcb) = 0;
|
||||
virtual void SetFrameTCBScl(int modelIndex, int frameIndex, TCB tcb) = 0;
|
||||
virtual void SetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease ease) = 0;
|
||||
virtual void SetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease ease) = 0;
|
||||
virtual void SetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease ease) = 0;
|
||||
|
||||
enum ModelFlags
|
||||
{
|
||||
ModelFlags_NoExport = 1 << 0
|
||||
};
|
||||
|
||||
virtual void SetModelFlags(int modelIndex, unsigned modelFlags) = 0;
|
||||
|
||||
virtual void GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const = 0;
|
||||
virtual int GetFrameCount() const = 0;
|
||||
|
||||
virtual float GetFrameTimePos(int modelIndex, int frameIndex) const = 0;
|
||||
virtual void GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const = 0;
|
||||
virtual int GetFrameCountPos(int modelIndex) const = 0;
|
||||
virtual float GetFrameTimeRot(int modelIndex, int frameIndex) const = 0;
|
||||
virtual void GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const = 0;
|
||||
virtual int GetFrameCountRot(int modelIndex) const = 0;
|
||||
virtual float GetFrameTimeScl(int modelIndex, int frameIndex) const = 0;
|
||||
virtual void GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const = 0;
|
||||
virtual int GetFrameCountScl(int modelIndex) const = 0;
|
||||
|
||||
// For TCB & Ease-In/-Out support
|
||||
virtual void GetFrameTCBPos(int modelIndex, int frameIndex, TCB& tcb) const = 0;
|
||||
virtual void GetFrameTCBRot(int modelIndex, int frameIndex, TCB& tcb) const = 0;
|
||||
virtual void GetFrameTCBScl(int modelIndex, int frameIndex, TCB& tcb) const = 0;
|
||||
virtual void GetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease& ease) const = 0;
|
||||
virtual void GetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease& ease) const = 0;
|
||||
virtual void GetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease& ease) const = 0;
|
||||
|
||||
virtual unsigned GetModelFlags(int modelIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IANIMATIONDATA_H
|
||||
@@ -1,55 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTCONTEXT_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTCONTEXT_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cstdarg>
|
||||
#include "Exceptions.h"
|
||||
#include "ILogger.h"
|
||||
|
||||
struct IPakSystem;
|
||||
class ISettings;
|
||||
|
||||
class IExportContext
|
||||
: public ILogger
|
||||
{
|
||||
public:
|
||||
// Declare an exception type to report the case where the scene must be saved before exporting.
|
||||
struct NeedSaveErrorTag {};
|
||||
typedef Exception<NeedSaveErrorTag> NeedSaveError;
|
||||
struct PakSystemErrorTag {};
|
||||
typedef Exception<PakSystemErrorTag> PakSystemError;
|
||||
|
||||
virtual void SetProgress(float progress) = 0;
|
||||
virtual void SetCurrentTask(const std::string& id) = 0;
|
||||
virtual IPakSystem* GetPakSystem() = 0;
|
||||
virtual ISettings* GetSettings() = 0;
|
||||
virtual void GetRootPath(char* buffer, int bufferSizeInBytes) = 0;
|
||||
|
||||
protected:
|
||||
// ILogger
|
||||
virtual void LogImpl(ILogger::ESeverity eSeverity, const char* message) = 0;
|
||||
};
|
||||
|
||||
struct CurrentTaskScope
|
||||
{
|
||||
CurrentTaskScope(IExportContext* context, const std::string& id)
|
||||
: context(context) {context->SetCurrentTask(id); }
|
||||
~CurrentTaskScope() {context->SetCurrentTask(""); }
|
||||
IExportContext* context;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTCONTEXT_H
|
||||
@@ -1,98 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTSOURCE_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTSOURCE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Exceptions.h"
|
||||
|
||||
class ISkeletonData;
|
||||
class IAnimationData;
|
||||
class IExportContext;
|
||||
class IModelData;
|
||||
class IGeometryFileData;
|
||||
class IGeometryData;
|
||||
class IMaterialData;
|
||||
class ISkinningData;
|
||||
class IMorphData;
|
||||
class IGeometryMaterialData;
|
||||
|
||||
namespace ExportGlobal
|
||||
{
|
||||
const float g_defaultFrameRate = 30.f;
|
||||
};
|
||||
|
||||
struct SExportMetaData
|
||||
{
|
||||
enum EAxisUp
|
||||
{
|
||||
X_UP,
|
||||
Y_UP,
|
||||
Z_UP
|
||||
};
|
||||
|
||||
char authoring_tool[128];
|
||||
char source_data[1024]; // Filename of the source.
|
||||
char author[128]; // Name of the author.
|
||||
char revision[64];
|
||||
EAxisUp up_axis;
|
||||
float fMeterUnit;
|
||||
float fFramesPerSecond;
|
||||
|
||||
SExportMetaData()
|
||||
{
|
||||
fMeterUnit = 1.0f;
|
||||
up_axis = Z_UP;
|
||||
fFramesPerSecond = ExportGlobal::g_defaultFrameRate;
|
||||
strcpy(authoring_tool, "CryENGINE Collada Exporter");
|
||||
strcpy(source_data, "");
|
||||
strcpy(author, "");
|
||||
strcpy(revision, "1.4.1");
|
||||
}
|
||||
};
|
||||
|
||||
class IExportSource
|
||||
{
|
||||
public:
|
||||
virtual ~IExportSource()
|
||||
{
|
||||
}
|
||||
virtual std::string GetResourceCompilerPath() const = 0;
|
||||
virtual void GetMetaData(SExportMetaData& metaData) const = 0;
|
||||
virtual std::string GetDCCFileName() const = 0;
|
||||
virtual float GetDCCFrameRate() const{ return ExportGlobal::g_defaultFrameRate; }
|
||||
virtual std::string GetExportDirectory() const = 0;
|
||||
virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData) = 0;
|
||||
virtual bool ReadMaterials(IExportContext* context, const IGeometryFileData* geometryFileData, IMaterialData* materialData) = 0;
|
||||
virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData) = 0;
|
||||
virtual void ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* modelData, int modelIndex, ISkeletonData* skeletonData) = 0;
|
||||
virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData) = 0;
|
||||
virtual int GetAnimationCount() const = 0;
|
||||
virtual std::string GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const = 0;
|
||||
virtual void GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const = 0;
|
||||
virtual void ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const = 0;
|
||||
virtual IAnimationData* ReadAnimation(IExportContext* context, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const = 0;
|
||||
virtual bool ReadGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, const IMaterialData* materialData, int modelIndex) = 0;
|
||||
virtual bool ReadGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, const IModelData* modelData, const IMaterialData* materialData, int modelIndex) const = 0;
|
||||
virtual bool ReadBoneGeometry(IExportContext* context, IGeometryData* geometry, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData) = 0;
|
||||
virtual bool ReadBoneGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData) const = 0;
|
||||
virtual void ReadMorphs(IExportContext* context, IMorphData* morphData, const IModelData* modelData, int modelIndex) = 0;
|
||||
virtual bool ReadMorphGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, int modelIndex, const IMorphData* morphData, int morphIndex, const IMaterialData* materialData) = 0;
|
||||
virtual bool HasValidPosController(const IModelData* modelData, int modelIndex) const = 0;
|
||||
virtual bool HasValidRotController(const IModelData* modelData, int modelIndex) const = 0;
|
||||
virtual bool HasValidSclController(const IModelData* modelData, int modelIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTSOURCE_H
|
||||
@@ -1,35 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class IGeometryData
|
||||
{
|
||||
public:
|
||||
virtual int AddPosition(float x, float y, float z) = 0;
|
||||
virtual int AddNormal(float x, float y, float z) = 0;
|
||||
virtual int AddTextureCoordinate(float u, float v) = 0;
|
||||
virtual int AddVertexColor(float r, float g, float b, float a) = 0;
|
||||
virtual int AddPolygon(const int* indices, int mtlID) = 0;
|
||||
|
||||
virtual int GetNumberOfPositions() const = 0;
|
||||
virtual int GetNumberOfNormals() const = 0;
|
||||
virtual int GetNumberOfTextureCoordinates() const = 0;
|
||||
virtual int GetNumberOfVertexColors() const = 0;
|
||||
virtual int GetNumberOfPolygons() const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYDATA_H
|
||||
@@ -1,54 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYFILEDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYFILEDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ExportFileType.h"
|
||||
#include <string>
|
||||
|
||||
class IGeometryFileData
|
||||
{
|
||||
public:
|
||||
struct SProperties
|
||||
{
|
||||
int filetypeInt; // combination of flags from CryFileType
|
||||
bool bDoNotMerge;
|
||||
bool bUseCustomNormals;
|
||||
bool bUseF32VertexFormat;
|
||||
bool b8WeightsPerVertex;
|
||||
std::string customExportPath;
|
||||
|
||||
SProperties()
|
||||
: filetypeInt(CRY_FILE_TYPE_NONE)
|
||||
, bDoNotMerge(false)
|
||||
, bUseCustomNormals(false)
|
||||
, bUseF32VertexFormat(false)
|
||||
, b8WeightsPerVertex(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
public:
|
||||
virtual int AddGeometryFile(const void* handle, const char* name, const SProperties& properties) = 0;
|
||||
virtual const SProperties& GetProperties(int geometryFileIndex) const = 0;
|
||||
virtual int GetGeometryFileCount() const = 0;
|
||||
|
||||
// return an implementation-specific handle (for example a maya Dag Path string, or a MAX node name or whatever)
|
||||
// its opaque to the exporter, but you can cast it yourself.
|
||||
virtual const void* GetGeometryFileHandle(int geometryFileIndex) const = 0;
|
||||
virtual const char* GetGeometryFileName(int geometryFileIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYFILEDATA_H
|
||||
@@ -1,27 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYMATERIALDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYMATERIALDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class IGeometryMaterialData
|
||||
{
|
||||
public:
|
||||
virtual void AddUsedMaterialIndex(int materialIndex) = 0;
|
||||
virtual int GetUsedMaterialCount() const = 0;
|
||||
virtual int GetUsedMaterialIndex(int usedMaterialIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYMATERIALDATA_H
|
||||
@@ -1,33 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMATERIALDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMATERIALDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class IMaterialData
|
||||
{
|
||||
public:
|
||||
// the handle represents an implementation specific underlying handle (like a maya pointer to a string dag name).
|
||||
virtual int AddMaterial(const char* name, int id, const void* handle, const char* properties) = 0;
|
||||
virtual int AddMaterial(const char* name, int id, const char* subMatName, const void* handle, const char* properties) = 0;
|
||||
virtual int GetMaterialCount() const = 0;
|
||||
virtual const char* GetName(int materialIndex) const = 0;
|
||||
virtual int GetID(int materialIndex) const = 0;
|
||||
virtual const char* GetSubMatName(int materialIndex) const = 0;
|
||||
virtual const void* GetHandle(int materialIndex) const = 0;
|
||||
virtual const char* GetProperties(int materialIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMATERIALDATA_H
|
||||
@@ -1,36 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMODELDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMODELDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "HelperData.h"
|
||||
#include <string>
|
||||
|
||||
class IModelData
|
||||
{
|
||||
public:
|
||||
virtual int AddModel(const void* handle, const char* modelName, int parentModelIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString) = 0;
|
||||
virtual int GetModelCount() const = 0;
|
||||
virtual const void* GetModelHandle(int modelIndex) const = 0;
|
||||
virtual const char* GetModelName(int modelIndex) const = 0;
|
||||
virtual void SetTranslationRotationScale(int modelIndex, const float* translation, const float* rotation, const float* scale) = 0;
|
||||
virtual void GetTranslationRotationScale(int modelIndex, float* translation, float* rotation, float* scale) const = 0;
|
||||
virtual const SHelperData& GetHelperData(int modelIndex) const = 0;
|
||||
virtual const std::string& GetProperties(int modelIndex) const = 0;
|
||||
virtual bool IsRoot(int modelIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMODELDATA_H
|
||||
@@ -1,29 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMORPHDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMORPHDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class IMorphData
|
||||
{
|
||||
public:
|
||||
virtual void SetHandle(const void* handle) = 0;
|
||||
virtual void AddMorph(const void* handle, const char* name, const char* fullName = NULL) = 0;
|
||||
virtual const void* GetHandle() const = 0;
|
||||
virtual int GetMorphCount() const = 0;
|
||||
virtual const void* GetMorphHandle(int morphIndex) const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMORPHDATA_H
|
||||
@@ -1,56 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKELETONDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKELETONDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class ISkeletonData
|
||||
{
|
||||
public:
|
||||
enum Axis
|
||||
{
|
||||
AxisX,
|
||||
AxisY,
|
||||
AxisZ
|
||||
};
|
||||
enum Limit
|
||||
{
|
||||
LimitMin,
|
||||
LimitMax
|
||||
};
|
||||
|
||||
virtual int AddBone(const void* handle, const char* name, int parentIndex) = 0;
|
||||
virtual int FindBone(const char* name) const = 0;
|
||||
virtual const void* GetBoneHandle(int boneIndex) const = 0;
|
||||
virtual int GetBoneParentIndex(int boneIndex) const = 0;
|
||||
virtual int GetBoneCount() const = 0;
|
||||
virtual void SetTranslation(int boneIndex, const float* vec) = 0;
|
||||
virtual void SetRotation(int boneIndex, const float* vec) = 0;
|
||||
virtual void SetScale(int boneIndex, const float* vec) = 0;
|
||||
virtual void SetParentFrameTranslation(int boneIndex, const float* vec) = 0;
|
||||
virtual void SetParentFrameRotation(int boneIndex, const float* vec) = 0;
|
||||
virtual void SetParentFrameScale(int boneIndex, const float* vec) = 0;
|
||||
virtual void SetPhysicalized(int boneIndex, bool physicalized) = 0;
|
||||
virtual void SetHasGeometry(int boneIndex, bool hasGeometry) = 0;
|
||||
virtual void SetBoneProperties(int boneIndex, const char* propertiesString) = 0;
|
||||
virtual void SetBoneGeomProperties(int boneIndex, const char* propertiesString) = 0;
|
||||
|
||||
virtual void SetLimit(int boneIndex, Axis axis, Limit extreme, float limit) = 0;
|
||||
virtual void SetSpringTension(int boneIndex, Axis axis, float springTension) = 0;
|
||||
virtual void SetSpringAngle(int boneIndex, Axis axis, float springAngle) = 0;
|
||||
virtual void SetAxisDamping(int boneIndex, Axis axis, float damping) = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKELETONDATA_H
|
||||
@@ -1,69 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "MaterialData.h"
|
||||
|
||||
int MaterialData::AddMaterial(const char* name, int id, const void* handle, const char* properties)
|
||||
{
|
||||
const int materialIndex = int(m_materials.size());
|
||||
m_materials.push_back(MaterialEntry(name, id, "submat", handle, properties));
|
||||
return materialIndex;
|
||||
}
|
||||
|
||||
int MaterialData::AddMaterial(const char* name, int id, const char* subMatName, const void* handle, const char* properties)
|
||||
{
|
||||
const int materialIndex = int(m_materials.size());
|
||||
m_materials.push_back(MaterialEntry(name, id, subMatName, handle, properties));
|
||||
return materialIndex;
|
||||
}
|
||||
|
||||
int MaterialData::GetMaterialCount() const
|
||||
{
|
||||
return int(m_materials.size());
|
||||
}
|
||||
|
||||
const char* MaterialData::GetName(int materialIndex) const
|
||||
{
|
||||
assert(materialIndex >= 0);
|
||||
assert(materialIndex < int(m_materials.size()));
|
||||
return m_materials[materialIndex].name.c_str();
|
||||
}
|
||||
|
||||
int MaterialData::GetID(int materialIndex) const
|
||||
{
|
||||
assert(materialIndex >= 0);
|
||||
assert(materialIndex < int(m_materials.size()));
|
||||
return m_materials[materialIndex].id;
|
||||
}
|
||||
|
||||
const char* MaterialData::GetSubMatName(int materialIndex) const
|
||||
{
|
||||
assert(materialIndex >= 0);
|
||||
assert(materialIndex < int(m_materials.size()));
|
||||
return m_materials[materialIndex].subMatName.c_str();
|
||||
}
|
||||
|
||||
const void* MaterialData::GetHandle(int materialIndex) const
|
||||
{
|
||||
assert(materialIndex >= 0);
|
||||
assert(materialIndex < int(m_materials.size()));
|
||||
return m_materials[materialIndex].handle;
|
||||
}
|
||||
|
||||
const char* MaterialData::GetProperties(int materialIndex) const
|
||||
{
|
||||
assert(materialIndex >= 0);
|
||||
assert(materialIndex < int(m_materials.size()));
|
||||
return m_materials[materialIndex].properties.c_str();
|
||||
}
|
||||
@@ -1,56 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IMaterialData.h"
|
||||
|
||||
class MaterialData
|
||||
: public IMaterialData
|
||||
{
|
||||
public:
|
||||
virtual int AddMaterial(const char* name, int id, const void* handle, const char* properties);
|
||||
virtual int AddMaterial(const char* name, int id, const char* subMatName, const void* handle, const char* properties);
|
||||
virtual int GetMaterialCount() const;
|
||||
virtual const char* GetName(int materialIndex) const;
|
||||
virtual int GetID(int materialIndex) const;
|
||||
virtual const char* GetSubMatName(int materialIndex) const;
|
||||
virtual const void* GetHandle(int materialIndex) const;
|
||||
virtual const char* GetProperties(int materialIndex) const;
|
||||
|
||||
private:
|
||||
struct MaterialEntry
|
||||
{
|
||||
MaterialEntry(const char* a_name, int a_id, const char* a_subMatName, const void* a_handle, const char* a_properties)
|
||||
: name(a_name)
|
||||
, id(a_id)
|
||||
, subMatName(a_subMatName)
|
||||
, handle(a_handle)
|
||||
, properties(a_properties ? a_properties : "")
|
||||
{
|
||||
}
|
||||
|
||||
string name;
|
||||
int id;
|
||||
string subMatName;
|
||||
const void* handle;
|
||||
string properties;
|
||||
};
|
||||
|
||||
std::vector<MaterialEntry> m_materials;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALDATA_H
|
||||
@@ -1,107 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "MaterialHelpers.h"
|
||||
#include "StringHelpers.h"
|
||||
#include "PathHelpers.h"
|
||||
#include "properties.h"
|
||||
|
||||
MaterialHelpers::MaterialInfo::MaterialInfo()
|
||||
{
|
||||
this->id = -1;
|
||||
this->name = "";
|
||||
this->physicalize = "None";
|
||||
this->diffuseTexture = "";
|
||||
this->diffuseColor[0] = this->diffuseColor[1] = this->diffuseColor[2] = 1.0f;
|
||||
this->specularColor[0] = this->specularColor[1] = this->specularColor[2] = 1.0f;
|
||||
this->emissiveColor[0] = this->emissiveColor[1] = this->emissiveColor[2] = 0.0f;
|
||||
}
|
||||
|
||||
std::string MaterialHelpers::PhysicsIDToString(const int physicsID)
|
||||
{
|
||||
switch (physicsID)
|
||||
{
|
||||
case 1:
|
||||
return "Default";
|
||||
break;
|
||||
case 2:
|
||||
return "ProxyNoDraw";
|
||||
break;
|
||||
case 3:
|
||||
return "NoCollide";
|
||||
break;
|
||||
case 4:
|
||||
return "Obstruct";
|
||||
break;
|
||||
default:
|
||||
return "None";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool MaterialHelpers::WriteMaterials(const std::string& filename, const std::vector<MaterialInfo>& materialList)
|
||||
{
|
||||
FILE* materialFile = fopen(filename.c_str(), "w");
|
||||
if (materialFile)
|
||||
{
|
||||
fprintf(materialFile, "<Material MtlFlags=\"524544\" >\n");
|
||||
fprintf(materialFile, " <SubMaterials>\n");
|
||||
for (int i = 0; i < materialList.size(); i++)
|
||||
{
|
||||
const MaterialInfo& material = materialList[i];
|
||||
|
||||
fprintf(materialFile, " <Material Name=\"%s\" ", material.name.c_str());
|
||||
|
||||
if (strcmp(material.physicalize.c_str(), "ProxyNoDraw") == 0)
|
||||
{
|
||||
fprintf(materialFile, "MtlFlags=\"1152\" Shader=\"Nodraw\" GenMask=\"0\" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(materialFile, "MtlFlags=\"524416\" Shader=\"Illum\" GenMask=\"100000000\" ");
|
||||
}
|
||||
|
||||
fprintf(materialFile, "SurfaceType=\"\" MatTemplate=\"\" ");
|
||||
fprintf(materialFile, "Diffuse=\"%f,%f,%f\" ", material.diffuseColor[0], material.diffuseColor[1], material.diffuseColor[2]);
|
||||
fprintf(materialFile, "Specular=\"%f,%f,%f\" ", material.specularColor[0], material.specularColor[1], material.specularColor[2]);
|
||||
fprintf(materialFile, "Emissive=\"%f,%f,%f\" ", material.emissiveColor[0], material.emissiveColor[1], material.emissiveColor[2]);
|
||||
fprintf(materialFile, "Shininess=\"10\" ");
|
||||
fprintf(materialFile, "Opacity=\"1\" ");
|
||||
fprintf(materialFile, ">\n");
|
||||
|
||||
fprintf(materialFile, " <Textures>\n");
|
||||
|
||||
// Write out diffuse texture.
|
||||
if (material.diffuseTexture.length() > 0)
|
||||
{
|
||||
//fprintf( materialFile, " <Texture Map=\"Diffuse\" File=\"%s\" >\n", ProcessTexturePath( material.diffuseTexture ).c_str() );
|
||||
fprintf(materialFile, " <Texture Map=\"Diffuse\" File=\"%s\" >\n", material.diffuseTexture.c_str());
|
||||
fprintf(materialFile, " <TexMod />\n");
|
||||
fprintf(materialFile, " </Texture>\n");
|
||||
}
|
||||
|
||||
fprintf(materialFile, " </Textures>\n");
|
||||
fprintf(materialFile, " </Material>\n");
|
||||
}
|
||||
fprintf(materialFile, " </SubMaterials>\n");
|
||||
fprintf(materialFile, "</Material>\n");
|
||||
fclose(materialFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALHELPERS_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALHELPERS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace MaterialHelpers
|
||||
{
|
||||
struct MaterialInfo
|
||||
{
|
||||
MaterialInfo();// : id(-1) { }
|
||||
|
||||
std::string name;
|
||||
std::string physicalize;
|
||||
int id;
|
||||
|
||||
float diffuseColor[3];
|
||||
float specularColor[3];
|
||||
float emissiveColor[3];
|
||||
std::string diffuseTexture;
|
||||
};
|
||||
|
||||
std::string PhysicsIDToString(const int physicsID);
|
||||
bool WriteMaterials(const std::string& filename, const std::vector<MaterialHelpers::MaterialInfo>& materialList);
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALHELPERS_H
|
||||
@@ -1,138 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXHELPERS_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXHELPERS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CompileTimeAssert.h"
|
||||
#include "PathHelpers.h"
|
||||
#include "StringHelpers.h"
|
||||
|
||||
|
||||
namespace MaxHelpers
|
||||
{
|
||||
enum
|
||||
{
|
||||
kBadChar = '_'
|
||||
};
|
||||
|
||||
#if !defined(MAX_PRODUCT_VERSION_MAJOR)
|
||||
#error MAX_PRODUCT_VERSION_MAJOR is undefined
|
||||
#elif (MAX_PRODUCT_VERSION_MAJOR >= 15)
|
||||
COMPILE_TIME_ASSERT(sizeof(MCHAR) == 2);
|
||||
#define MAX_MCHAR_SIZE 2
|
||||
typedef wstring MaxCompatibleString;
|
||||
#elif (MAX_PRODUCT_VERSION_MAJOR >= 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(MCHAR) == 1);
|
||||
#define MAX_MCHAR_SIZE 1
|
||||
typedef string MaxCompatibleString;
|
||||
#else
|
||||
#error 3dsMax 2009 and older are not supported anymore
|
||||
#endif
|
||||
|
||||
inline string CreateAsciiString(const char* s_ansi)
|
||||
{
|
||||
return StringHelpers::ConvertAnsiToAscii(s_ansi, kBadChar);
|
||||
}
|
||||
|
||||
|
||||
inline string CreateAsciiString(const wchar_t* s_utf16)
|
||||
{
|
||||
const string s_ansi = StringHelpers::ConvertUtf16ToAnsi(s_utf16, kBadChar);
|
||||
return CreateAsciiString(s_ansi.c_str());
|
||||
}
|
||||
|
||||
|
||||
inline string CreateUtf8String(const char* s_ansi)
|
||||
{
|
||||
return StringHelpers::ConvertAnsiToUtf8(s_ansi);
|
||||
}
|
||||
|
||||
|
||||
inline string CreateUtf8String(const wchar_t* s_utf16)
|
||||
{
|
||||
return StringHelpers::ConvertUtf16ToUtf8(s_utf16);
|
||||
}
|
||||
|
||||
|
||||
inline string CreateTidyAsciiNodeName(const char* s_ansi)
|
||||
{
|
||||
const size_t len = strlen(s_ansi);
|
||||
|
||||
string res;
|
||||
res.reserve(len);
|
||||
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
char c = s_ansi[i];
|
||||
if (c < ' ' || c >= 127)
|
||||
{
|
||||
c = kBadChar;
|
||||
}
|
||||
res.append(1, c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
inline string CreateTidyAsciiNodeName(const wchar_t* s_utf16)
|
||||
{
|
||||
const string s_ansi = StringHelpers::ConvertUtf16ToAnsi(s_utf16, kBadChar);
|
||||
return CreateTidyAsciiNodeName(s_ansi.c_str());
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
inline MSTR CreateMaxStringFromAscii(const char* s_ascii)
|
||||
{
|
||||
#if (MAX_MCHAR_SIZE == 2)
|
||||
return MSTR(StringHelpers::ConvertAsciiToUtf16(s_ascii).c_str());
|
||||
#else
|
||||
return MSTR(s_ascii);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline MaxCompatibleString CreateMaxCompatibleStringFromAscii(const char* s_ascii)
|
||||
{
|
||||
#if (MAX_MCHAR_SIZE == 2)
|
||||
return StringHelpers::ConvertAsciiToUtf16(s_ascii);
|
||||
#else
|
||||
return MaxCompatibleString(s_ascii);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline string GetAbsoluteAsciiPath(const char* s_ansi)
|
||||
{
|
||||
if (!s_ansi || !s_ansi[0])
|
||||
{
|
||||
return string();
|
||||
}
|
||||
return PathHelpers::GetAbsoluteAsciiPath(StringHelpers::ConvertAnsiToUtf16(s_ansi).c_str());
|
||||
}
|
||||
|
||||
|
||||
inline string GetAbsoluteAsciiPath(const wchar_t* s_utf16)
|
||||
{
|
||||
if (!s_utf16 || !s_utf16[0])
|
||||
{
|
||||
return string();
|
||||
}
|
||||
return PathHelpers::GetAbsoluteAsciiPath(s_utf16);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXHELPERS_H
|
||||
@@ -1,99 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "MaxUserPropertyHelpers.h"
|
||||
#include "StringHelpers.h"
|
||||
#include "MaxHelpers.h"
|
||||
|
||||
|
||||
std::string MaxUserPropertyHelpers::GetNodeProperties(INode* node)
|
||||
{
|
||||
if (node == 0)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
MSTR buf;
|
||||
node->GetUserPropBuffer(buf);
|
||||
|
||||
return MaxHelpers::CreateAsciiString(buf);
|
||||
}
|
||||
|
||||
|
||||
std::string MaxUserPropertyHelpers::GetStringNodeProperty(INode* node, const char* name, const char* defaultValue)
|
||||
{
|
||||
if (node == 0)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
MSTR val;
|
||||
if (!node->GetUserPropString(MaxHelpers::CreateMaxStringFromAscii(name), val))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return MaxHelpers::CreateAsciiString(val);
|
||||
}
|
||||
|
||||
|
||||
float MaxUserPropertyHelpers::GetFloatNodeProperty(INode* node, const char* name, float defaultValue)
|
||||
{
|
||||
if (node == 0)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
float val;
|
||||
if (!node->GetUserPropFloat(MaxHelpers::CreateMaxStringFromAscii(name), val))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int MaxUserPropertyHelpers::GetIntNodeProperty(INode* node, const char* name, int defaultValue)
|
||||
{
|
||||
if (node == 0)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
int val;
|
||||
if (!node->GetUserPropInt(MaxHelpers::CreateMaxStringFromAscii(name), val))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
bool MaxUserPropertyHelpers::GetBoolNodeProperty(INode* node, const char* name, bool defaultValue)
|
||||
{
|
||||
if (node == 0)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
BOOL val;
|
||||
if (!node->GetUserPropBool(MaxHelpers::CreateMaxStringFromAscii(name), val))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return (val != 0);
|
||||
}
|
||||
@@ -1,32 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXUSERPROPERTYHELPERS_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXUSERPROPERTYHELPERS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
class INode;
|
||||
|
||||
namespace MaxUserPropertyHelpers
|
||||
{
|
||||
std::string GetNodeProperties(INode* node);
|
||||
std::string GetStringNodeProperty(INode* node, const char* name, const char* defaultValue);
|
||||
float GetFloatNodeProperty(INode* node, const char* name, float defaultValue);
|
||||
int GetIntNodeProperty(INode* node, const char* name, int defaultValue);
|
||||
bool GetBoolNodeProperty(INode* node, const char* name, bool defaultValue);
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXUSERPROPERTYHELPERS_H
|
||||
@@ -1,914 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MESHUTILS_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MESHUTILS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "BaseTypes.h" // uint8
|
||||
#include "Cry_Vector3.h" // Vec3
|
||||
#include "IIndexedMesh.h" // CMesh
|
||||
namespace MeshUtils
|
||||
{
|
||||
struct Face
|
||||
{
|
||||
int vertexIndex[3];
|
||||
};
|
||||
|
||||
struct Color
|
||||
{
|
||||
uint8 r;
|
||||
uint8 g;
|
||||
uint8 b;
|
||||
};
|
||||
|
||||
// Stores linking of a vertex to bone(s)
|
||||
class VertexLinks
|
||||
{
|
||||
public:
|
||||
struct Link
|
||||
{
|
||||
int boneId;
|
||||
float weight;
|
||||
Vec3 offset;
|
||||
|
||||
Link()
|
||||
: boneId(-1)
|
||||
, weight(-1.0f)
|
||||
, offset(0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
enum ESort
|
||||
{
|
||||
eSort_ByWeight,
|
||||
eSort_ByBoneId,
|
||||
};
|
||||
|
||||
public:
|
||||
std::vector<Link> links;
|
||||
|
||||
public:
|
||||
// minWeightToDelete: links with weights <= minWeightToDelete will be deleted
|
||||
const char* Normalize(ESort eSort, const float minWeightToDelete, const int maxLinkCount)
|
||||
{
|
||||
if (minWeightToDelete < 0 || minWeightToDelete >= 1)
|
||||
{
|
||||
return "Bad minWeightToDelete passed";
|
||||
}
|
||||
if (maxLinkCount <= 0)
|
||||
{
|
||||
return "Bad maxLinkCount passed";
|
||||
}
|
||||
|
||||
// Merging links with matching bone ids
|
||||
{
|
||||
DeleteByWeight(0.0f);
|
||||
|
||||
if (links.empty())
|
||||
{
|
||||
return "All bone links of a vertex have zero weight";
|
||||
}
|
||||
|
||||
std::sort(links.begin(), links.end(), CompareLinksByBoneId);
|
||||
|
||||
size_t dst = 0;
|
||||
for (size_t i = 1; i < links.size(); ++i)
|
||||
{
|
||||
if (links[i].boneId == links[dst].boneId)
|
||||
{
|
||||
const float w0 = links[dst].weight;
|
||||
const float w1 = links[i].weight;
|
||||
const float a = w0 / (w0 + w1);
|
||||
links[dst].offset = links[dst].offset * a + links[i].offset * (1 - a);
|
||||
links[dst].weight = w0 + w1;
|
||||
}
|
||||
else
|
||||
{
|
||||
links[++dst] = links[i];
|
||||
}
|
||||
}
|
||||
|
||||
links.resize(dst + 1);
|
||||
}
|
||||
|
||||
// Deleting links, normalizing link weights.
|
||||
//
|
||||
// Note: we produce meaningful results even in cases like this:
|
||||
// input weights are { 0.03, 0.01 }, minWeightTodelete is 0.2.
|
||||
// Output weights produced are { 0.75, 0.25 }.
|
||||
{
|
||||
std::sort(links.begin(), links.end(), CompareLinksByWeight);
|
||||
|
||||
if (links.size() > maxLinkCount)
|
||||
{
|
||||
links.resize(maxLinkCount);
|
||||
}
|
||||
|
||||
NormalizeWeights();
|
||||
|
||||
const size_t oldSize = links.size();
|
||||
|
||||
DeleteByWeight(minWeightToDelete);
|
||||
|
||||
if (links.empty())
|
||||
{
|
||||
return "All bone links of a vertex are deleted (minWeightToDelete is too big)";
|
||||
}
|
||||
|
||||
if (links.size() != oldSize)
|
||||
{
|
||||
NormalizeWeights();
|
||||
}
|
||||
}
|
||||
|
||||
switch (eSort)
|
||||
{
|
||||
case eSort_ByWeight:
|
||||
// Do nothing because we already sorted links by weight (see above)
|
||||
break;
|
||||
case eSort_ByBoneId:
|
||||
std::sort(links.begin(), links.end(), CompareLinksByBoneId);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void DeleteByWeight(float minWeightToDelete)
|
||||
{
|
||||
for (size_t i = 0; i < links.size(); ++i)
|
||||
{
|
||||
if (links[i].weight <= minWeightToDelete)
|
||||
{
|
||||
if (i < links.size() - 1)
|
||||
{
|
||||
links[i] = links[links.size() - 1];
|
||||
}
|
||||
links.resize(links.size() - 1);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NormalizeWeights()
|
||||
{
|
||||
assert(!links.empty() && links[0].weight > 0);
|
||||
|
||||
float w = 0;
|
||||
|
||||
for (size_t i = 0; i < links.size(); ++i)
|
||||
{
|
||||
w += links[i].weight;
|
||||
}
|
||||
|
||||
w = 1 / w;
|
||||
|
||||
for (size_t i = 0; i < links.size(); ++i)
|
||||
{
|
||||
links[i].weight *= w;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CompareLinksByBoneId(const Link& left, const Link& right)
|
||||
{
|
||||
if (left.boneId != right.boneId)
|
||||
{
|
||||
return left.boneId < right.boneId;
|
||||
}
|
||||
if (left.weight != right.weight)
|
||||
{
|
||||
return left.weight < right.weight;
|
||||
}
|
||||
return memcmp(&left.offset, &right.offset, sizeof(left.offset)) < 0;
|
||||
}
|
||||
|
||||
static bool CompareLinksByWeight(const Link& left, const Link& right)
|
||||
{
|
||||
if (left.weight != right.weight)
|
||||
{
|
||||
return left.weight > right.weight;
|
||||
}
|
||||
if (left.boneId != right.boneId)
|
||||
{
|
||||
return left.boneId < right.boneId;
|
||||
}
|
||||
return memcmp(&left.offset, &right.offset, sizeof(left.offset)) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
// Vertex data
|
||||
std::vector<Vec3> m_positions;
|
||||
std::vector<int> m_topologyIds;
|
||||
std::vector<Vec3> m_normals;
|
||||
std::vector<std::vector<Vec2>> m_texCoords;
|
||||
std::vector<Color> m_colors;
|
||||
std::vector<uint8> m_alphas;
|
||||
std::vector<VertexLinks> m_links;
|
||||
std::vector<int> m_vertexMatIds;
|
||||
size_t m_auxSizeof;
|
||||
std::vector<uint8> m_aux;
|
||||
|
||||
// Face data
|
||||
std::vector<Face> m_faces;
|
||||
std::vector<int> m_faceMatIds;
|
||||
|
||||
// Mappings computed and filled by ComputeVertexRemapping()
|
||||
std::vector<int> m_vertexOldToNew;
|
||||
std::vector<int> m_vertexNewToOld;
|
||||
|
||||
public:
|
||||
Mesh()
|
||||
: m_auxSizeof(0)
|
||||
{
|
||||
}
|
||||
|
||||
int GetVertexCount() const
|
||||
{
|
||||
return m_positions.size();
|
||||
}
|
||||
|
||||
int GetFaceCount() const
|
||||
{
|
||||
return m_faces.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_positions.clear();
|
||||
m_topologyIds.clear();
|
||||
m_normals.clear();
|
||||
m_texCoords.clear();
|
||||
m_colors.clear();
|
||||
m_alphas.clear();
|
||||
m_links.clear();
|
||||
m_vertexMatIds.clear();
|
||||
m_aux.clear();
|
||||
|
||||
m_faces.clear();
|
||||
m_faceMatIds.clear();
|
||||
|
||||
m_vertexOldToNew.clear();
|
||||
m_vertexNewToOld.clear();
|
||||
}
|
||||
|
||||
const char* SetPositions(const float* pVec3, int count, int stride, const float scale)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad position count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < sizeof(Vec3)))
|
||||
{
|
||||
return "bad position stride";
|
||||
}
|
||||
|
||||
m_positions.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const float* const p = (const float*)(((const char*)pVec3) + ((size_t)i * stride));
|
||||
if (!_finite(p[0]) || !_finite(p[1]) || !_finite(p[2]))
|
||||
{
|
||||
m_positions.clear();
|
||||
return "Illegal (NAN) vertex position. Fix the 3d Model.";
|
||||
}
|
||||
m_positions[i].x = p[0] * scale;
|
||||
m_positions[i].y = p[1] * scale;
|
||||
m_positions[i].z = p[2] * scale;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetTopologyIds(const int* pTopo, int count, int stride)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad topologyId count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < sizeof(int)))
|
||||
{
|
||||
return "bad topologyId stride";
|
||||
}
|
||||
|
||||
m_topologyIds.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const int* const p = (const int*)(((const char*)pTopo) + ((size_t)i * stride));
|
||||
m_topologyIds[i] = p[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetNormals(const float* pVec3, int count, int stride)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad normal count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < sizeof(Vec3)))
|
||||
{
|
||||
return "bad normal stride";
|
||||
}
|
||||
|
||||
m_normals.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const float* const p = (const float*)(((const char*)pVec3) + ((size_t)i * stride));
|
||||
if (!_finite(p[0]) || !_finite(p[1]) || !_finite(p[2]))
|
||||
{
|
||||
m_normals.clear();
|
||||
return "Illegal (NAN) vertex normal. Fix the 3d Model.";
|
||||
}
|
||||
m_normals[i].x = p[0];
|
||||
m_normals[i].y = p[1];
|
||||
m_normals[i].z = p[2];
|
||||
m_normals[i] = m_normals[i].GetNormalizedSafe(Vec3_OneZ);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetTexCoords(const float* pVec2, int count, int stride, bool bFlipT, uint streamIndex)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad texCoord count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < sizeof(float) * 2))
|
||||
{
|
||||
return "bad texCoord stride";
|
||||
}
|
||||
if (m_texCoords.size() <= streamIndex)
|
||||
{
|
||||
m_texCoords.resize(streamIndex + 1);
|
||||
}
|
||||
|
||||
m_texCoords[streamIndex].resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const float* const p = (const float*)(((const char*)pVec2) + ((size_t)i * stride));
|
||||
if (!_finite(p[0]) || !_finite(p[1]))
|
||||
{
|
||||
m_texCoords[streamIndex].clear();
|
||||
return "Illegal (NAN) texture coordinate. Fix the 3d Model.";
|
||||
}
|
||||
m_texCoords[streamIndex][i].x = p[0];
|
||||
m_texCoords[streamIndex][i].y = bFlipT ? 1 - p[1] : p[1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetColors(const uint8* pRgb, int count, int stride)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad color count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < 3))
|
||||
{
|
||||
return "bad color stride";
|
||||
}
|
||||
|
||||
m_colors.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const uint8* const p = (((const uint8*)pRgb) + ((size_t)i * stride));
|
||||
m_colors[i].r = p[0];
|
||||
m_colors[i].g = p[1];
|
||||
m_colors[i].b = p[2];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetAlphas(const uint8* pAlpha, int count, int stride)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad alpha count";
|
||||
}
|
||||
if (stride < 0)
|
||||
{
|
||||
return "bad alpha stride";
|
||||
}
|
||||
|
||||
m_alphas.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const uint8* const p = (((const uint8*)pAlpha) + ((size_t)i * stride));
|
||||
m_alphas[i] = p[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetFaces(const int* pVertIdx3, int count, int stride)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad face count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < 3 * sizeof(int)))
|
||||
{
|
||||
return "bad face stride";
|
||||
}
|
||||
|
||||
m_faces.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const int* const p = (const int*)(((const char*)pVertIdx3) + ((size_t)i * stride));
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
if (p[j] < 0 || p[j] >= m_positions.size())
|
||||
{
|
||||
return "bad vertex index found in a face";
|
||||
}
|
||||
m_faces[i].vertexIndex[j] = p[j];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetFaceMatIds(const int* pMatIds, int count, int stride, int maxMaterialId)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad face materialId count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < sizeof(int)))
|
||||
{
|
||||
return "bad face materialIdstride";
|
||||
}
|
||||
|
||||
m_faceMatIds.resize(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const int* const p = (const int*)(((const char*)pMatIds) + ((size_t)i * stride));
|
||||
if (p[0] < 0)
|
||||
{
|
||||
return "negative material ID found in a face";
|
||||
}
|
||||
if (p[0] >= maxMaterialId)
|
||||
{
|
||||
return "material ID found in a face is outside of allowed ranges";
|
||||
}
|
||||
m_faceMatIds[i] = p[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SetAux(size_t auxSizeof, const void* pData, int count, int stride)
|
||||
{
|
||||
if (auxSizeof <= 0)
|
||||
{
|
||||
return "bad aux sizeof";
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
return "bad aux count";
|
||||
}
|
||||
if (stride < 0 || (stride > 0 && stride < auxSizeof))
|
||||
{
|
||||
return "bad aux stride";
|
||||
}
|
||||
|
||||
m_auxSizeof = auxSizeof;
|
||||
|
||||
m_aux.resize(count * m_auxSizeof);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
const uint8* const p = (((const uint8*)pData) + ((size_t)i * stride));
|
||||
memcpy(&m_aux[i * m_auxSizeof], p, m_auxSizeof);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Validation
|
||||
|
||||
// Returns 0 if ok, or pointer to the error text
|
||||
const char* Validate() const
|
||||
{
|
||||
const int nVerts = (int)m_positions.size();
|
||||
if (nVerts <= 0)
|
||||
{
|
||||
return "No vertices";
|
||||
}
|
||||
|
||||
const int nFaces = (int)m_faces.size();
|
||||
if (nFaces <= 0)
|
||||
{
|
||||
return "No faces";
|
||||
}
|
||||
|
||||
if (!m_topologyIds.empty() && nVerts != (int)m_topologyIds.size())
|
||||
{
|
||||
return "Mismatch in the number of topology IDs";
|
||||
}
|
||||
|
||||
if (!m_normals.empty() && nVerts != (int)m_normals.size())
|
||||
{
|
||||
return "Mismatch in the number of normals";
|
||||
}
|
||||
|
||||
for (uint streamIndex = 0; streamIndex < m_texCoords.size(); ++streamIndex)
|
||||
{
|
||||
if (!m_texCoords[streamIndex].empty() && nVerts != (int)m_texCoords[streamIndex].size())
|
||||
{
|
||||
return "Mismatch in the number of texture coordinates";
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_colors.empty() && nVerts != (int)m_colors.size())
|
||||
{
|
||||
return "Mismatch in the number of colors";
|
||||
}
|
||||
|
||||
if (!m_alphas.empty() && nVerts != (int)m_alphas.size())
|
||||
{
|
||||
return "Mismatch in the number of alphas";
|
||||
}
|
||||
|
||||
if (!m_links.empty() && nVerts != (int)m_links.size())
|
||||
{
|
||||
return "Mismatch in the number of vertex-bone links";
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_links.size(); ++i)
|
||||
{
|
||||
if (m_links[i].links.empty())
|
||||
{
|
||||
return "Found a vertex without bone linking";
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_vertexMatIds.empty() && nVerts != (int)m_vertexMatIds.size())
|
||||
{
|
||||
return "Mismatch in the number of vertex materials";
|
||||
}
|
||||
|
||||
if (!m_aux.empty() && nVerts != (int)(m_aux.size() / m_auxSizeof))
|
||||
{
|
||||
return "Mismatch in the number of auxiliary elements";
|
||||
}
|
||||
|
||||
if (!m_faceMatIds.empty() && nFaces != (int)m_faceMatIds.size())
|
||||
{
|
||||
return "Mismatch in the number of face materials";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Computation
|
||||
|
||||
void RemoveDegenerateFaces()
|
||||
{
|
||||
int writePos = 0;
|
||||
for (int readPos = 0; readPos < (int)m_faces.size(); ++readPos)
|
||||
{
|
||||
const Face& face = m_faces[readPos];
|
||||
if (face.vertexIndex[0] != face.vertexIndex[1] &&
|
||||
face.vertexIndex[1] != face.vertexIndex[2] &&
|
||||
face.vertexIndex[0] != face.vertexIndex[2])
|
||||
{
|
||||
m_faces[writePos] = m_faces[readPos];
|
||||
if (!m_faceMatIds.empty())
|
||||
{
|
||||
m_faceMatIds[writePos] = m_faceMatIds[readPos];
|
||||
}
|
||||
++writePos;
|
||||
}
|
||||
}
|
||||
m_faces.resize(writePos);
|
||||
if (!m_faceMatIds.empty())
|
||||
{
|
||||
m_faceMatIds.resize(writePos);
|
||||
}
|
||||
}
|
||||
|
||||
int AddVertexCopy(int sourceVertexIndex)
|
||||
{
|
||||
if (sourceVertexIndex < 0 || sourceVertexIndex >= m_positions.size())
|
||||
{
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_positions.push_back(m_positions[sourceVertexIndex]);
|
||||
if (!m_topologyIds.empty())
|
||||
{
|
||||
m_topologyIds.push_back(m_topologyIds[sourceVertexIndex]);
|
||||
}
|
||||
if (!m_normals.empty())
|
||||
{
|
||||
m_normals.push_back(m_normals[sourceVertexIndex]);
|
||||
}
|
||||
for (uint streamIndex = 0; streamIndex < m_texCoords.size(); ++streamIndex)
|
||||
{
|
||||
if (!m_texCoords[streamIndex].empty())
|
||||
{
|
||||
m_texCoords[streamIndex].push_back(m_texCoords[streamIndex][sourceVertexIndex]);
|
||||
}
|
||||
}
|
||||
if (!m_colors.empty())
|
||||
{
|
||||
m_colors.push_back(m_colors[sourceVertexIndex]);
|
||||
}
|
||||
if (!m_alphas.empty())
|
||||
{
|
||||
m_alphas.push_back(m_alphas[sourceVertexIndex]);
|
||||
}
|
||||
if (!m_links.empty())
|
||||
{
|
||||
m_links.push_back(m_links[sourceVertexIndex]);
|
||||
}
|
||||
if (!m_vertexMatIds.empty())
|
||||
{
|
||||
m_vertexMatIds.push_back(m_vertexMatIds[sourceVertexIndex]);
|
||||
}
|
||||
if (!m_aux.empty())
|
||||
{
|
||||
m_aux.resize(m_aux.size() + m_auxSizeof);
|
||||
memcpy(&m_aux[m_aux.size() - m_auxSizeof], &m_aux[sourceVertexIndex * m_auxSizeof], m_auxSizeof);
|
||||
}
|
||||
return (int)m_positions.size() - 1;
|
||||
}
|
||||
|
||||
// Note: might create new vertices and modify vertex indices in faces
|
||||
void SetVertexMaterialIdsFromFaceMaterialIds()
|
||||
{
|
||||
m_vertexMatIds.clear();
|
||||
if (m_faceMatIds.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_vertexMatIds.resize(m_positions.size(), -1);
|
||||
|
||||
for (size_t i = 0; i < m_faces.size(); ++i)
|
||||
{
|
||||
const int faceMatId = m_faceMatIds[i];
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
int v = m_faces[i].vertexIndex[j];
|
||||
if (m_vertexMatIds[v] >= 0 && m_vertexMatIds[v] != faceMatId)
|
||||
{
|
||||
v = AddVertexCopy(v);
|
||||
m_faces[i].vertexIndex[j] = v;
|
||||
}
|
||||
m_vertexMatIds[v] = faceMatId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Computes m_vertexOldToNew and m_vertexNewToOld by detecting duplicate vertices
|
||||
void ComputeVertexRemapping()
|
||||
{
|
||||
const size_t nVerts = m_positions.size();
|
||||
|
||||
m_vertexNewToOld.resize(nVerts);
|
||||
for (size_t i = 0; i < nVerts; ++i)
|
||||
{
|
||||
m_vertexNewToOld[i] = i;
|
||||
}
|
||||
|
||||
VertexLess less(*this);
|
||||
std::sort(m_vertexNewToOld.begin(), m_vertexNewToOld.end(), less);
|
||||
|
||||
m_vertexOldToNew.resize(nVerts);
|
||||
|
||||
int nVertsNew = 0;
|
||||
for (size_t i = 0; i < nVerts; ++i)
|
||||
{
|
||||
if (i == 0 || less(m_vertexNewToOld[i - 1], m_vertexNewToOld[i]))
|
||||
{
|
||||
m_vertexNewToOld[nVertsNew++] = m_vertexNewToOld[i];
|
||||
}
|
||||
m_vertexOldToNew[m_vertexNewToOld[i]] = nVertsNew - 1;
|
||||
}
|
||||
m_vertexNewToOld.resize(nVertsNew);
|
||||
}
|
||||
|
||||
// Changes order of vertices, number of vertices, vertex indices in faces
|
||||
void RemoveVerticesByUsingComputedRemapping()
|
||||
{
|
||||
CompactVertices(m_positions, m_vertexNewToOld);
|
||||
CompactVertices(m_topologyIds, m_vertexNewToOld);
|
||||
CompactVertices(m_normals, m_vertexNewToOld);
|
||||
for (uint streamIndex = 0; streamIndex < m_texCoords.size(); ++streamIndex)
|
||||
{
|
||||
CompactVertices(m_texCoords[streamIndex], m_vertexNewToOld);
|
||||
}
|
||||
CompactVertices(m_colors, m_vertexNewToOld);
|
||||
CompactVertices(m_alphas, m_vertexNewToOld);
|
||||
CompactVertices(m_links, m_vertexNewToOld);
|
||||
CompactVertices(m_vertexMatIds, m_vertexNewToOld);
|
||||
CompactVerticesRaw(m_aux, m_auxSizeof, m_vertexNewToOld);
|
||||
|
||||
for (size_t i = 0, count = m_faces.size(); i < count; ++i)
|
||||
{
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
const int oldVertedIdx = m_faces[i].vertexIndex[j];
|
||||
assert(oldVertedIdx >= 0 && (size_t)oldVertedIdx < m_vertexOldToNew.size());
|
||||
const int newVertexIndex = m_vertexOldToNew[oldVertedIdx];
|
||||
m_faces[i].vertexIndex[j] = newVertexIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deleting degraded faces (faces with two or more vertices
|
||||
// sharing same position in space)
|
||||
void RemoveDegradedFaces()
|
||||
{
|
||||
size_t j = 0;
|
||||
|
||||
for (size_t i = 0, count = m_faces.size(); i < count; ++i)
|
||||
{
|
||||
const Vec3& p0 = m_positions[m_faces[i].vertexIndex[0]];
|
||||
const Vec3& p1 = m_positions[m_faces[i].vertexIndex[1]];
|
||||
const Vec3& p2 = m_positions[m_faces[i].vertexIndex[2]];
|
||||
if (p0 != p1 && p1 != p2 && p2 != p0)
|
||||
{
|
||||
m_faces[j] = m_faces[i];
|
||||
if (!m_faceMatIds.empty())
|
||||
{
|
||||
m_faceMatIds[j] = m_faceMatIds[i];
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
m_faces.resize(j);
|
||||
if (!m_faceMatIds.empty())
|
||||
{
|
||||
m_faceMatIds.resize(j);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Internal helpers
|
||||
|
||||
template<class T>
|
||||
static void CompactVertices(std::vector<T>& arr, const std::vector<int>& newToOld)
|
||||
{
|
||||
if (arr.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t newCount = newToOld.size();
|
||||
|
||||
std::vector<T> tmp;
|
||||
tmp.reserve(newCount);
|
||||
|
||||
for (size_t i = 0; i < newCount; ++i)
|
||||
{
|
||||
tmp.push_back(arr[newToOld[i]]);
|
||||
}
|
||||
|
||||
arr.swap(tmp);
|
||||
}
|
||||
|
||||
static void CompactVerticesRaw(std::vector<uint8>& arr, size_t elemSizeof, const std::vector<int>& newToOld)
|
||||
{
|
||||
if (arr.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t newCount = newToOld.size();
|
||||
|
||||
std::vector<uint8> tmp;
|
||||
tmp.resize(newCount * elemSizeof);
|
||||
|
||||
for (size_t i = 0; i < newCount; ++i)
|
||||
{
|
||||
memcpy(&tmp[i * elemSizeof], &arr[newToOld[i] * elemSizeof], elemSizeof);
|
||||
}
|
||||
|
||||
arr.swap(tmp);
|
||||
}
|
||||
|
||||
struct VertexLess
|
||||
{
|
||||
const Mesh& m;
|
||||
|
||||
VertexLess(const Mesh& mesh)
|
||||
: m(mesh)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(int a, int b) const
|
||||
{
|
||||
if (!m.m_topologyIds.empty())
|
||||
{
|
||||
const int res = m.m_topologyIds[a] - m.m_topologyIds[b];
|
||||
if (res != 0)
|
||||
{
|
||||
return res < 0;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const int res = memcmp(&m.m_positions[a], &m.m_positions[b], sizeof(m.m_positions[0]));
|
||||
if (res != 0)
|
||||
{
|
||||
return res < 0;
|
||||
}
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
|
||||
if (res == 0 && !m.m_normals.empty())
|
||||
{
|
||||
res = memcmp(&m.m_normals[a], &m.m_normals[b], sizeof(m.m_normals[0]));
|
||||
}
|
||||
|
||||
for (uint streamIndex = 0; streamIndex < m.m_texCoords.size(); ++streamIndex)
|
||||
{
|
||||
if (res == 0 && !m.m_texCoords[streamIndex].empty())
|
||||
{
|
||||
res = memcmp(&m.m_texCoords[streamIndex][a], &m.m_texCoords[streamIndex][b], sizeof(m.m_texCoords[streamIndex][0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 0 && !m.m_colors.empty())
|
||||
{
|
||||
res = memcmp(&m.m_colors[a], &m.m_colors[b], sizeof(m.m_colors[0]));
|
||||
}
|
||||
|
||||
if (res == 0 && !m.m_alphas.empty())
|
||||
{
|
||||
res = (int)m.m_alphas[a] - (int)m.m_alphas[b];
|
||||
}
|
||||
|
||||
if (res == 0 && !m.m_links.empty())
|
||||
{
|
||||
if (m.m_links[a].links.size() != m.m_links[b].links.size())
|
||||
{
|
||||
res = (m.m_links[a].links.size() < m.m_links[b].links.size()) ? -1 : +1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = memcmp(&m.m_links[a].links[0], &m.m_links[b].links[0], sizeof(m.m_links[a].links[0]) * m.m_links[a].links.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 0 && !m.m_vertexMatIds.empty())
|
||||
{
|
||||
res = m.m_vertexMatIds[a] - m.m_vertexMatIds[b];
|
||||
}
|
||||
|
||||
if (res == 0 && !m.m_aux.empty())
|
||||
{
|
||||
res = memcmp(&m.m_aux[a * m.m_auxSizeof], &m.m_aux[b * m.m_auxSizeof], m.m_auxSizeof);
|
||||
}
|
||||
|
||||
return res < 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
} // namespace MeshUtils
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MESHUTILS_H
|
||||
@@ -1,118 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ModelData.h"
|
||||
|
||||
int ModelData::AddModel(const void* handle, const char* modelName, int parentModelIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString)
|
||||
{
|
||||
int modelIndex = int(m_models.size());
|
||||
m_models.push_back(ModelEntry(handle, modelName, parentModelIndex, geometry, helperData, propertiesString));
|
||||
if (parentModelIndex >= 0)
|
||||
{
|
||||
m_models[parentModelIndex].children.push_back(modelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_roots.push_back(modelIndex);
|
||||
}
|
||||
return modelIndex;
|
||||
}
|
||||
|
||||
const void* ModelData::GetModelHandle(int modelIndex) const
|
||||
{
|
||||
return m_models[modelIndex].handle;
|
||||
}
|
||||
|
||||
const char* ModelData::GetModelName(int modelIndex) const
|
||||
{
|
||||
return m_models[modelIndex].name.c_str();
|
||||
}
|
||||
|
||||
void ModelData::SetTranslationRotationScale(int const modelIndex, const float* const translation, const float* const rotation, const float* const scale)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_models[modelIndex].translation[i] = translation[i];
|
||||
m_models[modelIndex].rotation[i] = rotation[i];
|
||||
m_models[modelIndex].scale[i] = scale[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::GetTranslationRotationScale(int const modelIndex, float* const translation, float* const rotation, float* const scale) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
translation[i] = m_models[modelIndex].translation[i];
|
||||
rotation[i] = m_models[modelIndex].rotation[i];
|
||||
scale[i] = m_models[modelIndex].scale[i];
|
||||
}
|
||||
}
|
||||
|
||||
const SHelperData& ModelData::GetHelperData(int modelIndex) const
|
||||
{
|
||||
return m_models[modelIndex].helperData;
|
||||
}
|
||||
|
||||
const std::string& ModelData::GetProperties(int modelIndex) const
|
||||
{
|
||||
return m_models[modelIndex].propertiesString;
|
||||
}
|
||||
|
||||
bool ModelData::IsRoot(int modelIndex) const
|
||||
{
|
||||
return (m_models[modelIndex].parentIndex < 0);
|
||||
}
|
||||
|
||||
int ModelData::GetModelCount() const
|
||||
{
|
||||
return int(m_models.size());
|
||||
}
|
||||
|
||||
int ModelData::GetRootCount() const
|
||||
{
|
||||
return int(m_roots.size());
|
||||
}
|
||||
|
||||
int ModelData::GetRootIndex(int rootIndex) const
|
||||
{
|
||||
return m_roots[rootIndex];
|
||||
}
|
||||
|
||||
int ModelData::GetChildCount(int modelIndex) const
|
||||
{
|
||||
return int(m_models[modelIndex].children.size());
|
||||
}
|
||||
|
||||
int ModelData::GetChildIndex(int modelIndex, int childIndexIndex) const
|
||||
{
|
||||
return m_models[modelIndex].children[childIndexIndex];
|
||||
}
|
||||
|
||||
bool ModelData::HasGeometry(int modelIndex) const
|
||||
{
|
||||
return m_models[modelIndex].geometry;
|
||||
}
|
||||
|
||||
ModelData::ModelEntry::ModelEntry(const void* a_handle, const std::string& a_name, int a_parentIndex, bool a_geometry, const SHelperData& a_helperData, const std::string& a_propertiesString)
|
||||
: handle(a_handle)
|
||||
, name(a_name)
|
||||
, parentIndex(a_parentIndex)
|
||||
, geometry(a_geometry)
|
||||
, helperData(a_helperData)
|
||||
, propertiesString(a_propertiesString)
|
||||
{
|
||||
translation[0] = translation[1] = translation[2] = 0.0f;
|
||||
rotation[0] = rotation[1] = rotation[2] = 0.0f;
|
||||
scale[0] = scale[1] = scale[2] = 1.0f;
|
||||
}
|
||||
@@ -1,63 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MODELDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MODELDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IModelData.h"
|
||||
|
||||
class ModelData
|
||||
: public IModelData
|
||||
{
|
||||
public:
|
||||
// IModelData
|
||||
virtual int AddModel(const void* handle, const char* name, int parentModelIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString);
|
||||
virtual int GetModelCount() const;
|
||||
virtual const void* GetModelHandle(int modelIndex) const;
|
||||
virtual const char* GetModelName(int modelIndex) const;
|
||||
virtual void SetTranslationRotationScale(int modelIndex, const float* translation, const float* rotation, const float* scale);
|
||||
virtual void GetTranslationRotationScale(int modelIndex, float* translation, float* rotation, float* scale) const;
|
||||
virtual const SHelperData& GetHelperData(int modelIndex) const;
|
||||
virtual const std::string& GetProperties(int modelIndex) const;
|
||||
virtual bool IsRoot(int modelIndex) const;
|
||||
|
||||
int GetRootCount() const;
|
||||
int GetRootIndex(int rootIndex) const;
|
||||
int GetChildCount(int modelIndex) const;
|
||||
int GetChildIndex(int modelIndex, int childIndexIndex) const;
|
||||
bool HasGeometry(int modelIndex) const;
|
||||
|
||||
private:
|
||||
struct ModelEntry
|
||||
{
|
||||
ModelEntry(const void* handle, const std::string& name, int parentIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString);
|
||||
|
||||
const void* handle;
|
||||
std::string name;
|
||||
int parentIndex;
|
||||
bool geometry;
|
||||
std::vector<int> children;
|
||||
float translation[3];
|
||||
float rotation[3];
|
||||
float scale[3];
|
||||
SHelperData helperData;
|
||||
std::string propertiesString;
|
||||
};
|
||||
|
||||
std::vector<ModelEntry> m_models;
|
||||
std::vector<int> m_roots;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MODELDATA_H
|
||||
@@ -1,55 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "MorphData.h"
|
||||
|
||||
MorphData::MorphData()
|
||||
: m_handle(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MorphData::SetHandle(const void* handle)
|
||||
{
|
||||
m_handle = handle;
|
||||
}
|
||||
|
||||
void MorphData::AddMorph(const void* handle, const char* name, const char* fullname)
|
||||
{
|
||||
m_morphs.push_back(Entry(handle, name, fullname ? fullname : ""));
|
||||
}
|
||||
|
||||
const void* MorphData::GetHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
int MorphData::GetMorphCount() const
|
||||
{
|
||||
return int(m_morphs.size());
|
||||
}
|
||||
|
||||
std::string MorphData::GetMorphName(int morphIndex) const
|
||||
{
|
||||
return m_morphs[morphIndex].name;
|
||||
}
|
||||
|
||||
std::string MorphData::GetMorphFullName(int morphIndex) const
|
||||
{
|
||||
return m_morphs[morphIndex].fullname.length() > 0 ? m_morphs[morphIndex].fullname : m_morphs[morphIndex].name;
|
||||
}
|
||||
|
||||
const void* MorphData::GetMorphHandle(int morphIndex) const
|
||||
{
|
||||
return m_morphs[morphIndex].handle;
|
||||
}
|
||||
@@ -1,52 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MORPHDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MORPHDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IMorphData.h"
|
||||
|
||||
class MorphData
|
||||
: public IMorphData
|
||||
{
|
||||
public:
|
||||
MorphData();
|
||||
|
||||
virtual void SetHandle(const void* handle);
|
||||
virtual void AddMorph(const void* handle, const char* name, const char* fullname);
|
||||
virtual const void* GetHandle() const;
|
||||
virtual int GetMorphCount() const;
|
||||
virtual const void* GetMorphHandle(int morphIndex) const;
|
||||
|
||||
std::string GetMorphName(int morphIndex) const;
|
||||
std::string GetMorphFullName(int morphIndex) const;
|
||||
|
||||
private:
|
||||
struct Entry
|
||||
{
|
||||
Entry(const void* handle, const std::string& name, const std::string& fullname)
|
||||
: handle(handle)
|
||||
, name(name)
|
||||
, fullname(fullname) {}
|
||||
const void* handle;
|
||||
std::string name;
|
||||
std::string fullname;
|
||||
};
|
||||
|
||||
const void* m_handle;
|
||||
std::vector<Entry> m_morphs;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MORPHDATA_H
|
||||
@@ -1,86 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SingleAnimationExportSourceAdapter.h"
|
||||
#include "IGeometryFileData.h"
|
||||
#include <cassert>
|
||||
|
||||
SingleAnimationExportSourceAdapter::SingleAnimationExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex)
|
||||
: ExportSourceDecoratorBase(source)
|
||||
, animationIndex(animationIndex)
|
||||
, geometryFileData(geometryFileData)
|
||||
, geometryFileIndex(geometryFileIndex)
|
||||
{
|
||||
assert(this->animationIndex < this->source->GetAnimationCount());
|
||||
}
|
||||
|
||||
float SingleAnimationExportSourceAdapter::GetDCCFrameRate() const
|
||||
{
|
||||
return this->source->GetDCCFrameRate();
|
||||
}
|
||||
|
||||
void SingleAnimationExportSourceAdapter::ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData)
|
||||
{
|
||||
const int geometryFileIndex = geometryFileData->AddGeometryFile(
|
||||
this->geometryFileData->GetGeometryFileHandle(this->geometryFileIndex),
|
||||
this->geometryFileData->GetGeometryFileName(this->geometryFileIndex),
|
||||
this->geometryFileData->GetProperties(this->geometryFileIndex));
|
||||
}
|
||||
|
||||
void SingleAnimationExportSourceAdapter::ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData)
|
||||
{
|
||||
assert(geometryFileIndex == 0);
|
||||
this->source->ReadModels(this->geometryFileData, this->geometryFileIndex, modelData);
|
||||
}
|
||||
|
||||
void SingleAnimationExportSourceAdapter::ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* const modelData, int modelIndex, ISkeletonData* skeletonData)
|
||||
{
|
||||
this->source->ReadSkinning(context, skinningData, modelData, modelIndex, skeletonData);
|
||||
}
|
||||
|
||||
bool SingleAnimationExportSourceAdapter::ReadSkeleton(const IGeometryFileData* const geometryFileData, int geometryFileIndex, const IModelData* const modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData)
|
||||
{
|
||||
assert(geometryFileIndex == 0);
|
||||
return this->source->ReadSkeleton(this->geometryFileData, this->geometryFileIndex, modelData, modelIndex, materialData, skeletonData);
|
||||
}
|
||||
|
||||
int SingleAnimationExportSourceAdapter::GetAnimationCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string SingleAnimationExportSourceAdapter::GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const
|
||||
{
|
||||
assert(geometryFileIndex == 0);
|
||||
assert(animationIndex == 0);
|
||||
return this->source->GetAnimationName(this->geometryFileData, this->geometryFileIndex, this->animationIndex);
|
||||
}
|
||||
|
||||
void SingleAnimationExportSourceAdapter::GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const
|
||||
{
|
||||
assert(animationIndex == 0);
|
||||
this->source->GetAnimationTimeSpan(start, stop, this->animationIndex);
|
||||
}
|
||||
|
||||
void SingleAnimationExportSourceAdapter::ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const
|
||||
{
|
||||
assert(animationIndex == 0);
|
||||
this->source->ReadAnimationFlags(context, animationData, geometryFileData, modelData, modelIndex, skeletonData, this->animationIndex);
|
||||
}
|
||||
|
||||
IAnimationData* SingleAnimationExportSourceAdapter::ReadAnimation(IExportContext* context, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const
|
||||
{
|
||||
assert(animationIndex == 0);
|
||||
return this->source->ReadAnimation(context, geometryFileData, modelData, modelIndex, skeletonData, this->animationIndex, fps);
|
||||
}
|
||||
@@ -1,45 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SINGLEANIMATIONEXPORTSOURCEADAPTER_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SINGLEANIMATIONEXPORTSOURCEADAPTER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ExportSourceDecoratorBase.h"
|
||||
|
||||
class SingleAnimationExportSourceAdapter
|
||||
: public ExportSourceDecoratorBase
|
||||
{
|
||||
public:
|
||||
SingleAnimationExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryData, int geometryFileIndex, int animationIndex);
|
||||
|
||||
virtual float GetDCCFrameRate() const;
|
||||
|
||||
virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData);
|
||||
virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData);
|
||||
virtual void ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* modelData, int modelIndex, ISkeletonData* skeletonData);
|
||||
virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData);
|
||||
virtual int GetAnimationCount() const;
|
||||
virtual std::string GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const;
|
||||
virtual void GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const;
|
||||
virtual void ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const;
|
||||
virtual IAnimationData* ReadAnimation(IExportContext* context, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const;
|
||||
|
||||
private:
|
||||
int animationIndex;
|
||||
IGeometryFileData* geometryFileData;
|
||||
int geometryFileIndex;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SINGLEANIMATIONEXPORTSOURCEADAPTER_H
|
||||
@@ -1,309 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SkeletonData.h"
|
||||
#include <cctype>
|
||||
|
||||
int SkeletonData::AddBone(const void* handle, const char* name, int parentIndex)
|
||||
{
|
||||
int modelIndex = int(m_bones.size());
|
||||
m_bones.push_back(BoneEntry(handle, name, parentIndex));
|
||||
m_nameBoneIndexMap.insert(std::make_pair(name, modelIndex));
|
||||
if (parentIndex >= 0)
|
||||
{
|
||||
m_bones[parentIndex].children.push_back(modelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_roots.push_back(modelIndex);
|
||||
}
|
||||
return modelIndex;
|
||||
}
|
||||
|
||||
int SkeletonData::FindBone(const char* name) const
|
||||
{
|
||||
std::map<std::string, int>::const_iterator modelPos = m_nameBoneIndexMap.find(name);
|
||||
return (modelPos != m_nameBoneIndexMap.end() ? (*modelPos).second : -1);
|
||||
}
|
||||
|
||||
const void* SkeletonData::GetBoneHandle(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].handle;
|
||||
}
|
||||
|
||||
int SkeletonData::GetBoneParentIndex(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].parentIndex;
|
||||
}
|
||||
|
||||
int SkeletonData::GetBoneCount() const
|
||||
{
|
||||
return int(m_bones.size());
|
||||
}
|
||||
|
||||
void SkeletonData::SetTranslation(int modelIndex, const float* vec)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_bones[modelIndex].translation[i] = vec[i];
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonData::SetRotation(int modelIndex, const float* vec)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_bones[modelIndex].rotation[i] = vec[i];
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonData::SetScale(int modelIndex, const float* vec)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_bones[modelIndex].scale[i] = vec[i];
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonData::SetParentFrameTranslation(int boneIndex, const float* vec)
|
||||
{
|
||||
EnsureParentFrameExists(boneIndex);
|
||||
std::copy(vec, vec + 3, m_bones[boneIndex].parentFrameTranslation);
|
||||
}
|
||||
|
||||
void SkeletonData::SetParentFrameRotation(int boneIndex, const float* vec)
|
||||
{
|
||||
EnsureParentFrameExists(boneIndex);
|
||||
std::copy(vec, vec + 3, m_bones[boneIndex].parentFrameRotation);
|
||||
}
|
||||
|
||||
void SkeletonData::SetParentFrameScale(int boneIndex, const float* vec)
|
||||
{
|
||||
EnsureParentFrameExists(boneIndex);
|
||||
std::copy(vec, vec + 3, m_bones[boneIndex].parentFrameScale);
|
||||
}
|
||||
|
||||
void SkeletonData::SetLimit(int boneIndex, Axis axis, Limit extreme, float limit)
|
||||
{
|
||||
m_bones[boneIndex].limits.insert(std::make_pair(AxisLimit(axis, extreme), limit));
|
||||
}
|
||||
|
||||
void SkeletonData::SetSpringTension(int boneIndex, Axis axis, float springTension)
|
||||
{
|
||||
m_bones[boneIndex].springTensions.insert(std::make_pair(axis, springTension));
|
||||
}
|
||||
|
||||
void SkeletonData::SetSpringAngle(int boneIndex, Axis axis, float springAngle)
|
||||
{
|
||||
m_bones[boneIndex].springAngles.insert(std::make_pair(axis, springAngle));
|
||||
}
|
||||
|
||||
void SkeletonData::SetAxisDamping(int boneIndex, Axis axis, float damping)
|
||||
{
|
||||
m_bones[boneIndex].dampings.insert(std::make_pair(axis, damping));
|
||||
}
|
||||
|
||||
void SkeletonData::SetPhysicalized(int boneIndex, bool physicalized)
|
||||
{
|
||||
m_bones[boneIndex].physicalized = physicalized;
|
||||
}
|
||||
|
||||
void SkeletonData::SetHasGeometry(int boneIndex, bool hasGeometry)
|
||||
{
|
||||
m_bones[boneIndex].hasGeometry = hasGeometry;
|
||||
}
|
||||
|
||||
void SkeletonData::SetBoneProperties(int boneIndex, const char* propertiesString)
|
||||
{
|
||||
m_bones[boneIndex].propertiesString = propertiesString;
|
||||
}
|
||||
|
||||
void SkeletonData::SetBoneGeomProperties(int boneIndex, const char* propertiesString)
|
||||
{
|
||||
m_bones[boneIndex].geomPropertiesString = propertiesString;
|
||||
}
|
||||
|
||||
bool SkeletonData::HasParentFrame(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].hasParentFrame;
|
||||
}
|
||||
|
||||
void SkeletonData::GetParentFrameTranslation(int boneIndex, float* vec) const
|
||||
{
|
||||
std::copy(m_bones[boneIndex].parentFrameTranslation, m_bones[boneIndex].parentFrameTranslation + 3, vec);
|
||||
}
|
||||
|
||||
void SkeletonData::GetParentFrameRotation(int boneIndex, float* vec) const
|
||||
{
|
||||
std::copy(m_bones[boneIndex].parentFrameRotation, m_bones[boneIndex].parentFrameRotation + 3, vec);
|
||||
}
|
||||
|
||||
void SkeletonData::GetParentFrameScale(int boneIndex, float* vec) const
|
||||
{
|
||||
std::copy(m_bones[boneIndex].parentFrameScale, m_bones[boneIndex].parentFrameScale + 3, vec);
|
||||
}
|
||||
|
||||
bool SkeletonData::HasLimit(int boneIndex, Axis axis, Limit extreme) const
|
||||
{
|
||||
return m_bones[boneIndex].limits.find(AxisLimit(axis, extreme)) != m_bones[boneIndex].limits.end();
|
||||
}
|
||||
|
||||
float SkeletonData::GetLimit(int boneIndex, Axis axis, Limit extreme) const
|
||||
{
|
||||
return (*m_bones[boneIndex].limits.find(AxisLimit(axis, extreme))).second;
|
||||
}
|
||||
|
||||
bool SkeletonData::HasSpringTension(int boneIndex, Axis axis) const
|
||||
{
|
||||
return m_bones[boneIndex].springTensions.find(axis) != m_bones[boneIndex].springTensions.end();
|
||||
}
|
||||
|
||||
float SkeletonData::GetSpringTension(int boneIndex, Axis axis) const
|
||||
{
|
||||
return (*m_bones[boneIndex].springTensions.find(axis)).second;
|
||||
}
|
||||
|
||||
bool SkeletonData::HasSpringAngle(int boneIndex, Axis axis) const
|
||||
{
|
||||
return m_bones[boneIndex].springAngles.find(axis) != m_bones[boneIndex].springAngles.end();
|
||||
}
|
||||
|
||||
float SkeletonData::GetSpringAngle(int boneIndex, Axis axis) const
|
||||
{
|
||||
return (*m_bones[boneIndex].springAngles.find(axis)).second;
|
||||
}
|
||||
|
||||
bool SkeletonData::HasAxisDamping(int boneIndex, Axis axis) const
|
||||
{
|
||||
return m_bones[boneIndex].dampings.find(axis) != m_bones[boneIndex].dampings.end();
|
||||
}
|
||||
|
||||
float SkeletonData::GetAxisDamping(int boneIndex, Axis axis) const
|
||||
{
|
||||
return (*m_bones[boneIndex].dampings.find(axis)).second;
|
||||
}
|
||||
|
||||
bool SkeletonData::GetPhysicalized(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].physicalized;
|
||||
}
|
||||
|
||||
bool SkeletonData::HasGeometry(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].hasGeometry;
|
||||
}
|
||||
|
||||
int SkeletonData::GetRootCount() const
|
||||
{
|
||||
return int(m_roots.size());
|
||||
}
|
||||
|
||||
int SkeletonData::GetRootIndex(int rootIndex) const
|
||||
{
|
||||
return m_roots[rootIndex];
|
||||
}
|
||||
|
||||
int SkeletonData::GetParentIndex(int modelIndex) const
|
||||
{
|
||||
return m_bones[modelIndex].parentIndex;
|
||||
}
|
||||
|
||||
const std::string SkeletonData::GetName(int modelIndex) const
|
||||
{
|
||||
std::string copy(m_bones[modelIndex].name);
|
||||
for (int i = 0, count = int(copy.size()); i < count; ++i)
|
||||
{
|
||||
if (!std::isalnum(copy[i]) && copy[i] != ' ')
|
||||
{
|
||||
copy[i] = '_';
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
const std::string SkeletonData::GetSafeName(int modelIndex) const
|
||||
{
|
||||
std::string name = GetName(modelIndex);
|
||||
std::replace_if(name.begin(), name.end(), std::isspace, '_');
|
||||
return name;
|
||||
}
|
||||
|
||||
int SkeletonData::GetChildCount(int modelIndex) const
|
||||
{
|
||||
return int(m_bones[modelIndex].children.size());
|
||||
}
|
||||
|
||||
int SkeletonData::GetChildIndex(int modelIndex, int childIndexIndex) const
|
||||
{
|
||||
return m_bones[modelIndex].children[childIndexIndex];
|
||||
}
|
||||
|
||||
void SkeletonData::GetTranslation(float* vec, int modelIndex) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
vec[i] = m_bones[modelIndex].translation[i];
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonData::GetRotation(float* vec, int modelIndex) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
vec[i] = m_bones[modelIndex].rotation[i];
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonData::GetScale(float* vec, int modelIndex) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
vec[i] = m_bones[modelIndex].scale[i];
|
||||
}
|
||||
}
|
||||
|
||||
const std::string SkeletonData::GetBoneProperties(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].propertiesString;
|
||||
}
|
||||
|
||||
const std::string SkeletonData::GetBoneGeomProperties(int boneIndex) const
|
||||
{
|
||||
return m_bones[boneIndex].geomPropertiesString;
|
||||
}
|
||||
|
||||
void SkeletonData::EnsureParentFrameExists(int boneIndex)
|
||||
{
|
||||
if (!m_bones[boneIndex].hasParentFrame)
|
||||
{
|
||||
std::fill(m_bones[boneIndex].parentFrameTranslation, m_bones[boneIndex].parentFrameTranslation + 3, 0.0f);
|
||||
std::fill(m_bones[boneIndex].parentFrameRotation, m_bones[boneIndex].parentFrameRotation + 3, 0.0f);
|
||||
std::fill(m_bones[boneIndex].parentFrameScale, m_bones[boneIndex].parentFrameScale + 3, 0.0f);
|
||||
m_bones[boneIndex].hasParentFrame = true;
|
||||
}
|
||||
}
|
||||
|
||||
SkeletonData::BoneEntry::BoneEntry(const void* handle, const std::string& name, int parentIndex)
|
||||
: handle(handle)
|
||||
, name(name)
|
||||
, parentIndex(parentIndex)
|
||||
, hasParentFrame(false)
|
||||
, physicalized(false)
|
||||
, hasGeometry(hasGeometry)
|
||||
{
|
||||
translation[0] = translation[1] = translation[2] = 0.0f;
|
||||
rotation[0] = rotation[1] = rotation[2] = 0.0f;
|
||||
scale[0] = scale[1] = scale[2] = 1.0f;
|
||||
}
|
||||
@@ -1,116 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKELETONDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKELETONDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ISkeletonData.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SkeletonData
|
||||
: public ISkeletonData
|
||||
{
|
||||
public:
|
||||
// ISkeletonData
|
||||
virtual int AddBone(const void* handle, const char* name, int parentIndex);
|
||||
virtual int FindBone(const char* name) const;
|
||||
virtual const void* GetBoneHandle(int boneIndex) const;
|
||||
virtual int GetBoneParentIndex(int boneIndex) const;
|
||||
virtual int GetBoneCount() const;
|
||||
virtual void SetTranslation(int boneIndex, const float* vec);
|
||||
virtual void SetRotation(int boneIndex, const float* vec);
|
||||
virtual void SetScale(int boneIndex, const float* vec);
|
||||
virtual void SetParentFrameTranslation(int boneIndex, const float* vec);
|
||||
virtual void SetParentFrameRotation(int boneIndex, const float* vec);
|
||||
virtual void SetParentFrameScale(int boneIndex, const float* vec);
|
||||
virtual void SetLimit(int boneIndex, Axis axis, Limit extreme, float limit);
|
||||
virtual void SetSpringTension(int boneIndex, Axis axis, float springTension);
|
||||
virtual void SetSpringAngle(int boneIndex, Axis axis, float springAngle);
|
||||
virtual void SetAxisDamping(int boneIndex, Axis axis, float damping);
|
||||
virtual void SetPhysicalized(int boneIndex, bool physicalized);
|
||||
virtual void SetHasGeometry(int boneIndex, bool hasGeometry);
|
||||
virtual void SetBoneProperties(int boneIndex, const char* propertiesString);
|
||||
virtual void SetBoneGeomProperties(int boneIndex, const char* propertiesString);
|
||||
|
||||
bool HasParentFrame(int boneIndex) const;
|
||||
void GetParentFrameTranslation(int boneIndex, float* vec) const;
|
||||
void GetParentFrameRotation(int boneIndex, float* vec) const;
|
||||
void GetParentFrameScale(int boneIndex, float* vec) const;
|
||||
bool HasLimit(int boneIndex, Axis axis, Limit extreme) const;
|
||||
float GetLimit(int boneIndex, Axis axis, Limit extreme) const;
|
||||
bool HasSpringTension(int boneIndex, Axis axis) const;
|
||||
float GetSpringTension(int boneIndex, Axis axis) const;
|
||||
bool HasSpringAngle(int boneIndex, Axis axis) const;
|
||||
float GetSpringAngle(int boneIndex, Axis axis) const;
|
||||
bool HasAxisDamping(int boneIndex, Axis axis) const;
|
||||
float GetAxisDamping(int boneIndex, Axis axis) const;
|
||||
bool GetPhysicalized(int boneIndex) const;
|
||||
bool HasGeometry(int boneIndex) const;
|
||||
|
||||
int GetRootCount() const;
|
||||
int GetRootIndex(int rootIndex) const;
|
||||
int GetParentIndex(int boneIndex) const;
|
||||
const std::string GetName(int boneIndex) const;
|
||||
const std::string GetSafeName(int boneIndex) const;
|
||||
int GetChildCount(int boneIndex) const;
|
||||
int GetChildIndex(int boneIndex, int childIndexIndex) const;
|
||||
void GetTranslation(float* vec, int boneIndex) const;
|
||||
void GetRotation(float* vec, int boneIndex) const;
|
||||
void GetScale(float* vec, int boneIndex) const;
|
||||
const std::string GetBoneProperties(int boneIndex) const;
|
||||
const std::string GetBoneGeomProperties(int boneIndex) const;
|
||||
|
||||
private:
|
||||
void EnsureParentFrameExists(int boneIndex);
|
||||
|
||||
typedef std::pair<Axis, Limit> AxisLimit;
|
||||
typedef std::map<AxisLimit, float> AxisLimitLimitMap;
|
||||
typedef std::map<Axis, float> AxisSpringTensionMap;
|
||||
typedef std::map<Axis, float> AxisSpringAngleMap;
|
||||
typedef std::map<Axis, float> AxisDampingMap;
|
||||
|
||||
struct BoneEntry
|
||||
{
|
||||
public:
|
||||
BoneEntry(const void* handle, const std::string& name, int parentIndex);
|
||||
const void* handle;
|
||||
std::string name;
|
||||
int parentIndex;
|
||||
AxisLimitLimitMap limits;
|
||||
AxisSpringTensionMap springTensions;
|
||||
AxisSpringAngleMap springAngles;
|
||||
AxisDampingMap dampings;
|
||||
bool hasParentFrame;
|
||||
float parentFrameTranslation[3];
|
||||
float parentFrameRotation[3];
|
||||
float parentFrameScale[3];
|
||||
bool physicalized;
|
||||
std::vector<int> children;
|
||||
float translation[3];
|
||||
float rotation[3];
|
||||
float scale[3];
|
||||
bool hasGeometry;
|
||||
std::string propertiesString;
|
||||
std::string geomPropertiesString;
|
||||
};
|
||||
|
||||
std::vector<BoneEntry> m_bones;
|
||||
std::vector<int> m_roots;
|
||||
std::map<std::string, int> m_nameBoneIndexMap;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKELETONDATA_H
|
||||
@@ -1,45 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SkinningData.h"
|
||||
|
||||
void SkinningData::SetVertexCount(int vertexCount)
|
||||
{
|
||||
m_weights.resize(vertexCount);
|
||||
}
|
||||
|
||||
void SkinningData::AddWeight(int vertexIndex, int boneIndex, float weight)
|
||||
{
|
||||
m_weights[vertexIndex].push_back(BoneWeight(boneIndex, weight));
|
||||
}
|
||||
|
||||
int SkinningData::GetVertexCount() const
|
||||
{
|
||||
return int(m_weights.size());
|
||||
}
|
||||
|
||||
int SkinningData::GetBoneLinkCount(int vertexIndex) const
|
||||
{
|
||||
return int(m_weights[vertexIndex].size());
|
||||
}
|
||||
|
||||
int SkinningData::GetBoneIndex(int vertexIndex, int linkIndex) const
|
||||
{
|
||||
return m_weights[vertexIndex][linkIndex].boneIndex;
|
||||
}
|
||||
|
||||
float SkinningData::GetWeight(int vertexIndex, int linkIndex) const
|
||||
{
|
||||
return m_weights[vertexIndex][linkIndex].weight;
|
||||
}
|
||||
@@ -1,46 +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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKINNINGDATA_H
|
||||
#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKINNINGDATA_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ISkinningData.h"
|
||||
|
||||
class SkinningData
|
||||
: public ISkinningData
|
||||
{
|
||||
public:
|
||||
virtual void SetVertexCount(int vertexCount);
|
||||
virtual void AddWeight(int vertexIndex, int boneIndex, float weight);
|
||||
|
||||
int GetVertexCount() const;
|
||||
int GetBoneLinkCount(int vertexIndex) const;
|
||||
int GetBoneIndex(int vertexIndex, int linkIndex) const;
|
||||
float GetWeight(int vertexIndex, int linkIndex) const;
|
||||
|
||||
private:
|
||||
struct BoneWeight
|
||||
{
|
||||
BoneWeight(int boneIndex, float weight)
|
||||
: boneIndex(boneIndex)
|
||||
, weight(weight) {}
|
||||
int boneIndex;
|
||||
float weight;
|
||||
};
|
||||
|
||||
std::vector<std::vector<BoneWeight> > m_weights;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKINNINGDATA_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user