Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
@@ -15,6 +15,7 @@
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Asset/AssetManagerComponent.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Jobs/Algorithms.h>
#include <AzCore/Jobs/JobManagerComponent.h>
#include <AzCore/Memory/MemoryComponent.h>
#include <AzCore/Module/DynamicModuleHandle.h>
@@ -38,7 +39,7 @@
#include <AzToolsFramework/Asset/AssetUtils.h>
#include <AzToolsFramework/AssetBundle/AssetBundleComponent.h>
#include <AzToolsFramework/AssetCatalog/PlatformAddressedAssetCatalogBus.h>
#include <AzCore/Jobs/Algorithms.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponent.h>
namespace AssetBundler
{
@@ -163,6 +164,7 @@ namespace AssetBundler
components.emplace_back(azrtti_typeid<AzToolsFramework::AssetBundleComponent>());
components.emplace_back(azrtti_typeid<AzToolsFramework::ArchiveComponent>());
components.emplace_back(azrtti_typeid<AzToolsFramework::Prefab::PrefabSystemComponent>());
for (auto iter = components.begin(); iter != components.end();)
{
@@ -2665,9 +2667,9 @@ namespace AssetBundler
AZ_Printf(AppWindowName, "\n");
AZ_Printf(AppWindowName, "Some args in this tool take paths as arguments, and there are two main types:\n");
AZ_Printf(AppWindowName, " \"path\" - This refers to an Engine-Root-Relative path.\n");
AZ_Printf(AppWindowName, " - Example: \"C:\\Lumberyard\\dev\\SamplesProject\\test.txt\" can be represented as \"SamplesProject\\test.txt\".\n");
AZ_Printf(AppWindowName, " - Example: \"C:\\Lumberyard\\dev\\AutomatedTesting\\test.txt\" can be represented as \"AutomatedTesting\\test.txt\".\n");
AZ_Printf(AppWindowName, " \"cache path\" - This refers to a Cache-Relative path.\n");
AZ_Printf(AppWindowName, " - Example: \"C:\\Lumberyard\\dev\\SamplesProject\\Cache\\pc\\animations\\skeletonlist.xml\" is represented as \"animations\\skeletonlist.xml\".\n");
AZ_Printf(AppWindowName, " - Example: \"C:\\Lumberyard\\dev\\AutomatedTesting\\Cache\\pc\\animations\\skeletonlist.xml\" is represented as \"animations\\skeletonlist.xml\".\n");
AZ_Printf(AppWindowName, "\n");
OutputHelpSeeds();
@@ -1302,7 +1302,8 @@ namespace AssetBuilderSDK
->Field("Patterns", &AssetBuilderDesc::m_patterns)
->Field("BusId", &AssetBuilderDesc::m_busId)
->Field("Version", &AssetBuilderDesc::m_version)
->Field("AnalysisFingerprint", &AssetBuilderDesc::m_analysisFingerprint);
->Field("AnalysisFingerprint", &AssetBuilderDesc::m_analysisFingerprint)
->Field("ProductsToKeepOnFailure", &AssetBuilderDesc::m_productsToKeepOnFailure);
serializeContext->RegisterGenericType<AZStd::vector<AssetBuilderDesc>>();
}
@@ -272,7 +272,7 @@ namespace AssetBuilderSDK
* If your analysis fingerprint DOES change, then all source files will be sent to your CreateJobs function regardless of modtime changes.
* This does not necessarily mean that the jobs will need doing, just that CreateJobs will be called.
* For best results, make sure your analysis fingerprint only changes when its likely that you need to re-analyze source files for changes, which
* may result in job fingerprints to be diffent (for example, if you have changed your logic inside your builder).
* may result in job fingerprints to be different (for example, if you have changed your logic inside your builder).
**/
AZStd::string m_analysisFingerprint;
@@ -282,6 +282,10 @@ namespace AssetBuilderSDK
AZStd::unordered_map<AZStd::string, AZ::u8> m_flagsByJobKey;
// If BF_DeleteLastKnownGoodProductOnFailure is raised, ALL specified product keys will be deleted on failure
// use this set to keep specific products in the job, if necessary
AZStd::unordered_map<AZStd::string, AZStd::unordered_set<AZ::u32>> m_productsToKeepOnFailure;
void AddFlags(AZ::u8 flag, const AZStd::string& jobKey);
bool HasFlag(AZ::u8 flag, const AZStd::string& jobKey) const;
@@ -151,7 +151,7 @@ namespace AssetBuilderSDK
bool GatherProductDependencies(
AZ::SerializeContext& serializeContext,
void* obj,
const void* obj,
AZ::TypeId typeId,
AZStd::vector<ProductDependency>& productDependencies,
ProductPathDependencySet& productPathDependencySet,
@@ -176,7 +176,7 @@ namespace AssetBuilderSDK
return enumerateResult;
}
bool OutputObject(void* obj, AZ::TypeId typeId, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext, const DependencyHandler& handler)
bool OutputObject(const void* obj, AZ::TypeId typeId, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext, const DependencyHandler& handler)
{
if (!serializeContext)
{
@@ -57,7 +57,7 @@ namespace AssetBuilderSDK
bool GatherProductDependencies(
AZ::SerializeContext& serializeContext,
void* obj,
const void* obj,
AZ::TypeId typeId,
AZStd::vector<ProductDependency>& productDependencies,
ProductPathDependencySet& productPathDependencySet,
@@ -66,7 +66,7 @@ namespace AssetBuilderSDK
template<class T>
bool GatherProductDependencies(
AZ::SerializeContext& serializeContext,
AZ::Data::Asset<T>* obj,
const AZ::Data::Asset<T>* obj,
AZ::TypeId typeId,
AZStd::vector<ProductDependency>& productDependencies,
ProductPathDependencySet& productPathDependencySet,
@@ -79,7 +79,7 @@ namespace AssetBuilderSDK
template<class T>
bool GatherProductDependencies(
AZ::SerializeContext& serializeContext,
T* obj,
const T* obj,
AZStd::vector<ProductDependency>& productDependencies,
ProductPathDependencySet& productPathDependencySet,
const DependencyHandler& handler = &UpdateDependenciesFromClassData)
@@ -87,18 +87,18 @@ namespace AssetBuilderSDK
return GatherProductDependencies(serializeContext, obj, azrtti_typeid<T>(), productDependencies, productPathDependencySet, handler);
}
bool OutputObject(void* obj, AZ::TypeId typeId, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext = nullptr,
bool OutputObject(const void* obj, AZ::TypeId typeId, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext = nullptr,
const DependencyHandler& handler = &UpdateDependenciesFromClassData);
template<class T>
bool OutputObject(T* obj, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext = nullptr,
bool OutputObject(const T* obj, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext = nullptr,
const DependencyHandler& handler = &UpdateDependenciesFromClassData)
{
return OutputObject(obj, azrtti_typeid<T>(), outputPath, assetType, subId, jobProduct, serializeContext, handler);
}
template<class T>
bool OutputObject(AZ::Data::Asset<T>* obj, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext = nullptr,
bool OutputObject(const AZ::Data::Asset<T>* obj, AZStd::string_view outputPath, AZ::Data::AssetType assetType, AZ::u32 subId, JobProduct& jobProduct, AZ::SerializeContext* serializeContext = nullptr,
const DependencyHandler& handler = &UpdateDependenciesFromClassData)
{
AZ_Error("AssetBuilderSDK", false, "Can't output dependencies for AZ::Data::Asset<T>* - Use T* or another underlying type");
@@ -464,8 +464,8 @@ namespace AssetProcessor
if (isExactDependency)
{
// Search for products in the cache platform folder
// Example: If a path dependency is "test1.asset" in SamplesProject on PC, this would search
// "SamplesProject/Cache/pc/test1.asset"
// Example: If a path dependency is "test1.asset" in AutomatedTesting on PC, this would search
// "AutomatedTesting/Cache/pc/test1.asset"
m_stateData->GetProductsByProductName(productNameWithPlatform, productInfoContainer);
}
@@ -725,6 +725,14 @@ namespace AssetProcessor
{
AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer products;
m_stateData->GetProductsByJobID(job.m_jobID, products);
auto keepProductsIter = description.m_productsToKeepOnFailure.find(jobEntry.m_jobKey.toUtf8().constData());
if (keepProductsIter != description.m_productsToKeepOnFailure.end())
{
// keep some products
AZStd::erase_if(products, [&](const auto& entry) { return !keepProductsIter->second.contains(entry.m_subID); });
}
DeleteProducts(products);
}
}
@@ -1569,7 +1577,7 @@ namespace AssetProcessor
// this might be interesting, but only if its a known product!
// the dictionary in statedata stores only the relative path, not the platform.
// which means right now we have, for example
// d:/SamplesProject/Cache/ios/textures/favorite.tga
// d:/AutomatedTesting/Cache/ios/textures/favorite.tga
// ^^^^^^^^^ projectroot
// ^^^^^^^^^^^^^^^^^^^^^ cache root
// ^^^^^^^^^^^^^^^^^^^^^^^^^ platform root
@@ -1701,7 +1709,19 @@ namespace AssetProcessor
AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Deleting file %s because either its source file %s was removed or the builder did not emit this job.\n", fullProductPath.toUtf8().constData(), source.m_sourceName.c_str());
AssetProcessor::ProcessingJobInfoBus::Broadcast(&AssetProcessor::ProcessingJobInfoBus::Events::BeginCacheFileUpdate, fullProductPath.toUtf8().data());
successfullyRemoved &= QFile::remove(fullProductPath);
bool wasRemoved = QFile::remove(fullProductPath);
// Another process may be holding on to the file currently, so wait for a very brief period and then retry deleting
// once in case we were just too quick to delete the file before.
if (!wasRemoved)
{
constexpr int DeleteRetryDelay = 10;
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(DeleteRetryDelay));
wasRemoved = QFile::remove(fullProductPath);
}
successfullyRemoved &= wasRemoved;
AssetProcessor::ProcessingJobInfoBus::Broadcast(&AssetProcessor::ProcessingJobInfoBus::Events::EndCacheFileUpdate, fullProductPath.toUtf8().data(), false);
if(productFileInfo.absoluteDir().entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).empty())
@@ -1805,10 +1825,9 @@ namespace AssetProcessor
{
if (!DeleteProducts(products))
{
// try again in a while. Achieve this by recycling the item back into
// the queue as if it had been deleted again.
CheckSource(FileEntry(normalizedPath, true));
AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Delete failed on %s. Will retry!. \n", normalizedPath.toUtf8().constData());
// DeleteProducts will make an attempt to retry deleting each product
// We can't just re-queue the whole file with CheckSource because we're deleting bits from the database as we go
AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Delete failed on %s.\n", normalizedPath.toUtf8().constData());
}
}
else
@@ -105,6 +105,16 @@ void AssetScannerWorker::ScanForSourceFiles(const ScanFolderInfo& scanFolderInfo
AZ::u64 fileSize = isDirectory ? 0 : entry.size();
AssetFileInfo assetFileInfo(absPath, modTime, fileSize, &rootScanFolder, isDirectory);
// Skip over the Cache folder if the file entry is the project cache root
QDir projectCacheRoot;
AssetUtilities::ComputeProjectCacheRoot(projectCacheRoot);
QString relativeToProjectCacheRoot = projectCacheRoot.relativeFilePath(absPath);
if (QDir::isRelativePath(relativeToProjectCacheRoot) && !relativeToProjectCacheRoot.startsWith(".."))
{
// The Cache folder should not be scanned
continue;
}
// Filtering out excluded files
if (m_platformConfiguration->IsFileExcluded(absPath))
{
@@ -136,7 +146,5 @@ void AssetScannerWorker::EmitFiles()
m_folderList.clear();
Q_EMIT ExcludedFound(m_excludedList);
m_excludedList.clear();
}
@@ -157,7 +157,7 @@ namespace AssetProcessor
{
AssetBuilderSDK::AssetBuilderDesc builderDesc;
builderDesc.m_name = "Settings Registry Builder";
builderDesc.m_patterns.emplace_back("*/bootstrap.cfg", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard);
builderDesc.m_patterns.emplace_back("*/engine.json", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard);
builderDesc.m_builderType = AssetBuilderSDK::AssetBuilderDesc::AssetBuilderType::Internal;
builderDesc.m_busId = m_builderId;
builderDesc.m_createJobFunction = AZStd::bind(&SettingsRegistryBuilder::CreateJobs, this, AZStd::placeholders::_1, AZStd::placeholders::_2);
@@ -195,7 +195,9 @@ namespace AssetProcessor
response.m_createJobOutputs.push_back(AZStd::move(job));
}
response.m_sourceFileDependencyList.emplace_back("*.setreg", AZ::Uuid::CreateNull(),
AZ::IO::Path settingsRegistryWildcard = AZ::SettingsRegistryInterface::RegistryFolder;
settingsRegistryWildcard /= "*.setreg";
response.m_sourceFileDependencyList.emplace_back(AZStd::move(settingsRegistryWildcard.Native()), AZ::Uuid::CreateNull(),
AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Wildcards);
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
}
@@ -294,10 +296,11 @@ namespace AssetProcessor
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, platform, specialization, &scratchBuffer);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, platform, specialization, &scratchBuffer);
// Merge the Developer User settings registry only in non-release builds
// Merge the Project User and User home settings registry only in non-release builds
if (!specialization.Contains("release"))
{
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_UserRegistry(registry, platform, specialization, &scratchBuffer);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, platform, specialization, &scratchBuffer);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, platform, specialization, &scratchBuffer);
}
AZ::ComponentApplicationBus::Broadcast([&registry](AZ::ComponentApplicationRequests* appRequests)
@@ -336,6 +339,7 @@ namespace AssetProcessor
file.Close();
response.m_outputProducts.emplace_back(outputPath, m_assetType, productSubID + aznumeric_cast<AZ::u32>(i));
response.m_outputProducts.back().m_dependenciesHandled = true;
outputPath.erase(extensionOffset);
}
@@ -120,7 +120,7 @@ namespace AssetProcessor
QString canonicalTempDirPath = AssetUtilities::NormalizeDirectoryPath(m_data->m_temporarySourceDir.canonicalPath());
m_data->m_temporarySourceDir = QDir(canonicalTempDirPath);
m_data->m_scopedDir.Setup(m_data->m_temporarySourceDir.path());
m_data->m_gameName = AssetUtilities::ComputeProjectName("SamplesProject"); // uses the above file.
m_data->m_gameName = AssetUtilities::ComputeProjectName("AutomatedTesting"); // uses the above file.
AssetUtilities::ResetAssetRoot();
QDir newRoot; // throwaway dummy var - we just want to invoke the below function
@@ -105,8 +105,8 @@ namespace AssetProcessorMessagesTests
m_batchApplicationManager = AZStd::make_unique<UnitTestBatchApplicationManager>(&argC, nullptr, nullptr);
m_batchApplicationManager->BeforeRun();
// Override Game Name to be "SamplesProject"
AssetUtilities::ComputeProjectName("SamplesProject", true);
// Override Game Name to be "AutomatedTesting"
AssetUtilities::ComputeProjectName("AutomatedTesting", true);
m_batchApplicationManager->m_platformConfiguration = new PlatformConfiguration();
m_batchApplicationManager->InitAssetProcessorManager();
@@ -150,7 +150,7 @@ namespace AssetProcessorMessagesTests
connectionSettings.m_assetProcessorIp = "127.0.0.1";
connectionSettings.m_assetProcessorPort = AssetProcessorPort;
connectionSettings.m_branchToken = appBranchToken;
connectionSettings.m_projectName = "SamplesProject";
connectionSettings.m_projectName = "AutomatedTesting";
connectionSettings.m_assetPlatform = "pc";
connectionSettings.m_connectionIdentifier = "UNITTEST";
connectionSettings.m_connectTimeout = AZStd::chrono::seconds(15);
@@ -227,7 +227,7 @@ void AssetProcessorManagerTest::SetUp()
SetArgReferee<0>(m_data->m_databaseLocation),
Return(true)));
m_gameName = AssetUtilities::ComputeProjectName("SamplesProject", true);
m_gameName = AssetUtilities::ComputeProjectName("AutomatedTesting", true);
AssetUtilities::ResetAssetRoot();
QDir newRoot;
@@ -1665,7 +1665,7 @@ TEST_F(PathDependencyTest, NoLongerProcessedFile_IsRemoved)
m_sharedConnection->GetProductsBySourceName("test1.txt", products);
ASSERT_EQ(products.size(), 0);
ASSERT_FALSE(QFile::exists(m_normalizedCacheRootDir.absoluteFilePath("pc/samplesproject/test1.asset1").toUtf8().constData()));
ASSERT_FALSE(QFile::exists(m_normalizedCacheRootDir.absoluteFilePath("pc/automatedtesting/test1.asset1").toUtf8().constData()));
}
TEST_F(PathDependencyTest, AssetProcessed_Impl_SelfReferrentialProductDependency_DependencyIsRemoved)
@@ -586,7 +586,7 @@ TEST_F(PlatformConfigurationUnitTests, Test_GemHandling)
QTemporaryDir tempEngineRoot;
QDir tempPath(tempEngineRoot.path());
AssetUtilities::ResetAssetRoot();
AssetUtilities::ComputeProjectName("SamplesProject", true);
AssetUtilities::ComputeProjectName("AutomatedTesting", true);
QDir computedEngineRoot;
ASSERT_TRUE(AssetUtilities::ComputeAssetRoot(computedEngineRoot, &tempPath));
@@ -666,7 +666,7 @@ TEST_F(PlatformConfigurationUnitTests, PlatformConfigFile_IsPresent_Found)
QTemporaryDir tempEngineRoot;
QDir tempPath(tempEngineRoot.path());
AssetUtilities::ResetAssetRoot();
AssetUtilities::ComputeProjectName("SamplesProject", true);
AssetUtilities::ComputeProjectName("AutomatedTesting", true);
auto settingsRegistry = AZ::SettingsRegistry::Get();
ASSERT_NE(nullptr, settingsRegistry);
@@ -70,7 +70,7 @@ namespace AssetProcessor
namespace
{
constexpr const char* AssetProcessorManagerTestGameProject = "SamplesProject";
constexpr const char* AssetProcessorManagerTestGameProject = "AutomatedTesting";
/// This functions sorts the processed result list by platform name
/// if platform is same than it sorts by job description
void sortAssetToProcessResultList(QList<JobDetails>& processResults)
@@ -669,6 +669,7 @@ void GUIApplicationManager::FileChanged(QString path)
AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get();
AZ_Assert(settingsRegistry, "Unable to retrieve global SettingsRegistry, it should be available now");
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*settingsRegistry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*settingsRegistry, *m_frameworkApp.GetAzCommandLine(), false);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*settingsRegistry);
}
@@ -1011,6 +1011,7 @@ namespace AssetProcessor
}
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
AZ::IO::FixedMaxPathString projectName = AZ::Utils::GetProjectName();
AZ::IO::FixedMaxPath engineRoot(AZ::IO::PosixPathSeparator);
settingsRegistry->Get(engineRoot.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
@@ -1061,6 +1062,7 @@ namespace AssetProcessor
AZ::StringFunc::Replace(scanFolderEntry.m_scanFolderDisplayName, "@ROOT@", assetRootPath.c_str());
AZ::StringFunc::Replace(scanFolderEntry.m_scanFolderDisplayName, "@PROJECTROOT@", projectPath.c_str());
AZ::StringFunc::Replace(scanFolderEntry.m_scanFolderDisplayName, "@PROJECTNAME@", projectName.c_str());
AZ::StringFunc::Replace(scanFolderEntry.m_scanFolderDisplayName, "@ENGINEROOT@", engineRoot.c_str());
QStringList includeIdentifiers;
@@ -97,7 +97,7 @@ namespace AssetUtilities
bool ShouldUseFileHashing();
//! Determine the name of the current project - for example, SamplesProject
//! Determine the name of the current project - for example, AutomatedTesting
//! Can be overridden by passing in a non-empty projectNameOverride
//! The override will persist if the project name wasn't set previously or
//! force=true is supplied
@@ -1,4 +1,5 @@
{
"project_name" : "AzTestRunner",
"product_name" : "AzTestRunner Project",
"android_settings": {
"package_name" : "com.lumberyard.tests",
+2 -5
View File
@@ -9,10 +9,6 @@
# 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})
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
@@ -72,9 +68,10 @@ ly_add_target(
Uploader/include/Uploader
BUILD_DEPENDENCIES
PRIVATE
3rdParty::Crashpad::Handler
AZ::AzCore
AZ::CrashSupport
PUBLIC
3rdParty::Crashpad::Handler
)
add_subdirectory(Tools)
@@ -9,6 +9,10 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
if(NOT PAL_TRAIT_BUILD_HOST_TOOLS)
return()
endif()
ly_add_target(
NAME ToolsCrashHandler STATIC
NAMESPACE AZ
@@ -125,7 +125,7 @@ bool CSummedAreaFilterKernel::CreateFromSincCalc(const unsigned long indwSize)
float r2 = r1 * 8.0f;
// http://home.no.net/dmaurer/~dersch/interpolator/interpolator.html
// weight = [ sin(x*) / (x*) ] * [ sin(x* / 8) / (x*/8) ]
// weight = [ sin(x*pi) / (x*pi) ] * [ sin(x*pi / 8) / (x*pi/8) ]
// http://www.binbooks.com/books/photo/i/l/57186AF8DE
// sinc(x) = sin(pi * x) / (pi * x)
@@ -17,7 +17,10 @@
#include "../offline/hash.h"
#if defined(_WIN32) && !defined(PORTABLE)
#include <AzCore/PlatformDef.h>
AZ_PUSH_DISABLE_WARNING(4115, "-Wunknown-warning-option")
#include <d3dcompiler.h>
AZ_POP_DISABLE_WARNING
#pragma comment(lib,"d3dcompiler.lib")
#endif //defined(_WIN32) && !defined(PORTABLE)
+1 -1
View File
@@ -1,4 +1,4 @@
/*
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
@@ -1,152 +0,0 @@
<RCJobs>
<!--
DefaultProperties can be overriden from command line
-->
<DefaultProperties
game="SamplesProject"
engine="Engine"
loc="LY_Localization"
src="."
trg="TempRC"
gems="Gems"
pak_root=".\Build"
vertex_index="u16"
streaming="auto"
/>
<Properties
image_types="*.tif;*.png;*.bmp;*.jpg;*.jpe;*.jpeg;*.tga;*.gif"
geometry_types="*.cgf;*.cga"
animation_types="*.i_caf"
xml_types="*.animevents;*.animsettings;*.adb;*.bspace;*.cdf;*.chrparams;*.comb;*.dlg;*.ent;*.fsq;*.fxl;*.ik;*.json;*.lmg;*.mtl;*.setup;*.xml;*.node;*.veg;*.prototype;*.uicanvas;*.uiprefab;*.prefab"
copy_types="${xml_types};*.txt;*.skel;*.skin;*.cfg;*.csv;*.dat;*.ini;*.xls;*.as;*.p;*.chr;*.caf;*.dba;*.ctc;*.lua;*.lut;*.bnk;*.wem;*.cal;*.grd;*.grp;*.ext;*.cfx;*.cfi;*.ttf;*.pak;*.abc;*.cbc;*.bin"
copynooverwrite_types="*.dds;*.dds.*;*.cga;*.cgf"
gems_excludes="*.h;*.c;*.cpp;*.lib;*.dll;*.inl;*.obj"
exclude_types="${gems_excludes};*.$*;*.exportsettings;*.psd;wwise_project*\*;*\ShaderCache\*"
levels_pak_types="Levels\*"
levels_pak_excludes="${exclude_types}"
game_data_pak_types="Config\*.*;Difficulty\*.*;Libs\*.*;Materials\*.*;Prefabs\*.*;Levels\*.*xml;Levels\*.*dds"
game_data_pak_excludes="${exclude_types};*filelist.*"
animation_pak_types="Animations\*.*"
animation_pak_excludes="${exclude_types}"
objects_pak_types="Objects\*.*"
objects_pak_excludes="${exclude_types};Objects\level_specific\*.*;Objects\multiplayer\*.*;Objects\weapons\*.*;Objects\characters\*.*;Objects\props\*.*"
objects_multiplayer_pak_types="Objects\multiplayer\*.*"
objects_multiplayer_pak_excludes="${exclude_types}"
weapons_pak_types="Objects\weapons\*.*"
weapons_pak_excludes="${exclude_types}"
character_pak_types="Objects\characters\*.*;Objects\props\*.*"
character_pak_excludes="${exclude_types}"
level_specific_pak_types="Objects\level_specific\*.*"
level_specific_pak_excludes="${exclude_types}"
textures_pak_types="Textures\*.*"
textures_pak_excludes="{exclude_types}"
sounds_pak_types="Sounds\*.*"
sounds_pak_excludes="${exclude_types}"
videos_pak_types="Videos\*.*"
videos_pak_excludes="${exclude_types}"
scripts_pak_types="Entities\*.*;Scripts\*.*"
scripts_pak_excludes="${exclude_types}"
shader_pak_types="Shaders\*.ext;Shaders\*.cfi;Shaders\*.cfx"
shader_pak_excludes="${exclude_types}"
engine_pak_types="Config\*.*;Fonts\*.*;EngineAssets\*.*;Libs\*.*;Material\*.*"
engine_pak_excludes="${exclude_types}"
gems_pak_types="*"
gems_pak_excludes="${exclude_types}"
src_game="${game}"
src_engine="${src}\${engine}"
src_gems="${src}\${gems}"
src_loc="${src}\${loc}"
trg_game="${trg}\${game}"
trg_engine="${trg}\${engine}"
trg_gems="${trg}\${gems}"
trg_loc="${trg}\${loc}"
pak_game="${pak_root}\${game}"
pak_engine="${pak_root}\${engine}"
vtx_idx="${vertex_index}"
streaming="0"
/>
<ConvertJob>
<!-- process source animation files into staging -->
<Job sourceroot="${src_game}" targetroot="${trg_game}" input="${animation_types}" animConfigFolder="Animations" cafAlignTracks="1" dbaStreamPrepare="1" />
<Job sourceroot="${src_engine}" targetroot="${trg_engine}" input="${animation_types}" animConfigFolder="Animations" cafAlignTracks="1" dbaStreamPrepare="1" />
<Job sourceroot="${src_gems}" targetroot="${trg_gems}" input="${animation_types}" animConfigFolder="Animations" cafAlignTracks="1" dbaStreamPrepare="1" />
<!-- process source geometry files into staging -->
<Job sourceroot="${src_game}" targetroot="${trg_game}" input="${geometry_types}" VertexPositionFormat="exporter" SplitLODs="1" vertexindexformat="${vtx_idx}" />
<Job sourceroot="${src_engine}" targetroot="${trg_engine}" input="${geometry_types}" VertexPositionFormat="exporter" SplitLODs="1" vertexindexformat="${vtx_idx}" />
<Job sourceroot="${src_gems}" targetroot="${trg_gems}" input="${geometry_types}" VertexPositionFormat="exporter" SplitLODs="1" vertexindexformat="${vtx_idx}" />
<!-- process source image files into staging -->
<Job sourceroot="${src_game}" targetroot="${trg_game}" input="${image_types}" imagecompressor="${imagecompressor}" streaming="${streaming}" />
<Job sourceroot="${src_engine}" targetroot="${trg_engine}" input="${image_types}" imagecompressor="${imagecompressor}" streaming="${streaming}" />
<Job sourceroot="${src_gems}" targetroot="${trg_gems}" input="${image_types}" imagecompressor="${imagecompressor}" streaming="${streaming}" />
</ConvertJob>
<CopyJob>
<Job sourceroot="${src_game}" targetroot="${trg_game}" input="${copynooverwrite_types}" copyonlynooverwrite="1" exclude="${exclude_types}" />
<Job sourceroot="${src_engine}" targetroot="${trg_engine}" input="${copynooverwrite_types}" copyonlynooverwrite="1" exclude="${exclude_types}" />
<Job sourceroot="${src_gems}" targetroot="${trg_gems}" input="${copynooverwrite_types}" copyonlynooverwrite="1" exclude="${exclude_types}" />
<Job sourceroot="${src_game}" targetroot="${trg_game}" input="${copy_types}" copyonly="1" exclude="${exclude_types}" />
<Job sourceroot="${src_engine}" targetroot="${trg_engine}" input="${copy_types}" copyonly="1" exclude="${exclude_types}" />
<Job sourceroot="${src_gems}" targetroot="${trg_gems}" input="${copy_types}" copyonly="1" exclude="${exclude_types}" />
</CopyJob>
<PakJob>
<Job sourceroot="${trg_game}" input="${levels_pak_types}" zip="${pak_game}\Levels.pak" exclude="${levels_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${game_data_pak_types}" zip="${pak_game}\GameData.pak" exclude="${game_data_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${animation_pak_types}" zip="${pak_game}\Animations.pak" exclude="${animation_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${objects_pak_types}" zip="${pak_game}\Objects.pak" exclude="${objects_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${objects_multiplayer_pak_types}" zip="${pak_game}\ObjectsMP.pak" exclude="${objects_multiplayer_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${weapons_pak_types}" zip="${pak_game}\Weapons.pak" exclude="${weapons_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${character_pak_types}" zip="${pak_game}\Characters.pak" exclude="${character_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${level_specific_pak_types}" zip="${pak_game}\LevelSpecific.pak" exclude="${level_specific_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${textures_pak_types}" zip="${pak_game}\Textures.pak" exclude="${textures_pak_excludes}" />
<Job sourceroot="${trg_game}" input="${sounds_pak_types}" zip="${pak_game}\Sounds.pak" exclude="${sounds_pak_excludes}" zip_compression="0" />
<Job sourceroot="${trg_game}" input="${videos_pak_types}" zip="${pak_game}\Videos.pak" exclude="${videos_pak_excludes}" zip_compression="0" />
<Job sourceroot="${trg_game}" input="${scripts_pak_types}" zip="${pak_game}\Scripts.pak" exclude="${scripts_pak_excludes}" />
<Job sourceroot="${trg_engine}" input="${shader_pak_types}" zip="${pak_engine}\Shaders.pak" exclude="${shader_pak_excludes}" />
<Job sourceroot="${trg_engine}" input="${engine_pak_types}" zip="${pak_engine}\Engine.pak" exclude="${engine_pak_excludes}" />
<Job sourceroot="${trg_gems}" input="${gems_pak_types}" zip="${pak_game}\${gems}.pak" exclude="${gems_pak_excludes}" />
</PakJob>
<CopyPakJob>
<Job sourceroot="${pak_game}" targetroot="${src_game}" input="*.pak" copyonly="1"/>
<Job sourceroot="${pak_engine}" targetroot="${src_game}" input="*.pak" copyonly="1"/>
</CopyPakJob>
<CleanJob>
<Job input="" targetroot="${trg}" clean_targetroot="1" />
</CleanJob>
<ValidateJob>
<Run Job="ConvertJob"/>
<Job input="" targetroot="${trg}" clean_targetroot="1" refs_scan="1" />
</ValidateJob>
<Run Job="ConvertJob"/>
<Run Job="CopyJob"/>
<Run Job="PakJob"/>
<Run Job="CopyPakJob"/>
<Run Job="CleanJob"/>
<Run Job="ValidateJob"/>
</RCJobs>
@@ -4,7 +4,7 @@
-->
<DefaultProperties
p="pc"
game="samplesproject"
game="automatedtesting"
src="cache\${game}\${p}"
trg="${game}_${p}_paks"
/>
@@ -5,7 +5,7 @@
-->
<DefaultProperties
p="pc"
game="samplesproject"
game="automatedtesting"
src="Cache\${game}\${p}"
trg="${game}_${p}_paks"
@@ -48,6 +48,7 @@
#include "CryLibrary.h"
#include <AzCore/Module/Environment.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/CommandLine/CommandLine.h>
@@ -2407,23 +2408,30 @@ void ResourceCompiler::ScanForAssetReferences(std::vector<string>& outReferences
}
}
std::vector<string> levelPaks;
FileUtil::ScanDirectory(scanRoot, "level.pak", levelPaks, true, string());
for (size_t i = 0; i < levelPaks.size(); ++i)
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (!usePrefabSystemForLevels)
{
const string path = PathHelpers::GetDirectory(levelPaks[i].c_str()) + "\\resourcelist.txt";
if (reader.LoadFromPak(GetPakSystem(), path, lines))
std::vector<string> levelPaks;
FileUtil::ScanDirectory(scanRoot, "level.pak", levelPaks, true, string());
for (size_t i = 0; i < levelPaks.size(); ++i)
{
for (size_t j = 0; j < lines.size(); ++j)
const string path = PathHelpers::GetDirectory(levelPaks[i].c_str()) + "\\resourcelist.txt";
if (reader.LoadFromPak(GetPakSystem(), path, lines))
{
const char* const line = lines[j];
if (references.find(line) == references.end())
for (size_t j = 0; j < lines.size(); ++j)
{
strings.push_back(line);
references.insert(strings.back().c_str());
const char* const line = lines[j];
if (references.find(line) == references.end())
{
strings.push_back(line);
references.insert(strings.back().c_str());
}
}
++numSources;
}
++numSources;
}
}
+5 -1
View File
@@ -558,10 +558,14 @@ int rcmain(int argc, char** argv, [[maybe_unused]] char** envp)
RCLog("Initializing System");
{
// Create a local SettingsRegistry to read the bootstrap.cfg settings if the appRoot hasn't been overriden
// Create a local SettingsRegistry to read the bootstrap.cfg settings if the engine root hasn't been overridden
// on the command line
AZ::CommandLine commandLine;
commandLine.Parse(argc, argv);
AZ::SettingsRegistryImpl settingsRegistry;
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(settingsRegistry, commandLine, false);
string projectPath = config.GetAsString("gameroot", "", "");
if (!projectPath.empty())
@@ -1074,7 +1074,7 @@ bool CStatCGFCompiler::CompileCGF(AssetBuilderSDK::ProcessJobResponse& response,
// Check if our material name is just a name, or if it contains a path
if (strstr(materialName.c_str(), "/") || strstr(materialName.c_str(), "\\"))
{
// The material path is already relative to devroot, for example "samplesproject/materials/foo.mtl"
// The material path is already relative to devroot, for example "automatedtesting/materials/foo.mtl"
// We need to convert this to the cache path AP generates. In this case, cut off the game project name.
AZStd::string materialRelativePath = materialName;
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePath, gameFolder);
@@ -212,7 +212,7 @@ TEST_F(CGFBuilderTest, CGF_MaterialInSameFolder)
}
// In this case, we load a basic CGF where the material path is absolute from the dev/ folder,
// for example "samplesproject/materials/test.mtl".
// for example "automatedtesting/materials/test.mtl".
TEST_F(CGFBuilderTest, CGF_MaterialInDifferentFolder)
{
AZStd::string cgfName = "gs_block.cgf";
@@ -1,48 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <RC/ResourceCompilerScene/Chr/ChrExportContexts.h>
namespace AZ
{
namespace RC
{
ChrGroupExportContext::ChrGroupExportContext(SceneAPI::Events::ExportEventContext& parent,
const SceneAPI::DataTypes::ISkeletonGroup& group, Phase phase)
: m_products(parent.GetProductList())
, m_scene(parent.GetScene())
, m_outputDirectory(parent.GetOutputDirectory())
, m_group(group)
, m_phase(phase)
{
}
ChrGroupExportContext::ChrGroupExportContext(SceneAPI::Events::ExportProductList& products, const SceneAPI::Containers::Scene& scene,
const AZStd::string& outputDirectory, const SceneAPI::DataTypes::ISkeletonGroup& group, Phase phase)
: m_products(products)
, m_scene(scene)
, m_outputDirectory(outputDirectory)
, m_group(group)
, m_phase(phase)
{
}
ChrGroupExportContext::ChrGroupExportContext(const ChrGroupExportContext& copyContext, Phase phase)
: m_products(copyContext.m_products)
, m_scene(copyContext.m_scene)
, m_outputDirectory(copyContext.m_outputDirectory)
, m_group(copyContext.m_group)
, m_phase(phase)
{
}
}
}
@@ -1,59 +0,0 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/RTTI/RTTI.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
#include <RC/ResourceCompilerScene/Common/ExportContextGlobal.h>
namespace AZ
{
namespace SceneAPI
{
namespace DataTypes
{
class ISkeletonGroup;
}
namespace Events
{
class ExportProductList;
}
}
namespace RC
{
// Called to export a specific Skeleton (Chr) Group
struct ChrGroupExportContext
: public SceneAPI::Events::ICallContext
{
AZ_RTTI(ChrGroupExportContext, "{294BB98B-DE9D-4B03-B219-A8A94657E81E}", SceneAPI::Events::ICallContext);
ChrGroupExportContext(SceneAPI::Events::ExportEventContext& parent,
const SceneAPI::DataTypes::ISkeletonGroup& group, Phase phase);
ChrGroupExportContext(SceneAPI::Events::ExportProductList& products, const SceneAPI::Containers::Scene& scene,
const AZStd::string& outputDirectory, const SceneAPI::DataTypes::ISkeletonGroup& group, Phase phase);
ChrGroupExportContext(const ChrGroupExportContext& copyContent, Phase phase);
ChrGroupExportContext(const ChrGroupExportContext& copyContent) = delete;
~ChrGroupExportContext() override = default;
ChrGroupExportContext& operator=(const ChrGroupExportContext& other) = delete;
SceneAPI::Events::ExportProductList& m_products;
const SceneAPI::Containers::Scene& m_scene;
const AZStd::string& m_outputDirectory;
const SceneAPI::DataTypes::ISkeletonGroup& m_group;
const Phase m_phase;
};
}
}
@@ -1,58 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <RC/ResourceCompilerScene/Chr/ChrExporter.h>
#include <Cry_Geo.h>
#include <ConvertContext.h>
#include <CGFContent.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/SceneManifest.h>
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISkeletonGroup.h>
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
#include <RC/ResourceCompilerScene/Chr/ChrExportContexts.h>
namespace AZ
{
namespace RC
{
namespace SceneContainers = AZ::SceneAPI::Containers;
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
ChrExporter::ChrExporter(IConvertContext* convertContext)
: m_convertContext(convertContext)
{
BindToCall(&ChrExporter::ProcessContext);
ActivateBindings();
}
SceneEvents::ProcessingResult ChrExporter::ProcessContext(SceneEvents::ExportEventContext& context)
{
const SceneContainers::SceneManifest& manifest = context.GetScene().GetManifest();
auto valueStorage = manifest.GetValueStorage();
auto view = SceneContainers::MakeDerivedFilterView<SceneDataTypes::ISkeletonGroup>(valueStorage);
SceneEvents::ProcessingResultCombiner result;
for (const SceneDataTypes::ISkeletonGroup& skeletonGroup : view)
{
AZ_TraceContext("Skeleton Group", skeletonGroup.GetName());
result += SceneEvents::Process<ChrGroupExportContext>(context, skeletonGroup, Phase::Construction);
result += SceneEvents::Process<ChrGroupExportContext>(context, skeletonGroup, Phase::Filling);
result += SceneEvents::Process<ChrGroupExportContext>(context, skeletonGroup, Phase::Finalizing);
}
return result.GetResult();
}
} // namespace RC
} // namespace AZ
@@ -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.
*
*/
#pragma once
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.h>
struct IConvertContext;
namespace AZ
{
namespace SceneAPI
{
namespace Events
{
class ExportEventContext;
}
}
namespace RC
{
namespace SceneEvents = AZ::SceneAPI::Events;
class ChrExporter
: public SceneEvents::CallProcessorBinder
{
public:
ChrExporter(IConvertContext* convertContext);
~ChrExporter() override = default;
SceneEvents::ProcessingResult ProcessContext(SceneEvents::ExportEventContext& context);
private:
IConvertContext* m_convertContext;
};
} // namespace RC
} // namespace AZ
@@ -1,131 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Cry_Geo.h> // Needed for CGFContent.h
#include <CGFContent.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
#include <RC/ResourceCompilerScene/Chr/ChrExportContexts.h>
#include <RC/ResourceCompilerScene/Chr/ChrGroupExporter.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISkeletonGroup.h>
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
#include <SceneAPI/SceneCore/Utilities/FileUtilities.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace RC
{
namespace SceneUtil = AZ::SceneAPI::Utilities;
namespace SceneContainer = AZ::SceneAPI::Containers;
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
const AZStd::string ChrGroupExporter::fileExtension = "chr";
ChrGroupExporter::ChrGroupExporter(IAssetWriter* writer, IConvertContext* convertContext)
: m_assetWriter(writer)
, m_convertContext(convertContext)
{
BindToCall(&ChrGroupExporter::ProcessContext);
ActivateBindings();
}
SceneEvents::ProcessingResult ChrGroupExporter::ProcessContext(ChrGroupExportContext& context) const
{
if (context.m_phase != Phase::Filling)
{
return SceneEvents::ProcessingResult::Ignored;
}
AZStd::string filename = SceneUtil::FileUtilities::CreateOutputFileName(context.m_group.GetName(), context.m_outputDirectory, fileExtension);
if (filename.empty())
{
AZ_TracePrintf(SceneUtil::ErrorWindow, "Invalid filename, can not be an empty value.\n");
return SceneEvents::ProcessingResult::Failure;
}
if (!SceneUtil::FileUtilities::EnsureTargetFolderExists(filename))
{
AZ_TracePrintf(SceneUtil::ErrorWindow, "Invalid filename, target folder does not exist. ('%s')\n", filename.c_str());
return SceneEvents::ProcessingResult::Failure;
}
SceneEvents::ProcessingResultCombiner result;
CContentCGF cgfContent(filename.c_str());
AZStd::unordered_map<AZStd::string, int> boneNameIdMap;
SkeletonExportContext skeletonContextConstruction(context.m_scene, context.m_group.GetSelectedRootBone(), *cgfContent.GetSkinningInfo(), boneNameIdMap, Phase::Construction);
ConfigureChrContent(cgfContent);
result += SceneEvents::Process(skeletonContextConstruction);
result += SceneEvents::Process<SkeletonExportContext>(context.m_scene, context.m_group.GetSelectedRootBone(), *cgfContent.GetSkinningInfo(), boneNameIdMap, Phase::Filling);
result += SceneEvents::Process<SkeletonExportContext>(context.m_scene, context.m_group.GetSelectedRootBone(), *cgfContent.GetSkinningInfo(), boneNameIdMap, Phase::Finalizing);
AZ_Assert(m_assetWriter != nullptr, "Unable to write CHR due to invalid asset writer.");
if (m_assetWriter)
{
if (m_assetWriter->WriteCHR(&cgfContent, m_convertContext))
{
static const AZ::Data::AssetType skeletonAssetType("{60161B46-21F0-4396-A4F0-F2CCF0664CDE}");
auto& list = context.m_products.GetProducts();
bool isFirst = AZStd::find_if(list.begin(), list.end(),
[](const SceneAPI::Events::ExportProduct& it) -> bool
{
return it.m_assetType == skeletonAssetType;
}) == list.end();
SceneAPI::Events::ExportProduct& product = context.m_products.AddProduct(AZStd::move(filename), context.m_group.GetId(), skeletonAssetType,
AZStd::nullopt, AZStd::nullopt);
// Previously only a single skeleton would be exported that was named after the source file. This was changed to exporting all
// skeletons now named after the root node. This means that the first skeleton would previously have been known under
// another name.
if (isFirst)
{
AZStd::string legacyName = product.m_filename;
AzFramework::StringFunc::Path::ReplaceFullName(legacyName, context.m_scene.GetName().c_str(), fileExtension.c_str());
product.m_legacyFileNames.emplace_back(AZStd::move(legacyName));
}
}
else
{
AZ_TracePrintf(SceneUtil::ErrorWindow, "Failed writing CHR file ('%s')\n", filename.c_str());
result += SceneEvents::ProcessingResult::Failure;
}
}
else
{
AZ_TracePrintf(SceneUtil::ErrorWindow, "Failed writing CHR file ('%s')\n", filename.c_str());
result += SceneEvents::ProcessingResult::Failure;
}
return result.GetResult();
}
void ChrGroupExporter::ConfigureChrContent(CContentCGF& content) const
{
CExportInfoCGF* exportInfo = content.GetExportInfo();
AZ_Assert(exportInfo != nullptr, "Invalid export info from %s.", content.GetFilename());
exportInfo->bMergeAllNodes = true;
exportInfo->bUseCustomNormals = false;
exportInfo->bCompiledCGF = false;
exportInfo->bHavePhysicsProxy = false;
exportInfo->bHaveAutoLods = false;
exportInfo->bNoMesh = true;
exportInfo->b8WeightsPerVertex = false;
exportInfo->bWantF32Vertices = false;
exportInfo->authorToolVersion = 1;
}
} // namespace RC
} // namespace AZ
@@ -1,47 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/string/string.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.h>
struct IConvertContext;
class CContentCGF;
namespace AZ
{
namespace RC
{
struct ChrGroupExportContext;
namespace SceneEvents = AZ::SceneAPI::Events;
class ChrGroupExporter
: public SceneEvents::CallProcessorBinder
{
public:
ChrGroupExporter(IAssetWriter* writer, IConvertContext* convertContext);
~ChrGroupExporter() override = default;
SceneEvents::ProcessingResult ProcessContext(ChrGroupExportContext& context) const;
static const AZStd::string fileExtension;
protected:
void ConfigureChrContent(CContentCGF& content) const;
IAssetWriter* m_assetWriter;
IConvertContext* m_convertContext;
};
} // namespace RC
} // namespace AZ
@@ -1,48 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <RC/ResourceCompilerScene/Skin/SkinExportContexts.h>
namespace AZ
{
namespace RC
{
SkinGroupExportContext::SkinGroupExportContext(SceneAPI::Events::ExportEventContext& parent,
const SceneAPI::DataTypes::ISkinGroup& group, Phase phase)
: m_products(parent.GetProductList())
, m_scene(parent.GetScene())
, m_outputDirectory(parent.GetOutputDirectory())
, m_group(group)
, m_phase(phase)
{
}
SkinGroupExportContext::SkinGroupExportContext(SceneAPI::Events::ExportProductList& products, const SceneAPI::Containers::Scene& scene,
const AZStd::string& outputDirectory, const SceneAPI::DataTypes::ISkinGroup& group, Phase phase)
: m_products(products)
, m_scene(scene)
, m_outputDirectory(outputDirectory)
, m_group(group)
, m_phase(phase)
{
}
SkinGroupExportContext::SkinGroupExportContext(const SkinGroupExportContext& copyContext, Phase phase)
: m_products(copyContext.m_products)
, m_scene(copyContext.m_scene)
, m_outputDirectory(copyContext.m_outputDirectory)
, m_group(copyContext.m_group)
, m_phase(phase)
{
}
}
}
@@ -1,57 +0,0 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/RTTI/RTTI.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
#include <RC/ResourceCompilerScene/Common/ExportContextGlobal.h>
struct CSkinningInfo;
namespace AZ
{
namespace SceneAPI
{
namespace DataTypes
{
class ISkinGroup;
}
}
namespace RC
{
// Called to export a specific Skin Group
struct SkinGroupExportContext
: public SceneAPI::Events::ICallContext
{
AZ_RTTI(SkinGroupExportContext, "{F2C0DF6D-84F7-4692-9626-C981FA599755}", SceneAPI::Events::ICallContext);
SkinGroupExportContext(SceneAPI::Events::ExportEventContext& parent,
const SceneAPI::DataTypes::ISkinGroup& group, Phase phase);
SkinGroupExportContext(SceneAPI::Events::ExportProductList& products, const SceneAPI::Containers::Scene& scene,
const AZStd::string& outputDirectory, const SceneAPI::DataTypes::ISkinGroup& group, Phase phase);
SkinGroupExportContext(const SkinGroupExportContext& copyContent, Phase phase);
SkinGroupExportContext(const SkinGroupExportContext& copyContent) = delete;
~SkinGroupExportContext() override = default;
SkinGroupExportContext& operator=(const SkinGroupExportContext& other) = delete;
SceneAPI::Events::ExportProductList& m_products;
const SceneAPI::Containers::Scene& m_scene;
const AZStd::string& m_outputDirectory;
const SceneAPI::DataTypes::ISkinGroup& m_group;
const Phase m_phase;
};
}
}
@@ -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.
*
*/
#include <RC/ResourceCompilerScene/Skin/SkinExporter.h>
#include <Cry_Geo.h>
#include <ConvertContext.h>
#include <CGFContent.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/SceneManifest.h>
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISkinGroup.h>
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
#include <RC/ResourceCompilerScene/Skin/SkinExportContexts.h>
namespace AZ
{
namespace RC
{
namespace SceneContainers = AZ::SceneAPI::Containers;
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
SkinExporter::SkinExporter(IConvertContext* convertContext)
: m_convertContext(convertContext)
{
BindToCall(&SkinExporter::ProcessContext);
ActivateBindings();
}
SceneEvents::ProcessingResult SkinExporter::ProcessContext(SceneEvents::ExportEventContext& context)
{
const SceneContainers::SceneManifest& manifest = context.GetScene().GetManifest();
auto valueStorage = manifest.GetValueStorage();
auto view = SceneContainers::MakeDerivedFilterView<SceneDataTypes::ISkinGroup>(valueStorage);
SceneEvents::ProcessingResultCombiner result;
for (const SceneDataTypes::ISkinGroup& skinGroup : view)
{
AZ_TraceContext("Skin Group", skinGroup.GetName());
result += SceneEvents::Process<SkinGroupExportContext>(context, skinGroup, Phase::Construction);
result += SceneEvents::Process<SkinGroupExportContext>(context, skinGroup, Phase::Filling);
result += SceneEvents::Process<SkinGroupExportContext>(context, skinGroup, Phase::Finalizing);
}
return result.GetResult();
}
} // namespace RC
} // namespace AZ
@@ -1,49 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.h>
namespace AZ
{
namespace SceneAPI
{
namespace Events
{
class ExportEventContext;
}
}
}
struct IConvertContext;
namespace AZ
{
namespace RC
{
namespace SceneEvents = AZ::SceneAPI::Events;
class SkinExporter
: public SceneEvents::CallProcessorBinder
{
public:
SkinExporter(IConvertContext* convertContext);
~SkinExporter() override = default;
SceneEvents::ProcessingResult ProcessContext(SceneEvents::ExportEventContext& context);
private:
IConvertContext* m_convertContext;
};
} // namespace RC
} // namespace AZ
@@ -1,93 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Cry_Geo.h> // Needed for CGFContent.h
#include <CGFContent.h>
#include <AzCore/std/containers/map.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
#include <RC/ResourceCompilerScene/Skin/SkinExportContexts.h>
#include <RC/ResourceCompilerScene/Skin/SkinGroupExporter.h>
#include <RC/ResourceCompilerScene/Skin/SkinUtils.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/SceneGraphSelector.h>
#include <SceneAPI/SceneCore/DataTypes/ManifestBase/ISceneNodeSelectionList.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISkinGroup.h>
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
#include <SceneAPI/SceneCore/Utilities/FileUtilities.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace RC
{
namespace SceneUtil = AZ::SceneAPI::Utilities;
namespace SceneContainer = AZ::SceneAPI::Containers;
const AZStd::string SkinGroupExporter::s_fileExtension = "skin";
SkinGroupExporter::SkinGroupExporter(IAssetWriter* writer, IConvertContext* convertContext)
: m_assetWriter(writer)
, m_convertContext(convertContext)
{
BindToCall(&SkinGroupExporter::ProcessContext);
ActivateBindings();
}
SceneEvents::ProcessingResult SkinGroupExporter::ProcessContext(SkinGroupExportContext& context) const
{
if (context.m_phase != Phase::Filling)
{
return SceneEvents::ProcessingResult::Ignored;
}
AZStd::string filename = SceneUtil::FileUtilities::CreateOutputFileName(context.m_group.GetName(), context.m_outputDirectory, s_fileExtension);
AZ_TraceContext("Skin filename", filename);
if (filename.empty() || !SceneUtil::FileUtilities::EnsureTargetFolderExists(filename))
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Invalid file name for skin");
return SceneEvents::ProcessingResult::Failure;
}
SceneEvents::ProcessingResultCombiner result;
CContentCGF cgfContent(filename.c_str());
ConfigureSkinContent(cgfContent);
// Process mesh
// For each selected mesh, find its skinned skeleton's root bone. Make sure the root bone is consistent through all selected skin meshes.
const SceneContainer::SceneGraph& graph = context.m_scene.GetGraph();
AZStd::vector<AZStd::string> targetNodes = SceneUtil::SceneGraphSelector::GenerateTargetNodes(graph,
context.m_group.GetSceneNodeSelectionList(), SceneUtil::SceneGraphSelector::IsMesh);
result += ProcessSkins(context, cgfContent, targetNodes);
if (m_assetWriter)
{
if (m_assetWriter->WriteSKIN(&cgfContent, m_convertContext, true))
{
static const AZ::Data::AssetType skinnedMeshAssetType("{C5D443E1-41FF-4263-8654-9438BC888CB7}"); // from MeshAsset.h
context.m_products.AddProduct(AZStd::move(filename), context.m_group.GetId(), skinnedMeshAssetType, 0, AZStd::nullopt);
}
else
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Writing Skin has failed.");
result += SceneEvents::ProcessingResult::Failure;
}
}
else
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "No asset writer found. Unable to write skin to disk");
result += SceneEvents::ProcessingResult::Failure;
}
return result.GetResult();
}
} // namespace RC
} // namespace AZ
@@ -1,44 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/string/string.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.h>
struct IConvertContext;
namespace AZ
{
namespace RC
{
struct SkinGroupExportContext;
namespace SceneEvents = AZ::SceneAPI::Events;
class SkinGroupExporter
: public SceneEvents::CallProcessorBinder
{
public:
SkinGroupExporter(IAssetWriter* writer, IConvertContext* convertContext);
~SkinGroupExporter() override = default;
SceneEvents::ProcessingResult ProcessContext(SkinGroupExportContext& context) const;
static const AZStd::string s_fileExtension;
protected:
IAssetWriter* m_assetWriter;
IConvertContext* m_convertContext;
};
} // namespace RC
} // namespace AZ
@@ -1,117 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Cry_Geo.h> // Needed for CGFContent.h
#include <CGFContent.h>
#include <AzCore/std/containers/map.h>
#include <AzCore/std/string/conversions.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
#include <RC/ResourceCompilerScene/Cgf/CgfUtils.h>
#include <RC/ResourceCompilerScene/Skin/SkinExportContexts.h>
#include <RC/ResourceCompilerScene/Skin/SkinLodExporter.h>
#include <RC/ResourceCompilerScene/Skin/SkinUtils.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/SceneGraphSelector.h>
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
#include <SceneAPI/SceneCore/DataTypes/ManifestBase/ISceneNodeSelectionList.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISkinGroup.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/ILodRule.h>
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
#include <SceneAPI/SceneCore/Utilities/FileUtilities.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace RC
{
namespace SceneUtil = AZ::SceneAPI::Utilities;
namespace SceneContainer = AZ::SceneAPI::Containers;
namespace SceneDataTypes = AZ::SceneAPI::DataTypes;
const AZStd::string SkinLodExporter::s_fileExtension = "skin";
SkinLodExporter::SkinLodExporter(IAssetWriter* writer, IConvertContext* convertContext)
: m_assetWriter(writer)
, m_convertContext(convertContext)
{
BindToCall(&SkinLodExporter::ProcessContext);
ActivateBindings();
}
SceneEvents::ProcessingResult SkinLodExporter::ProcessContext(SkinGroupExportContext& context) const
{
if (context.m_phase != Phase::Filling)
{
return SceneEvents::ProcessingResult::Ignored;
}
AZStd::shared_ptr<const SceneDataTypes::ILodRule> lodRule = context.m_group.GetRuleContainerConst().FindFirstByType<SceneDataTypes::ILodRule>();
if (!lodRule)
{
return SceneEvents::ProcessingResult::Ignored;
}
SceneEvents::ProcessingResultCombiner result;
for (size_t index = 0; index < lodRule->GetLodCount(); ++index)
{
AZ_TraceContext("Skin lod level", static_cast<uint64_t>(index));
AZStd::string filename = SceneUtil::FileUtilities::CreateOutputFileName(
context.m_group.GetName() + "_LOD" + AZStd::to_string(static_cast<int>(index + 1)), context.m_outputDirectory, s_fileExtension);
AZ_TraceContext("Skin lod filename", filename);
if (filename.empty() || !SceneUtil::FileUtilities::EnsureTargetFolderExists(filename))
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Invalid file name for skin");
result += SceneEvents::ProcessingResult::Failure;
break;
}
CContentCGF cgfContent(filename.c_str());
ConfigureSkinContent(cgfContent);
// Process mesh
// For each selected mesh, find its skinned skeleton's root bone. Make sure the root bone is consistent through all selected skin meshes.
const SceneContainer::SceneGraph& graph = context.m_scene.GetGraph();
AZStd::vector<AZStd::string> targetNodes = SceneUtil::SceneGraphSelector::GenerateTargetNodes(graph,
lodRule->GetSceneNodeSelectionList(index), SceneUtil::SceneGraphSelector::IsMesh);
result += ProcessSkins(context, cgfContent, targetNodes);
if (m_assetWriter)
{
if (m_assetWriter->WriteSKIN(&cgfContent, m_convertContext, false))
{
static const AZ::Data::AssetType skinnedMeshLodsAssetType("{58E5824F-C27B-46FD-AD48-865BA41B7A51}");
// Using the same guid as the parent group/cgf as this needs to be a lod of that cgf.
// Setting the lod to index+1 as 0 means the base mesh and 1-6 are lod levels 0-5.
context.m_products.AddProduct(AZStd::move(filename), context.m_group.GetId(), skinnedMeshLodsAssetType, index + 1, AZStd::nullopt);
}
else
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Writing Skin has failed.");
result += SceneEvents::ProcessingResult::Failure;
break;
}
}
else
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "No asset writer found. Unable to write skin to disk");
result += SceneEvents::ProcessingResult::Failure;
break;
}
}
return result.GetResult();
}
} // namespace RC
} // namespace AZ
@@ -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.
*
*/
#pragma once
#include <AzCore/std/string/string.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.h>
struct IConvertContext;
class CContentCGF;
namespace AZ
{
namespace RC
{
struct SkinGroupExportContext;
namespace SceneEvents = AZ::SceneAPI::Events;
class SkinLodExporter
: public SceneEvents::CallProcessorBinder
{
public:
SkinLodExporter(IAssetWriter* writer, IConvertContext* convertContext);
~SkinLodExporter() override = default;
SceneEvents::ProcessingResult ProcessContext(SkinGroupExportContext& context) const;
static const AZStd::string s_fileExtension;
protected:
IAssetWriter* m_assetWriter;
IConvertContext* m_convertContext;
};
} // namespace RC
} // namespace AZ
@@ -1,194 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Cry_Geo.h> // Needed for CGFContent.h
#include <CGFContent.h>
#include <AzCore/std/containers/map.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <RC/ResourceCompilerScene/Common/CommonExportContexts.h>
#include <RC/ResourceCompilerScene/Skin/SkinExportContexts.h>
#include <RC/ResourceCompilerScene/Skin/SkinGroupExporter.h>
#include <RC/ResourceCompilerScene/Cgf/CgfUtils.h>
#include <RC/ResourceCompilerScene/Skin/SkinUtils.h>
#include <RC/ResourceCompilerScene/Skin/SkinExportContexts.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISkinGroup.h>
#include <SceneAPI/SceneCore/Utilities/FileUtilities.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace RC
{
void ConfigureSkinContent(CContentCGF& content)
{
CExportInfoCGF* exportInfo = content.GetExportInfo();
exportInfo->bMergeAllNodes = true;
exportInfo->bUseCustomNormals = false;
exportInfo->bCompiledCGF = false;
exportInfo->bHavePhysicsProxy = false;
exportInfo->bHaveAutoLods = false;
exportInfo->bNoMesh = true;
exportInfo->b8WeightsPerVertex = false;
exportInfo->bWantF32Vertices = false;
exportInfo->authorToolVersion = 1;
}
void MergeToFirstNodeMesh(CContentCGF& content)
{
AZ_Assert(content.GetNodeCount() > 0, "Skin Mesh has no node to merge");
if (content.GetNodeCount() == 0)
{
return;
}
CMesh* mergedMesh = content.GetNode(0)->pMesh;
AZ_Assert(mergedMesh, "Failed to retrieve merged mesh for content root node");
if (!mergedMesh)
{
return;
}
for (size_t nodeIndex = 0; nodeIndex < content.GetNodeCount(); ++nodeIndex)
{
CNodeCGF* node = content.GetNode(nodeIndex);
AZ_Assert(node, "Failed to retrieve node at index %i", nodeIndex);
if (!node)
{
continue;
}
if (!node->bIdentityMatrix)
{
AZ_Assert(node->pMesh, "No mesh node set on CGF node at index %i", nodeIndex);
if (!node->pMesh)
{
continue;
}
for (size_t vertexIndex = 0; vertexIndex < node->pMesh->GetVertexCount(); ++vertexIndex)
{
node->pMesh->m_pPositions[vertexIndex] = node->worldTM.TransformPoint(node->pMesh->m_pPositions[vertexIndex]);
node->pMesh->m_pNorms[vertexIndex].RotateSafelyBy(node->worldTM);
}
}
if (nodeIndex > 0)
{
mergedMesh->Append(*node->pMesh);
// Keep color stream in sync size with vertex/normals stream. Reference to CGFNodeMerger::MergeNodes
if (mergedMesh->m_streamSize[CMesh::COLORS][0] > 0 && mergedMesh->m_streamSize[CMesh::COLORS][0] < mergedMesh->GetVertexCount())
{
int colorCount = mergedMesh->m_streamSize[CMesh::COLORS][0];
mergedMesh->ReallocStream(CMesh::COLORS, 0, mergedMesh->GetVertexCount());
memset(mergedMesh->m_pColor0 + colorCount, 255, (mergedMesh->GetVertexCount() - colorCount) * sizeof(SMeshColor));
}
}
}
// We already used the transform during merge, so clear it out
content.GetNode(0)->worldTM.SetIdentity();
}
void RemoveRedundantNodes(CContentCGF& content)
{
while (content.GetNodeCount() > 1)
{
CNodeCGF* deleteNode = content.GetNode(content.GetNodeCount() - 1);
content.RemoveNode(deleteNode);
}
}
SceneAPI::Events::ProcessingResult ProcessSkins(SkinGroupExportContext& context, CContentCGF& content, AZStd::vector<AZStd::string>& targetNodes)
{
namespace SceneEvents = SceneAPI::Events;
if (targetNodes.empty())
{
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "No nodes selected for mesh exporting.");
return SceneEvents::ProcessingResult::Ignored;
}
SceneEvents::ProcessingResultCombiner result;
ContainerExportContext containerContext(context.m_scene, context.m_outputDirectory, context.m_group, content, Phase::Construction);
result += SceneEvents::Process(containerContext);
result += SceneEvents::Process<ContainerExportContext>(containerContext, Phase::Filling);
const EPhysicsGeomType physicalizeType = PHYS_GEOM_TYPE_NONE;
AZStd::string rootBoneName;
const SceneAPI::Containers::SceneGraph& graph = context.m_scene.GetGraph();
AZStd::string currentRootBoneName;
for (const AZStd::string& nodeName : targetNodes)
{
AZ_TraceContext("Skin mesh", nodeName);
SceneAPI::Containers::SceneGraph::NodeIndex index = graph.Find(nodeName.c_str());
if (index.IsValid())
{
// Pick the target skeleton from the first node, then make sure all the remaining meshes are referencing the same skeleton
// as the skins need to merged to a single mesh at the end.
SceneEvents::ProcessingResult rootNameResult = SceneEvents::Process<ResolveRootBoneFromNodeContext>(currentRootBoneName, context.m_scene, index);
if (rootNameResult != SceneEvents::ProcessingResult::Success || currentRootBoneName.empty())
{
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Selected skin has no weight data.");
continue;
}
if (rootBoneName.empty())
{
rootBoneName = currentRootBoneName;
// The skeleton has been established so fill up the skinning information for it as there's still
// a strong link between skin and skeleton.
SceneEvents::ProcessingResult skinInfoResult = SceneEvents::Process<AddBonesToSkinningInfoContext>(
*content.GetSkinningInfo(), context.m_scene, rootBoneName);
if (skinInfoResult != SceneEvents::ProcessingResult::Success)
{
// Without the skinning info further processing will cause a crash so early out here.
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Unable to link bones to skin.");
return SceneEvents::ProcessingResult::Failure;
}
}
else if (rootBoneName != currentRootBoneName)
{
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Skin doesn't belong to the same skeleton as the rest of the meshes in the group.");
continue;
}
CNodeCGF* node = new CNodeCGF(); // will be auto deleted by CContentCGF cgf
SetNodeName(nodeName, *node);
result += SceneAPI::Events::Process<NodeExportContext>(containerContext, *node, nodeName, index, physicalizeType, rootBoneName, Phase::Construction);
result += SceneAPI::Events::Process<NodeExportContext>(containerContext, *node, nodeName, index, physicalizeType, rootBoneName, Phase::Filling);
content.AddNode(node);
result += SceneAPI::Events::Process<NodeExportContext>(containerContext, *node, nodeName, index, physicalizeType, rootBoneName, Phase::Finalizing);
currentRootBoneName.clear();
}
}
if (content.GetNodeCount() > 0)
{
// CharacterCompiler expects all skin sub-meshes to be merged and stored in a single CNodeCGF
MergeToFirstNodeMesh(content);
result += SceneAPI::Events::Process<ContainerExportContext>(containerContext, Phase::Finalizing);
RemoveRedundantNodes(content);
}
else
{
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "No valid skin information found that could be added to this container.");
result += SceneAPI::Events::Process<ContainerExportContext>(containerContext, Phase::Finalizing);
}
return result.GetResult();
}
}
}
@@ -1,31 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/string/string.h>
#include <SceneAPI/SceneCore/Events/ProcessingResult.h>
class CContentCGF;
struct CNodeCGF;
namespace AZ
{
namespace RC
{
struct SkinGroupExportContext;
void ConfigureSkinContent(CContentCGF& content);
void MergeToFirstNodeMesh(CContentCGF& content);
void RemoveRedundantNodes(CContentCGF& content);
AZ::SceneAPI::Events::ProcessingResult ProcessSkins(SkinGroupExportContext& context, CContentCGF& content, AZStd::vector<AZStd::string>& targetNodes);
} // namespace RC
} // namespace AZ
@@ -52,20 +52,4 @@ set(FILES
Cgf/CgfExporter.cpp
Cgf/CgfUtils.h
Cgf/CgfUtils.cpp
Chr/ChrExportContexts.h
Chr/ChrExportContexts.cpp
Chr/ChrGroupExporter.h
Chr/ChrGroupExporter.cpp
Chr/ChrExporter.h
Chr/ChrExporter.cpp
Skin/SkinExportContexts.h
Skin/SkinExportContexts.cpp
Skin/SkinGroupExporter.h
Skin/SkinGroupExporter.cpp
Skin/SkinLodExporter.h
Skin/SkinLodExporter.cpp
Skin/SkinExporter.h
Skin/SkinExporter.cpp
Skin/SkinUtils.h
Skin/SkinUtils.cpp
)
@@ -13,6 +13,7 @@
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzToolsFramework/Debug/TraceContext.h>
@@ -38,8 +39,10 @@ namespace AZ
namespace FbxSceneBuilder
{
const char* AssImpAnimationImporter::s_animationNodeName = "animation";
const FbxSDKWrapper::FbxTimeWrapper::TimeMode AssImpAnimationImporter::s_defaultTimeMode =
FbxSDKWrapper::FbxTimeWrapper::frames30;
// Downstream only supports 30 frames per second sample rate. Adjusting to 60 doubles the
// length of the animations, they still play back at 30 frames per second.
const double AssImpAnimationImporter::s_defaultTimeStepSampleRate = 1.0 / 30.0;
AssImpAnimationImporter::AssImpAnimationImporter()
{
@@ -51,7 +54,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(2); // [LYN-2281] Skinned mesh loading fixes
}
}
@@ -115,13 +118,13 @@ namespace AZ
}
// These variables are named using AssImp naming convention for consistency
unsigned int mNumPositionKeys{};
AZ::u32 mNumPositionKeys{};
aiVectorKey* mPositionKeys{};
unsigned int mNumRotationKeys{};
AZ::u32 mNumRotationKeys{};
aiQuatKey* mRotationKeys{};
unsigned int mNumScalingKeys{};
AZ::u32 mNumScalingKeys{};
aiVectorKey* mScalingKeys{};
AZStd::vector<aiVectorKey> m_ownedPositionKeys{};
@@ -156,7 +159,6 @@ namespace AZ
return AZStd::make_pair(animation, anim);
}
Events::ProcessingResult AssImpAnimationImporter::ImportAnimation(AssImpSceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Animation");
@@ -181,11 +183,11 @@ namespace AZ
// all the animations for a given node
// In the case of bone animations, the data is copied into a ConsolidatedNodeAnim so we can
// do fix-ups later without affecting the original data
auto mapAnimationsFunc = [](unsigned numChannels, auto** channels, const aiAnimation* animation, auto& map)
auto mapAnimationsFunc = [](AZ::u32 numChannels, auto** channels, const aiAnimation* animation, auto& map)
{
map.reserve(numChannels);
for (unsigned channelIndex = 0; channelIndex < numChannels; ++channelIndex)
for (AZ::u32 channelIndex = 0; channelIndex < numChannels; ++channelIndex)
{
auto* nodeAnim = channels[channelIndex];
AZStd::string name = GetName(nodeAnim);
@@ -194,13 +196,13 @@ namespace AZ
}
};
for (unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
for (AZ::u32 animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
{
const aiAnimation* animation = scene->mAnimations[animIndex];
mapAnimationsFunc(animation->mNumChannels, animation->mChannels, animation, boneAnimations);
for (unsigned channelIndex = 0; channelIndex < animation->mNumMorphMeshChannels; ++channelIndex)
for (AZ::u32 channelIndex = 0; channelIndex < animation->mNumMorphMeshChannels; ++channelIndex)
{
auto* nodeAnim = animation->mMorphMeshChannels[channelIndex];
AZStd::string name = GetName(nodeAnim);
@@ -280,7 +282,7 @@ namespace AZ
}
Events::ProcessingResultCombiner combinedAnimationResult;
for (unsigned meshIndex = 0; meshIndex < currentNode->mNumMeshes; ++meshIndex)
for (AZ::u32 meshIndex = 0; meshIndex < currentNode->mNumMeshes; ++meshIndex)
{
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[meshIndex]];
@@ -321,7 +323,7 @@ namespace AZ
DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform);
context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform);
context.m_sourceSceneSystem.ConvertUnit(localTransform);
for (unsigned time = 0; time <= animation->mDuration; ++time)
for (AZ::u32 time = 0; time <= animation->mDuration; ++time)
{
createdAnimationData->AddKeyFrame(localTransform);
}
@@ -408,15 +410,8 @@ namespace AZ
anim->mNumPositionKeys, anim->mNumRotationKeys, anim->mNumScalingKeys);
return Events::ProcessingResult::Failure;
}
unsigned numAnimationKeys = anim->mNumPositionKeys;
if (numAnimationKeys <= 1)
{
numAnimationKeys = AZStd::GetMax(anim->mNumRotationKeys, anim->mNumScalingKeys);
}
auto sampleKeyFrame = [](const auto& keys, unsigned numKeys, double time)
auto sampleKeyFrame = [](const auto& keys, AZ::u32 numKeys, double time, AZ::u32& lastIndex)
{
AZ_Error("AnimationImporter", numKeys > 0, "Animation key set must have at least 1 key");
@@ -427,9 +422,10 @@ namespace AZ
auto returnValue = keys[0].mValue;
for (unsigned keyIndex = 0; keyIndex < numKeys; ++keyIndex)
for (AZ::u32 keyIndex = lastIndex; keyIndex < numKeys; ++keyIndex)
{
const auto& key = keys[keyIndex];
lastIndex = keyIndex;
// We want to return the key that exactly matches the time if possible, otherwise we'll keep track of the previous time
// If we don't find an exact match and end up going past the desired time (or run out of keyframes) then we return the previous key
@@ -437,7 +433,7 @@ namespace AZ
{
returnValue = key.mValue;
}
else if (key.mTime == time)
else if (AZ::IsClose(key.mTime, time))
{
return key.mValue;
}
@@ -450,16 +446,34 @@ namespace AZ
return returnValue;
};
// Resample the animations at a fixed time step. This matches the behaviour of
// the previous SDK used. Longer term, this could be data driven, or based on the
// smallest time step between key frames.
// AssImp has an animation->mTicksPerSecond and animation->mDuration, but those
// are less predictable than just using a fixed time step.
const double duration = animation->mDuration / animation->mTicksPerSecond;
AZ::u32 numKeyFrames = AZStd::max(AZStd::max(anim->mNumScalingKeys, anim->mNumPositionKeys), anim->mNumRotationKeys);
if (!AZ::IsClose(duration / s_defaultTimeStepSampleRate, numKeyFrames, 1))
{
double dT = duration / s_defaultTimeStepSampleRate;
numKeyFrames = AZStd::ceilf(dT) + 1; // +1 because the animation is from [0, duration] - we have a keyframe at the end of the duration which needs to be included
}
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
AZStd::make_shared<SceneData::GraphData::AnimationData>();
createdAnimationData->ReserveKeyFrames(animation->mDuration + 1); // +1 because we start at 0 and the last keyframe is at mDuration instead of mDuration-1
createdAnimationData->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
for (unsigned time = 0; time <= animation->mDuration; ++time)
createdAnimationData->ReserveKeyFrames(numKeyFrames);
createdAnimationData->SetTimeStepBetweenFrames(s_defaultTimeStepSampleRate);
AZ::u32 lastScaleIndex = 0;
AZ::u32 lastPositionIndex = 0;
AZ::u32 lastRotationIndex = 0;
for (AZ::u32 frame = 0; frame < numKeyFrames; ++frame)
{
auto scale = sampleKeyFrame(anim->mScalingKeys, anim->mNumScalingKeys, time);
auto position = sampleKeyFrame(anim->mPositionKeys, anim->mNumPositionKeys, time);
auto rotation = sampleKeyFrame(anim->mRotationKeys, anim->mNumRotationKeys, time);
double time = frame * s_defaultTimeStepSampleRate * animation->mTicksPerSecond;
aiVector3D scale = sampleKeyFrame(anim->mScalingKeys, anim->mNumScalingKeys, time, lastScaleIndex);
aiVector3D position = sampleKeyFrame(anim->mPositionKeys, anim->mNumPositionKeys, time, lastPositionIndex);
aiQuaternion rotation = sampleKeyFrame(anim->mRotationKeys, anim->mNumRotationKeys, time, lastRotationIndex);
aiMatrix4x4 transform(scale, rotation, position);
@@ -555,9 +569,9 @@ namespace AZ
aiAnimMesh* aiAnimMesh = mesh->mAnimMeshes[meshIdx];
AZStd::string_view nodeName(aiAnimMesh->mName.C_Str());
const unsigned maxKeys = keys.size();
unsigned keyIdx = 0;
for (unsigned time = 0; time <= animation->mDuration; ++time)
const AZ::u32 maxKeys = keys.size();
AZ::u32 keyIdx = 0;
for (AZ::u32 time = 0; time <= animation->mDuration; ++time)
{
if (keyIdx < maxKeys - 1 && time >= keys[keyIdx+1].m_time)
{
@@ -45,9 +45,10 @@ namespace AZ
const aiMeshMorphAnim* meshMorphAnim,
const aiMesh* mesh);
static const double s_defaultTimeStepSampleRate;
protected:
static const char* s_animationNodeName;
static const FbxSDKWrapper::FbxTimeWrapper::TimeMode s_defaultTimeMode;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
@@ -15,6 +15,7 @@
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBitangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
@@ -42,7 +43,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpBitangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpBitangentStreamImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
}
}
@@ -56,15 +57,13 @@ namespace AZ
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
if (!meshDataResult.IsSuccess())
{
AZ_Error(Utilities::ErrorWindow, false,
"Tried to construct bitangent stream attribute for invalid or non-mesh parent data");
return Events::ProcessingResult::Failure;
return meshDataResult.GetError();
}
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
size_t vertexCount = parentMeshData->GetVertexCount();
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
@@ -15,6 +15,7 @@
#include <AzCore/std/string/conversions.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBlendShapeImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
@@ -43,7 +44,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpBlendShapeImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpBlendShapeImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2576
}
}
@@ -68,13 +69,24 @@ namespace AZ
return Events::ProcessingResult::Ignored;
}
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
if (!meshDataResult.IsSuccess())
{
return meshDataResult.GetError();
}
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
int parentMeshIndex = parentMeshData->GetSdkMeshIndex();
Events::ProcessingResultCombiner combinedBlendShapeResult;
for (int meshIdx = 0; meshIdx < numMesh; meshIdx++)
for (int nodeMeshIdx = 0; nodeMeshIdx < numMesh; nodeMeshIdx++)
{
int meshId = context.m_sourceNode.GetAssImpNode()->mMeshes[meshIdx];
aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[meshId];
if (!aiMesh->mNumAnimMeshes)
int sceneMeshIdx = context.m_sourceNode.GetAssImpNode()->mMeshes[nodeMeshIdx];
const aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[sceneMeshIdx];
// Each mesh gets its own node in the scene graph, so only generate
// morph targets for the current mesh.
if (parentMeshIndex != nodeMeshIdx || !aiMesh->mNumAnimMeshes)
{
continue;
}
@@ -96,9 +108,22 @@ namespace AZ
int firstMeshVertexIndex = -1;
int previousMeshVertexIndex = -1;
int verticesInMeshFace = 0;
AZStd::bitset<SceneData::GraphData::BlendShapeData::MaxNumUVSets> uvSetUsedFlags;
for (AZ::u8 uvSetIndex = 0; uvSetIndex < SceneData::GraphData::BlendShapeData::MaxNumUVSets; ++uvSetIndex)
{
uvSetUsedFlags.set(uvSetIndex, aiAnimMesh->HasTextureCoords(uvSetIndex));
}
AZStd::bitset<SceneData::GraphData::BlendShapeData::MaxNumColorSets> colorSetUsedFlags;
for (AZ::u8 colorSetIndex = 0; colorSetIndex < SceneData::GraphData::BlendShapeData::MaxNumColorSets;
++colorSetIndex)
{
colorSetUsedFlags.set(colorSetIndex, aiAnimMesh->HasVertexColors(colorSetIndex));
}
blendShapeData->ReserveData(
aiAnimMesh->mNumVertices, aiAnimMesh->HasTangentsAndBitangents(), uvSetUsedFlags, colorSetUsedFlags);
for (int vertIdx = 0; vertIdx < aiAnimMesh->mNumVertices; ++vertIdx)
{
AZ::Vector3 vertex(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mVertices[vertIdx]));
@@ -106,7 +131,7 @@ namespace AZ
context.m_sourceSceneSystem.SwapVec3ForUpAxis(vertex);
context.m_sourceSceneSystem.ConvertUnit(vertex);
// Add normals
AZ::Vector3 normal;
if (aiAnimMesh->HasNormals())
{
@@ -116,6 +141,39 @@ namespace AZ
}
blendShapeData->AddVertex(vertex, normal);
blendShapeData->SetVertexIndexToControlPointIndexMap(vertIdx, vertIdx);
// Add tangents and bitangents
if (aiAnimMesh->HasTangentsAndBitangents())
{
// Vector4's constructor that takes in a vector3 sets w to 1.0f automatically.
const AZ::Vector4 tangent(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mTangents[vertIdx]));
const AZ::Vector3 bitangent = AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mBitangents[vertIdx]);
blendShapeData->AddTangentAndBitangent(tangent, bitangent);
}
// Add UVs
for (AZ::u8 uvSetIdx = 0; uvSetIdx < SceneData::GraphData::BlendShapeData::MaxNumUVSets; ++uvSetIdx)
{
if (aiAnimMesh->HasTextureCoords(uvSetIdx))
{
const AZ::Vector2 vertexUV(
aiAnimMesh->mTextureCoords[uvSetIdx][vertIdx].x,
// The engine's V coordinate is reverse of how it's stored in assImp.
1.0f - aiAnimMesh->mTextureCoords[uvSetIdx][vertIdx].y);
blendShapeData->AddUV(vertexUV, uvSetIdx);
}
}
// Add colors
for (AZ::u8 colorSetIdx = 0; colorSetIdx < SceneData::GraphData::BlendShapeData::MaxNumColorSets; ++colorSetIdx)
{
if (aiAnimMesh->HasVertexColors(colorSetIdx))
{
SceneAPI::DataTypes::Color color =
AssImpSDKWrapper::AssImpTypeConverter::ToColor(aiAnimMesh->mColors[colorSetIdx][vertIdx]);
blendShapeData->AddColor(color, colorSetIdx);
}
}
}
// aiAnimMesh just has a list of positions for vertices. The face indices are on the original mesh.
@@ -15,6 +15,7 @@
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpColorStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
@@ -42,7 +43,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpColorStreamImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpColorStreamImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
}
}
@@ -56,15 +57,13 @@ namespace AZ
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
if (!meshDataResult.IsSuccess())
{
AZ_Error(Utilities::ErrorWindow, false,
"Tried to construct color stream attribute for invalid or non-mesh parent data");
return Events::ProcessingResult::Failure;
return meshDataResult.GetError();
}
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
size_t vertexCount = parentMeshData->GetVertexCount();
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
@@ -18,6 +18,7 @@
#include <AzCore/StringFunc/StringFunc.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
@@ -16,8 +16,10 @@
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinWeightsImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinWeightData.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
@@ -41,7 +43,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2576
}
}
@@ -57,11 +59,29 @@ namespace AZ
return Events::ProcessingResult::Ignored;
}
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
if (!meshDataResult.IsSuccess())
{
return meshDataResult.GetError();
}
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
int parentMeshIndex = parentMeshData->GetSdkMeshIndex();
Events::ProcessingResultCombiner combinedSkinWeightsResult;
for(unsigned m = 0; m < currentNode->mNumMeshes; ++m)
for(unsigned nodeMeshIndex = 0; nodeMeshIndex < currentNode->mNumMeshes; ++nodeMeshIndex)
{
auto mesh = scene->mMeshes[currentNode->mMeshes[m]];
if (nodeMeshIndex != parentMeshIndex)
{
// Only generate skinning data for the parent mesh.
// Each AssImp mesh is assigned to a unique node,
// so the skinning data should be generated as a child node
// for the associated parent mesh.
continue;
}
int sceneMeshIndex = currentNode->mMeshes[nodeMeshIndex];
const aiMesh* mesh = scene->mMeshes[sceneMeshIndex];
// Don't create this until a bone with weights is encountered
Containers::SceneGraph::NodeIndex weightsIndexForMesh;
@@ -80,7 +100,7 @@ namespace AZ
if (!weightsIndexForMesh.IsValid())
{
skinWeightName = s_skinWeightName;
skinWeightName += AZStd::to_string(m);
skinWeightName += AZStd::to_string(nodeMeshIndex);
RenamedNodesMap::SanitizeNodeName(skinWeightName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
weightsIndexForMesh =
@@ -15,6 +15,7 @@
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
@@ -42,7 +43,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpTangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpTangentStreamImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
}
}
@@ -56,15 +57,13 @@ namespace AZ
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
if (!meshDataResult.IsSuccess())
{
AZ_Error(Utilities::ErrorWindow, false,
"Tried to construct tangent stream attribute for invalid or non-mesh parent data");
return Events::ProcessingResult::Failure;
return meshDataResult.GetError();
}
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
size_t vertexCount = parentMeshData->GetVertexCount();
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
@@ -17,6 +17,7 @@
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpUvMapImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
@@ -43,7 +44,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
}
}
@@ -57,16 +58,14 @@ namespace AZ
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
if (!meshDataResult.IsSuccess())
{
AZ_Error(Utilities::ErrorWindow, false,
"Tried to construct uv stream attribute for invalid or non-mesh parent data");
return Events::ProcessingResult::Failure;
return meshDataResult.GetError();
}
const SceneData::GraphData::MeshData* const parentMeshData =
azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
int parentMeshIndex = parentMeshData->GetSdkMeshIndex();
size_t vertexCount = parentMeshData->GetVertexCount();
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
@@ -15,9 +15,11 @@
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
#include <SceneAPI/SceneData/GraphData/BoneData.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
namespace AZ::SceneAPI::FbxSceneBuilder
@@ -95,4 +97,34 @@ namespace AZ::SceneAPI::FbxSceneBuilder
return true;
}
GetMeshDataFromParentResult GetMeshDataFromParent(AssImpSceneNodeAppendedContext& context)
{
const DataTypes::IGraphObject* const parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition).get();
if (!parentData)
{
AZ_Error(Utilities::ErrorWindow, false,
"GetMeshDataFromParent failed because the parent was null, it should only be called with a valid parent node");
return AZ::Failure(Events::ProcessingResult::Failure);
}
if (!parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
{
// The parent node may contain bone information and not mesh information, skip it.
if (parentData->RTTI_IsTypeOf(SceneData::GraphData::BoneData::TYPEINFO_Uuid()))
{
// Return the ignore processing result in the failure.
return AZ::Failure(Events::ProcessingResult::Ignored);
}
AZ_Error(Utilities::ErrorWindow, false,
"Tried to get mesh data from parent for non-mesh parent data");
return AZ::Failure(Events::ProcessingResult::Failure);
}
const SceneData::GraphData::MeshData* const parentMeshData =
azrtti_cast<const SceneData::GraphData::MeshData* const>(parentData);
return AZ::Success(parentMeshData);
}
}
@@ -12,6 +12,8 @@
#pragma once
#include <SceneAPI/SceneCore/Events/ProcessingResult.h>
struct aiNode;
struct aiScene;
@@ -37,12 +39,16 @@ namespace AZ
{
class IGraphObject;
}
struct AssImpSceneNodeAppendedContext;
class FbxSceneSystem;
namespace FbxSceneBuilder
{
bool BuildSceneMeshFromAssImpMesh(aiNode* currentNode, const aiScene* scene, const FbxSceneSystem& sceneSystem, AZStd::vector<AZStd::shared_ptr<DataTypes::IGraphObject>>& meshes,
const AZStd::function<AZStd::shared_ptr<SceneData::GraphData::MeshData>()>& makeMeshFunc);
typedef AZ::Outcome<const SceneData::GraphData::MeshData* const, Events::ProcessingResult> GetMeshDataFromParentResult;
GetMeshDataFromParentResult GetMeshDataFromParent(AssImpSceneNodeAppendedContext& context);
}
}
}
@@ -0,0 +1,100 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Math/Matrix3x4.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/typetraits/is_base_of.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/Containers/Views/FilterIterator.h>
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
#include <SceneAPI/SceneCore/Containers/Utilities/SceneGraphUtilities.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphChildIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/ITransform.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/ICoordinateSystemRule.h>
#include <SceneAPI/SceneCore/Containers/RuleContainer.h>
namespace AZ
{
namespace SceneAPI
{
namespace Utilities
{
DataTypes::MatrixType ConcatenateMatricesUpwards(const Containers::SceneGraph& graph, Containers::SceneGraph::NodeIndex nodeIndex)
{
DataTypes::MatrixType outTransform = DataTypes::MatrixType::Identity();
while (nodeIndex.IsValid())
{
auto view = Containers::Views::MakeSceneGraphChildView<Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, graph.GetContentStorage().begin(), true);
auto result = AZStd::find_if(view.begin(), view.end(), Containers::DerivedTypeFilter<DataTypes::ITransform>());
if (result != view.end())
{
// Check if the node has any child transform node
const DataTypes::MatrixType& azTransform = azrtti_cast<const DataTypes::ITransform*>(result->get())->GetMatrix();
outTransform = azTransform * outTransform;
}
else
{
// Check if the node itself is a transform node.
AZStd::shared_ptr<const DataTypes::ITransform> transformData = azrtti_cast<const DataTypes::ITransform*>(graph.GetNodeContent(nodeIndex));
if (transformData)
{
outTransform = transformData->GetMatrix() * outTransform;
}
}
if (graph.HasNodeParent(nodeIndex))
{
nodeIndex = graph.GetNodeParent(nodeIndex);
}
else
{
break;
}
}
return outTransform;
}
SCENE_CORE_API DataTypes::MatrixType DetermineWorldTransform(const Containers::Scene& scene, const Containers::SceneGraph::NodeIndex nodeIndex, const Containers::RuleContainer& ruleContainer)
{
auto coordinateSystemRule = ruleContainer.FindFirstByType<DataTypes::ICoordinateSystemRule>();
if (coordinateSystemRule && coordinateSystemRule->GetUseAdvancedData())
{
SceneAPI::DataTypes::MatrixType matrix = SceneAPI::DataTypes::MatrixType::CreateIdentity();
if (coordinateSystemRule->GetTranslation() != Vector3(0.0f, 0.0f, 0.0f) || !coordinateSystemRule->GetRotation().IsIdentity())
{
matrix = DataTypes::MatrixType::CreateFromQuaternionAndTranslation(coordinateSystemRule->GetRotation(), coordinateSystemRule->GetTranslation());
}
if (coordinateSystemRule->GetScale() != 1.0f)
{
float scale = coordinateSystemRule->GetScale();
matrix.MultiplyByScale(Vector3(scale, scale, scale));
}
if (!coordinateSystemRule->GetOriginNodeName().empty())
{
auto rootIndex = scene.GetGraph().Find(coordinateSystemRule->GetOriginNodeName());
if (rootIndex.IsValid())
{
auto worldMatrix = ConcatenateMatricesUpwards(scene.GetGraph(), rootIndex);
worldMatrix.InvertFull();
matrix *= worldMatrix;
}
}
return matrix;
}
return ConcatenateMatricesUpwards(scene.GetGraph(), nodeIndex);
}
} // Utilities
} // SceneAPI
} // AZ
@@ -0,0 +1,35 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
class Scene;
class RuleContainer;
}
namespace Utilities
{
SCENE_CORE_API DataTypes::MatrixType DetermineWorldTransform(
const Containers::Scene& scene,
const Containers::SceneGraph::NodeIndex nodeIndex,
const Containers::RuleContainer& ruleContainer);
} // Utilities
} // SceneAPI
} // AZ
@@ -125,7 +125,7 @@ namespace AZ
template<typename Iterator, typename Traversal>
void SceneGraphDownwardsIterator<Iterator, Traversal>::IgnoreNodeDescendants()
{
m_ignoreDescendants = true;
m_ignoreDescendants = -1;
}
template<typename Iterator, typename Traversal>
@@ -43,5 +43,12 @@ namespace AZ::SceneAPI::DataTypes
virtual CoordinateSystem GetTargetCoordinateSystem() const = 0;
virtual const CoordinateSystemConverter& GetCoordinateSystemConverter() const = 0;
// advanced coordinate settings
virtual bool GetUseAdvancedData() const = 0;
virtual const AZStd::string& GetOriginNodeName() const = 0;
virtual const Quaternion& GetRotation() const = 0;
virtual const Vector3& GetTranslation() const = 0;
virtual float GetScale() const = 0;
};
} // namespace AZ::SceneAPI::DataTypes
@@ -144,6 +144,7 @@ namespace AZ
if (context && (context->IsRemovingReflection() || !context->FindClassData(AZ::SceneAPI::DataTypes::IGroup::TYPEINFO_Uuid())))
{
AZ::SceneAPI::DataTypes::IManifestObject::Reflect(context);
AZ::SceneAPI::Events::CallProcessorBinder::Reflect(context);
// Register components
AZ::SceneAPI::SceneCore::BehaviorComponent::Reflect(context);
AZ::SceneAPI::SceneCore::LoadingComponent::Reflect(context);
@@ -10,6 +10,7 @@
*
*/
#include <AzCore/Serialization/SerializeContext.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.h>
namespace AZ
@@ -48,6 +49,14 @@ namespace AZ
m_bindings.clear();
}
void CallProcessorBinder::Reflect(AZ::ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<CallProcessorBinder>()->Version(1);
}
}
} // namespace Events
} // namespace SceneAPI
} // namespace AZ
@@ -20,6 +20,8 @@
namespace AZ
{
class ReflectContext;
namespace SceneAPI
{
namespace Events
@@ -55,6 +57,8 @@ namespace AZ
CallProcessorBinder() = default;
SCENE_CORE_API virtual ~CallProcessorBinder();
static void Reflect(AZ::ReflectContext* context);
protected:
CallProcessorBinder(const CallProcessorBinder&) = delete;
@@ -133,4 +137,4 @@ namespace AZ
} // namespace SceneAPI
} // namespace AZ
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.inl>
#include <SceneAPI/SceneCore/Events/CallProcessorBinder.inl>
@@ -94,6 +94,8 @@ set(FILES
Containers/Utilities/ProxyPointer.inl
Containers/Utilities/Filters.h
Containers/Utilities/Filters.inl
Containers/Utilities/SceneUtilities.h
Containers/Utilities/SceneUtilities.cpp
Containers/Utilities/SceneGraphUtilities.h
Containers/Utilities/SceneGraphUtilities.inl
Containers/Utilities/SceneGraphUtilities.cpp
@@ -53,19 +53,19 @@ namespace AZ
////////////////////////////////////////////////////////////////////////////////////////////
// AzToolsFramework::EditorPythonConsoleNotifications
void OnTraceMessage(AZStd::string_view message) override
void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message));
}
void OnErrorMessage(AZStd::string_view message) override
void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message));
}
void OnExceptionMessage(AZStd::string_view message) override
void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message));
@@ -30,6 +30,61 @@ namespace AZ
return static_cast<unsigned int>(m_positions.size()-1);
}
void BlendShapeData::AddTangentAndBitangent(const Vector4& tangent, const Vector3& bitangent)
{
m_tangents.push_back(tangent);
m_bitangents.push_back(bitangent);
}
void BlendShapeData::AddUV(const Vector2& uv, AZ::u8 uvSetIndex)
{
if (uvSetIndex >= MaxNumUVSets)
{
AZ_ErrorOnce("SceneGraphData", false, "uvSetIndex %zu is greater or equal than the maximum uv sets %zu.", uvSetIndex, MaxNumUVSets);
return;
}
m_uvs[uvSetIndex].push_back(uv);
}
void BlendShapeData::AddColor(const SceneAPI::DataTypes::Color& color, AZ::u8 colorSetIndex)
{
if (colorSetIndex >= MaxNumColorSets)
{
AZ_ErrorOnce("SceneGraphData", false, "colorSetIndex %zu is greater or equal than the maximum color sets %zu.", colorSetIndex, MaxNumColorSets);
return;
}
m_colors[colorSetIndex].push_back(color);
}
void BlendShapeData::ReserveData(
unsigned int numVertices, bool reserveTangents, const AZStd::bitset<MaxNumUVSets>& uvSetUsedFlags,
const AZStd::bitset<MaxNumColorSets>& colorSetUsedFlags)
{
m_positions.reserve(numVertices);
m_normals.reserve(numVertices);
if (reserveTangents)
{
m_tangents.reserve(numVertices);
m_bitangents.reserve(numVertices);
}
for (AZ::u8 uvSetIndex = 0; uvSetIndex < MaxNumUVSets; ++uvSetIndex)
{
if (uvSetUsedFlags[uvSetIndex])
{
m_uvs[uvSetIndex].reserve(numVertices);
}
}
for (AZ::u8 colorSetIndex = 0; colorSetIndex < MaxNumColorSets; ++colorSetIndex)
{
if (colorSetUsedFlags[colorSetIndex])
{
m_colors[colorSetIndex].reserve(numVertices);
}
}
}
void BlendShapeData::AddFace(const Face& face)
{
m_faces.push_back(face);
@@ -47,7 +102,7 @@ namespace AZ
int BlendShapeData::GetControlPointIndex(int vertexIndex) const
{
auto iter = m_vertexIndexToControlPointIndexMap.find(vertexIndex);
AZ_Assert(iter != m_vertexIndexToControlPointIndexMap.end(), "Vertex index %i doesn't exist", vertexIndex);
AZ_Assert(iter != m_vertexIndexToControlPointIndexMap.end(), "Vertex index %i doesn't exist.", vertexIndex);
// Note: AZStd::unordered_map's operator [] doesn't have const version...
return iter->second;
}
@@ -92,6 +147,45 @@ namespace AZ
return m_normals[index];
}
const Vector2& BlendShapeData::GetUV(unsigned int vertexIndex, unsigned int uvSetIndex) const
{
AZ_Assert(uvSetIndex < MaxNumUVSets, "uvSet index out of range");
AZ_Assert(vertexIndex < m_uvs[uvSetIndex].size(), "uvSet index out of range");
return m_uvs[uvSetIndex][vertexIndex];
}
AZStd::vector<Vector4>& BlendShapeData::GetTangents()
{
return m_tangents;
}
const AZStd::vector<Vector4>& BlendShapeData::GetTangents() const
{
return m_tangents;
}
AZStd::vector<Vector3>& BlendShapeData::GetBitangents()
{
return m_bitangents;
}
const AZStd::vector<Vector3>& BlendShapeData::GetBitangents() const
{
return m_bitangents;
}
const AZStd::vector<Vector2>& BlendShapeData::GetUVs(AZ::u8 uvSetIndex) const
{
AZ_Assert(uvSetIndex < MaxNumUVSets, "uvSet index out of range");
return m_uvs[uvSetIndex];
}
const AZStd::vector<SceneAPI::DataTypes::Color>& BlendShapeData::GetColors(AZ::u8 colorSetIndex) const
{
AZ_Assert(colorSetIndex < MaxNumColorSets, "colorSet index out of range");
return m_colors[colorSetIndex];
}
unsigned int BlendShapeData::GetFaceVertexIndex(unsigned int face, unsigned int vertexIndex) const
{
AZ_Assert(face < m_faces.size(), "GetFaceVertexPositionIndex face index not in range");
@@ -16,6 +16,7 @@
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/string/string.h>
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexColorData.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBlendShapeData.h>
namespace AZ
@@ -30,8 +31,19 @@ namespace AZ
public:
AZ_RTTI(BlendShapeData, "{FF875C22-2E4F-4CE3-BA49-09BF78C70A09}", SceneAPI::DataTypes::IBlendShapeData)
// Maximum number of color sets matches limitation set in assImp (AI_MAX_NUMBER_OF_COLOR_SETS)
static constexpr AZ::u8 MaxNumColorSets = 8;
// Maximum number of uv sets matches limitation set in assImp (AI_MAX_NUMBER_OF_TEXTURECOORDS)
static constexpr AZ::u8 MaxNumUVSets = 8;
SCENE_DATA_API ~BlendShapeData() override;
SCENE_DATA_API virtual unsigned int AddVertex(const Vector3& position, const Vector3& normal);
SCENE_DATA_API void AddTangentAndBitangent(const Vector4& tangent, const Vector3& bitangent);
SCENE_DATA_API void AddUV(const Vector2& uv, AZ::u8 uvSetIndex);
SCENE_DATA_API void AddColor(const SceneAPI::DataTypes::Color& color, AZ::u8 colorSetIndex);
SCENE_DATA_API void ReserveData(
unsigned int numVertices, bool reserveTangents, const AZStd::bitset<MaxNumUVSets>& uvSetUsedFlags,
const AZStd::bitset<MaxNumColorSets>& colorSetUsedFlags);
//assume consistent winding - no stripping or fanning expected (3 index per face)
SCENE_DATA_API virtual void AddFace(const Face& face);
@@ -48,6 +60,14 @@ namespace AZ
SCENE_DATA_API const Vector3& GetPosition(unsigned int index) const override;
SCENE_DATA_API const Vector3& GetNormal(unsigned int index) const override;
SCENE_DATA_API const Vector2& GetUV(unsigned int vertexIndex, unsigned int uvSetIndex) const;
SCENE_DATA_API AZStd::vector<Vector4>& GetTangents();
SCENE_DATA_API const AZStd::vector<Vector4>& GetTangents() const;
SCENE_DATA_API AZStd::vector<Vector3>& GetBitangents();
SCENE_DATA_API const AZStd::vector<Vector3>& GetBitangents() const;
SCENE_DATA_API const AZStd::vector<Vector2>& GetUVs(AZ::u8 uvSetIndex) const;
SCENE_DATA_API const AZStd::vector<SceneAPI::DataTypes::Color>& GetColors(AZ::u8 colorSetIndex) const;
SCENE_DATA_API unsigned int GetFaceVertexIndex(unsigned int face, unsigned int vertexIndex) const override;
@@ -56,6 +76,11 @@ namespace AZ
protected:
AZStd::vector<Vector3> m_positions;
AZStd::vector<Vector3> m_normals;
AZStd::vector<Vector4> m_tangents;
AZStd::vector<Vector3> m_bitangents;
AZStd::vector<AZ::Vector2> m_uvs[MaxNumUVSets];
AZStd::vector<SceneAPI::DataTypes::Color> m_colors[MaxNumColorSets];
AZStd::vector<Face> m_faces;
AZStd::unordered_map<int, int> m_vertexIndexToControlPointIndexMap;
@@ -30,49 +30,56 @@ namespace AZ::SceneAPI::SceneData
void CoordinateSystemRule::UpdateCoordinateSystemConverter()
{
switch (m_targetCoordinateSystem)
if (m_useAdvancedData)
{
case ZUpPositiveYForward:
m_coordinateSystemConverter = {};
}
else
{
switch (m_targetCoordinateSystem)
{
// Source coordinate system, use identity for now, which will currently just assume LY's coordinate system.
const AZ::Vector3 sourceBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f, 1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
case ZUpPositiveYForward:
{
// Source coordinate system, use identity for now, which will currently just assume LY's coordinate system.
const AZ::Vector3 sourceBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f, 1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
// The target coordinate system, with X and Y inverted (rotate 180 degrees over Z)
const AZ::Vector3 targetBasisVectors[3] = { AZ::Vector3(-1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f,-1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
// The target coordinate system, with X and Y inverted (rotate 180 degrees over Z)
const AZ::Vector3 targetBasisVectors[3] = { AZ::Vector3(-1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f,-1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
// X, Y and Z are all at the same indices inside the target coordinate system, compared to the source coordinate system.
const AZ::u32 targetBasisIndices[3] = { 0, 1, 2 };
// X, Y and Z are all at the same indices inside the target coordinate system, compared to the source coordinate system.
const AZ::u32 targetBasisIndices[3] = { 0, 1, 2 };
m_coordinateSystemConverter = CoordinateSystemConverter::CreateFromBasisVectors(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
}
break;
m_coordinateSystemConverter = CoordinateSystemConverter::CreateFromBasisVectors(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
}
break;
case ZUpNegativeYForward:
{
// Source coordinate system, use identity for now, which will currently just assume LY's coordinate system.
const AZ::Vector3 sourceBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f, 1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
case ZUpNegativeYForward:
{
// Source coordinate system, use identity for now, which will currently just assume LY's coordinate system.
const AZ::Vector3 sourceBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f, 1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
// The target coordinate system, which is the same as the source, so basically we won't do anything here.
const AZ::Vector3 targetBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f, 1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
// The target coordinate system, which is the same as the source, so basically we won't do anything here.
const AZ::Vector3 targetBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
AZ::Vector3( 0.0f, 1.0f, 0.0f),
AZ::Vector3( 0.0f, 0.0f, 1.0f) };
// X, Y and Z are all at the same indices inside the target coordinate system, compared to the source coordinate system.
const AZ::u32 targetBasisIndices[3] = { 0, 1, 2 };
// X, Y and Z are all at the same indices inside the target coordinate system, compared to the source coordinate system.
const AZ::u32 targetBasisIndices[3] = { 0, 1, 2 };
m_coordinateSystemConverter = CoordinateSystemConverter::CreateFromBasisVectors(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
}
break;
m_coordinateSystemConverter = CoordinateSystemConverter::CreateFromBasisVectors(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
}
break;
default:
AZ_Assert(false, "Unsupported coordinate system conversion");
};
default:
AZ_Assert(false, "Unsupported coordinate system conversion");
};
}
}
void CoordinateSystemRule::SetTargetCoordinateSystem(CoordinateSystem targetCoordinateSystem)
@@ -94,22 +101,74 @@ namespace AZ::SceneAPI::SceneData
return;
}
serializeContext->Class<CoordinateSystemRule, IRule>()->Version(1)
->Field("targetCoordinateSystem", &CoordinateSystemRule::m_targetCoordinateSystem);
serializeContext->Class<CoordinateSystemRule, IRule>()->Version(2) // LYN-2442
->Field("targetCoordinateSystem", &CoordinateSystemRule::m_targetCoordinateSystem)
->Field("useAdvancedData", &CoordinateSystemRule::m_useAdvancedData)
->Field("originNodeName", &CoordinateSystemRule::m_originNodeName)
->Field("rotation", &CoordinateSystemRule::m_rotation)
->Field("translation", &CoordinateSystemRule::m_translation)
->Field("scale", &CoordinateSystemRule::m_scale);
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class<CoordinateSystemRule>("Coordinate system change", "Modify the target coordinate system, applying a transformation to all data (transforms and vertex data if it exists).")
editContext->Class<CoordinateSystemRule>("Coordinate system change",
"Modify the target coordinate system, applying a transformation to all data (transforms and vertex data if it exists).")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &CoordinateSystemRule::m_targetCoordinateSystem, "Facing direction", "Change the direction the actor/motion will face by applying a post transformation to the data.")
->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_useAdvancedData,
"Use Advanced Settings",
"Toggles on the advanced settings for transforming the mesh group.")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &CoordinateSystemRule::m_targetCoordinateSystem,
"Facing direction",
"Change the direction the actor/motion will face by applying a post transformation to the data.")
->EnumAttribute(CoordinateSystem::ZUpNegativeYForward, "Do nothing")
->EnumAttribute(CoordinateSystem::ZUpPositiveYForward, "Rotate 180 degrees around the up axis");
->EnumAttribute(CoordinateSystem::ZUpPositiveYForward, "Rotate 180 degrees around the up axis")
->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetBasicVisibility)
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
->DataElement("NodeListSelection", &CoordinateSystemRule::m_originNodeName,
"Relative Origin Node",
"Select a Node from the scene as the origin for this export.")
->Attribute("DisabledOption", "")
->Attribute("DefaultToDisabled", false)
->Attribute("ExcludeEndPoints", true)
->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_translation,
"Translation",
"Moves the group along the given vector.")
->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_rotation,
"Rotation",
"Sets the orientation offset of the processed mesh in degrees. Rotates the group after translation.")
->Attribute(Edit::Attributes::LabelForX, "P")
->Attribute(Edit::Attributes::LabelForY, "R")
->Attribute(Edit::Attributes::LabelForZ, "Y")
->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_scale,
"Scale",
"Sets the scale offset of the processed mesh.")
->Attribute(Edit::Attributes::Min, 0.0001)
->Attribute(Edit::Attributes::Max, 1000.0)
->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues);
}
}
AZ::Crc32 CoordinateSystemRule::GetBasicVisibility() const
{
return (m_useAdvancedData) ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
}
AZ::Crc32 CoordinateSystemRule::GetAdvancedVisibility() const
{
return (m_useAdvancedData) ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
}
bool CoordinateSystemRule::ConvertLegacyCoordinateSystemRule(AZ::SerializeContext& serializeContext,
AZ::SerializeContext::DataElementNode& classElement)
{
@@ -155,4 +214,54 @@ namespace AZ::SceneAPI::SceneData
return true;
}
bool CoordinateSystemRule::GetUseAdvancedData() const
{
return m_useAdvancedData;
}
void CoordinateSystemRule::SetUseAdvancedData(bool useAdvancedData)
{
m_useAdvancedData = useAdvancedData;
}
const AZStd::string& CoordinateSystemRule::GetOriginNodeName() const
{
return m_originNodeName;
}
void CoordinateSystemRule::SetOriginNodeName(const AZStd::string& originNodeName)
{
m_originNodeName = originNodeName;
}
const Quaternion& CoordinateSystemRule::GetRotation() const
{
return m_rotation;
}
void CoordinateSystemRule::SetRotation(const Quaternion& rotation)
{
m_rotation = rotation;
}
const Vector3& CoordinateSystemRule::GetTranslation() const
{
return m_translation;
}
void CoordinateSystemRule::SetTranslation(const Vector3& translation)
{
m_translation = translation;
}
float CoordinateSystemRule::GetScale() const
{
return m_scale;
}
void CoordinateSystemRule::SetScale(float scale)
{
m_scale = scale;
}
} // namespace AZ::SceneAPI::SceneData
@@ -39,12 +39,34 @@ namespace AZ::SceneAPI::SceneData
SCENE_DATA_API const CoordinateSystemConverter& GetCoordinateSystemConverter() const override { return m_coordinateSystemConverter; }
static void Reflect(AZ::ReflectContext* context);
SCENE_DATA_API static void Reflect(AZ::ReflectContext* context);
SCENE_DATA_API static bool ConvertLegacyCoordinateSystemRule(AZ::SerializeContext& serializeContext,
AZ::SerializeContext::DataElementNode& classElement);
// advanced coordinate settings
SCENE_DATA_API bool GetUseAdvancedData() const override;
SCENE_DATA_API void SetUseAdvancedData(bool useAdvancedData);
SCENE_DATA_API const AZStd::string& GetOriginNodeName() const override;
SCENE_DATA_API void SetOriginNodeName(const AZStd::string& originNodeName);
SCENE_DATA_API const Quaternion& GetRotation() const override;
SCENE_DATA_API void SetRotation(const Quaternion& rotation);
SCENE_DATA_API const Vector3& GetTranslation() const override;
SCENE_DATA_API void SetTranslation(const Vector3& translation);
SCENE_DATA_API float GetScale() const override;
SCENE_DATA_API void SetScale(float scale);
protected:
AZ::Crc32 GetBasicVisibility() const;
AZ::Crc32 GetAdvancedVisibility() const;
CoordinateSystemConverter m_coordinateSystemConverter;
CoordinateSystem m_targetCoordinateSystem;
// advanced coordinate settings
bool m_useAdvancedData = false;
AZStd::string m_originNodeName;
AZ::Quaternion m_rotation = AZ::Quaternion::CreateIdentity();
AZ::Vector3 m_translation = AZ::Vector3::CreateZero();
float m_scale = 1.0f;
};
} // namespace AZ::SceneAPI::SceneData
@@ -14,7 +14,7 @@
#include <SceneAPI/SceneCore/Containers/SceneManifest.h>
#include <SceneAPI/SceneData/ReflectionRegistrar.h>
#include <SceneAPI/SceneData/Rules/CommentRule.h>
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
#include <AzCore/Name/NameDictionary.h>
#include <AzCore/RTTI/BehaviorContext.h>
@@ -87,6 +87,7 @@ namespace AZ
AZ::SceneAPI::RegisterDataTypeReflection(m_serializeContext.get());
AZ::SceneAPI::Containers::SceneManifest::Reflect(m_serializeContext.get());
AZ::SceneAPI::DataTypes::IManifestObject::Reflect(m_serializeContext.get());
m_serializeContext->Class<AZ::SceneAPI::DataTypes::IRule, AZ::SceneAPI::DataTypes::IManifestObject>()->Version(1);
AZ::SceneAPI::MockRotationRule::Reflect(m_serializeContext.get());
m_jsonRegistrationContext = AZStd::make_unique<AZ::JsonRegistrationContext>();
@@ -174,5 +175,53 @@ namespace AZ
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(0.27)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(0.65)"));
}
TEST_F(SceneManifest_JSON, LoadFromString_CoordinateSystemRule_ReturnsTrue)
{
AZ::SceneAPI::SceneData::CoordinateSystemRule foo;
EXPECT_FALSE(foo.GetUseAdvancedData());
using namespace SceneAPI::Containers;
constexpr const char* jsonCoordinateSystemRule = { R"JSON(
{
"values": [
{
"$type": "CoordinateSystemRule",
"useAdvancedData": true,
"originNodeName": "test_origin_name",
"translation": [1.0, 2.0, 3.0],
"rotation": { "yaw" : 45.0, "pitch" : 18.5, "roll" : 215.0 },
"scale": 10.0
}
]
})JSON" };
SceneManifest loaded;
auto loadFromStringResult = loaded.LoadFromString(jsonCoordinateSystemRule, m_serializeContext.get(), m_jsonRegistrationContext.get());
EXPECT_TRUE(loadFromStringResult.IsSuccess());
EXPECT_FALSE(loaded.IsEmpty());
auto writeToJsonResult =
SceneManifestContainer::SaveToJsonDocumentHelper(loaded, m_serializeContext.get(), m_jsonRegistrationContext.get());
ASSERT_TRUE(writeToJsonResult.IsSuccess());
AZStd::string jsonText;
auto writeToStringResult = AzFramework::FileFunc::WriteJsonToString(writeToJsonResult.GetValue(), jsonText);
ASSERT_TRUE(writeToStringResult.IsSuccess());
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"("$type": "CoordinateSystemRule")"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"("useAdvancedData": true,)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"("originNodeName": "test_origin_name",)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"("rotation": [)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(0.028)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(-0.40)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(0.85)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(-0.33)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"("translation": [)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(1.0)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(2.0)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"(3.0)"));
EXPECT_THAT(jsonText.c_str(), ::testing::HasSubstr(R"("scale": 10.0)"));
}
}
}
@@ -1,89 +0,0 @@
Universal Remote Console
------------------------
Important: for the tool to work properly, the configuration files
* filters.xml
* params.xml
need to be in the same directoy where the .exe is found.
The build process will copy these files in the correct directory. In case you accidentally delete them,
you can find these files in RemoteConsole/config-files.
Feel free to modify this files to your requirements.
================================ Overview ======================================
In a nutshell, this tool allows you to:
* connect remotely to the game (multiple platforms) and the editor
* process and filter the game's console output
* execute a macro or OS command when certain log is received
* execute CVars and macros, take videos, snapshots, ...
* process (offline) existing log files (drag & drop) [new!]
* modify in-game parameters while the game is running using sliders
* MIDI input devices supported (KORG at the moment) to execute macros and sliders
* MIDI input has the extra advantage of not requiring a change of focus in the application
* fully customisable via XML files that you can change the tool parameters on-the-fly.
* get some statistics
Any comments/questions/requests, just let me know (Dario [dariop])
================ Filter Configuration Quick Guide =======================================
File: filters.xml
It needs to be located in the SAME DIRECTORY as the application.
This file allows you to define your own filters and associated accions.
Feel free to add/remove/modify the contents of this file to suit your needs.
The initial content is intended to be an example of usage.
How does this work?
* <Filter Name="Example">
This attribute is used to specify the filter. In this example, any log that
contains the word "Example" will be added to this filter's tab.
* <Label>My Example</Label>
This parameter is optional. If included it will be used to label the filter Tab.
Otherwise, the "Name" attribute in Filter will be used.
* <Color>FF0000</Color>
Optional. Specifies the color of the text in the filter. Format R8G8B8.
* <RegExp>\!(\w*)\]</RegExp>
Optional. Specifies a regular expression to be used as filter. The given example
would would added to this filter's tab any log that contains something of the
kind "...!....]", i.e. has an exclamation mark and at certain point later a "]"
* <Exec Type="DosCmd">dir c:</Exec>
Optional. Specifies an action to be taken if a particular filter is activated.
It can be used for instance to trigger a snapshot or a video when certain log
message is sent (e.g. a debugging message).
It can be very useful for debugging and QA.
There are two types of actions that can be executed:
+ <Exec Type="Macro">ScreenShot</Exec>
Executes a Macro (in this case ScreenShot, defined in this file)
+ <Exec Type="DosCmd">dir c:</Exec>
Executes a dos command (in this case "dir c:")
================ Menu Configuration Quick Guide =======================================
File: params.xml
It needs to be located in the SAME DIRECTORY as the application.
This file defines the menu of the applciation. You can add:
* Targets (IPs of the devices you want to connect to)
* Macros (set of CVars you want to sent at once to the game)
* GamePlay-specific commands (e.g. SetViewMode:FlyOn)
* Buttons (Macros that are places as separate buttons)
* Sliders (Macros whose parameters change with the slider value)
You can assign MIDI codes to each entry so they can be controlled via an external MIDI input.
All this data will become part of your menu so you can customize what you really need.
... and some more stuff to be discovered :-)
Cheers
Dario
@@ -1,41 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteConsole", "RemoteConsole\RemoteConsole.csproj", "{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|Any CPU.ActiveCfg = Debug|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|Any CPU.Build.0 = Debug|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|Mixed Platforms.Build.0 = Debug|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|x64.ActiveCfg = Debug|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|x64.Build.0 = Debug|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|x86.ActiveCfg = Debug|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Debug|x86.Build.0 = Debug|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|Any CPU.ActiveCfg = Release|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|Any CPU.Build.0 = Release|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|Mixed Platforms.ActiveCfg = Release|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|Mixed Platforms.Build.0 = Release|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|x64.ActiveCfg = Release|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|x64.Build.0 = Release|x64
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|x86.ActiveCfg = Release|x86
{1C86D237-2FDE-4303-835F-4A4E1F17E0C5}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = RemoteConsole\RemoteConsole.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -1,128 +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.
using System;
using System.Collections.Generic;
using System.Text;
namespace RemoteConsole
{
public static class Common
{
public static readonly string FiltersFileFullPath = System.IO.Path.Combine( System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "filters.xml");
public static readonly string MenusFileFullPath = System.IO.Path.Combine( System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "params.xml");
public static readonly string IconsPath = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + System.IO.Path.PathSeparator + "Icons" + System.IO.Path.PathSeparator;
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
Comparer<T> comp = Comparer<T>.Default;
if (comp.Compare(val, min) <= 0) return min;
else if (comp.Compare(val, max) >= 0) return max;
else return val;
}
public static int AddImageFileToImageList(string path, System.Windows.Forms.ImageList imgList)
{
if (path != null)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(path);
if (fileInfo.Exists)
{
System.Drawing.Image img = System.Drawing.Image.FromFile(path);
imgList.Images.Add(img);
return imgList.Images.Count - 1;
}
}
return -1;
}
public static bool IsRunningOnMono ()
{
return Type.GetType ("Mono.Runtime") != null;
}
}
public class CSettings
{
public enum EMode
{
eM_Full = 0, // Normal mode (connected to target)
eM_CommandsOnly, // Connected to target but not reading the log
eM_FileOnly, // Parse a file (not connected to target)
}
public bool DebugMidi = false;
public EMode Mode = EMode.eM_Full;
}
}
#if __MonoCS__
/**
* As of 2014/11/28, Mono lacks an implementation of System.Windows.Forms.DataVisualization.Charting.Chart.
* This code functions as a proxy to work around that.
*/
namespace System.Windows.Forms.DataVisualization.Charting
{
/**
* Various System.Windows.Forms.DataVisualization.Charting.*Collection member methods throw NotImplemented on use.
* JunkCollection provides the same method interface with implicit conversion operators to avoid complicating code.
*/
public class JunkCollection<T> : List<T>
{
public static implicit operator ChartAreaCollection(JunkCollection<T> list)
{
return new ChartAreaCollection ();
}
public static implicit operator LegendCollection(JunkCollection<T> list)
{
return new LegendCollection ();
}
public static implicit operator SeriesCollection(JunkCollection<T> list)
{
return new SeriesCollection ();
}
static T s_value;
public T this[string key]
{
get { return s_value; }
set { }
}
public void Add(string ignore)
{
}
}
public class Chart : System.Windows.Forms.Control, System.ComponentModel.ISupportInitialize
{
public ChartDashStyle BorderlineDashStyle;
public JunkCollection< ChartArea > ChartAreas = new JunkCollection< ChartArea > ();
public JunkCollection< Legend > Legends = new JunkCollection< Legend > ();
public JunkCollection< Series > Series = new JunkCollection< Series > ();
#region System.ComponentModel.ISupportInitialize
public void BeginInit()
{
}
public void EndInit()
{
}
#endregion
}
}
#endif
@@ -1,139 +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.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace RemoteConsole
{
class FilterData
{
public string Tag { get; private set; } // tag to search for in the log string
public string RegExpText; // customize reg exp search
public string Label; // tab label
public EMessageType MsgType { get; private set; } // text type (error, warning, message...)
public List<Exec> Execute { get; private set; } // Commands to Execute
public int TextColor = Convert.ToInt32("FFFFFF", 16); // White color by default
public class Exec
{
public enum EExecType
{
eET_None = 0,
eET_Macro,
eET_DosCmd
}
public Exec(string typeStr_, string cmd_)
{
string s = typeStr_.ToLower();
if (s == "macro")
Type = EExecType.eET_Macro;
else if (s == "doscmd")
Type = EExecType.eET_DosCmd;
else
Type = EExecType.eET_None;
Command = cmd_;
}
public EExecType Type { get; private set; }
public string Command { get; private set; }
}
public FilterData(string tabName_, EMessageType type)
{
this.Tag = tabName_;
this.Label = tabName_;
this.MsgType = type;
Execute = new List<Exec>();
}
public void AddExecCommand(Exec e)
{
if (e != null)
{
if (Execute.Find(x => x.Command.ToLower() == e.Command.ToLower()) == null)
{
Execute.Add(e);
}
}
}
}
class FilterFileReader
{
public List<FilterData> CreateStandardFilters()
{
List<FilterData> filterDataList = new List<FilterData>();
FilterData data = new FilterData("[*Error*]", EMessageType.eMT_Error);
data.Label = "Errors";
data.TextColor = Convert.ToInt32("FF0000", 16);
filterDataList.Add(data);
data = new FilterData("[*Warnings*]", EMessageType.eMT_Warning);
data.Label = "Warnings";
data.TextColor = Convert.ToInt32("0000FF", 16);
filterDataList.Add(data);
return filterDataList;
}
private int ExtractColor(string text)
{
Regex rx = new Regex("#?([0-9A-Fa-f]{6})");
Match match = rx.Match(text);
if (match.Success && match.Groups.Count == 2)
{
string hexColor = match.Groups[1].Value;
return Convert.ToInt32(hexColor, 16);
}
return 0;
}
public List<FilterData> GetXmlFilters(string path)
{
if (System.IO.File.Exists(path) == false)
{
return null;
}
List<FilterData> filterDataList = new List<FilterData>();
System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
xd.Load(path);
System.Xml.XmlNodeList nodelist = xd.SelectNodes("/Filters/Filter");
foreach (System.Xml.XmlNode node in nodelist) // for each <Filter> node
{
FilterData filter = new FilterData(node.Attributes.GetNamedItem("Name").Value, EMessageType.eMT_Message);
System.Xml.XmlNode n = node.SelectSingleNode("Label");
if (n != null) { filter.Label = n.InnerText; }
n = node.SelectSingleNode("Color");
if (n != null) { filter.TextColor = ExtractColor(n.InnerText); }
n = node.SelectSingleNode("RegExp");
if (n != null) { filter.RegExpText = n.InnerText; }
n = node.SelectSingleNode("Exec");
if (n != null)
{
filter.AddExecCommand(
new FilterData.Exec(n.Attributes.GetNamedItem("Type").Value,
n.InnerText)
);
}
filterDataList.Add(filter);
}
return filterDataList;
}
}
}
@@ -1,844 +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.
*
*/
namespace RemoteConsole
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
this.topToolStrip = new System.Windows.Forms.ToolStrip();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.cmsGraph = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
this.logPanel = new System.Windows.Forms.Panel();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tabControlTop = new System.Windows.Forms.TabControl();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.logChart = new System.Windows.Forms.DataVisualization.Charting.Chart();
this.contextMenuHistoryChart = new System.Windows.Forms.ContextMenuStrip(this.components);
this.historyChartViewMenu = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.historyChartClear = new System.Windows.Forms.ToolStripMenuItem();
this.tabFullLog = new System.Windows.Forms.TabPage();
this.fullLogConsole = new System.Windows.Forms.RichTextBox();
this.contextMenuTabs = new System.Windows.Forms.ContextMenuStrip(this.components);
this.actionSelectAll = new System.Windows.Forms.ToolStripMenuItem();
this.actionCopy = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.actionClear = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.actionClearAll = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.actionEditFiltersFile = new System.Windows.Forms.ToolStripMenuItem();
this.lalala = new System.Windows.Forms.ToolStripTextBox();
this.lalala2 = new System.Windows.Forms.ToolStripTextBox();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.panelHelp = new System.Windows.Forms.Panel();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.tabPageMidi = new System.Windows.Forms.TabPage();
this.lvMidiLog = new System.Windows.Forms.ListView();
this.cHNum = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cHLog = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cHChannel = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.chMode = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.chCode = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.chVelocity = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.tabControlFilters = new System.Windows.Forms.TabControl();
this.commandPanel = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.editInput = new System.Windows.Forms.TextBox();
this.imgList = new System.Windows.Forms.ImageList(this.components);
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.statusLabelTarget = new System.Windows.Forms.ToolStripStatusLabel();
this.statusLabelIp = new System.Windows.Forms.ToolStripStatusLabel();
this.labelSeparator = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabel4 = new System.Windows.Forms.ToolStripStatusLabel();
this.statusLabelMode = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabel5 = new System.Windows.Forms.ToolStripStatusLabel();
this.statusLabelMidi = new System.Windows.Forms.ToolStripStatusLabel();
this.forceRightAlignment = new System.Windows.Forms.ToolStripStatusLabel();
this.statusMenuLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.menuStatusText = new System.Windows.Forms.ToolStripStatusLabel();
this.statusLabelFilters = new System.Windows.Forms.ToolStripStatusLabel();
this.filtersTextStatus = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabel3 = new System.Windows.Forms.ToolStripStatusLabel();
this.statusConnectedImg = new System.Windows.Forms.ToolStripStatusLabel();
this.statusLabelConnected = new System.Windows.Forms.ToolStripStatusLabel();
this.bottomPanel = new System.Windows.Forms.Panel();
this.bodyPanel = new System.Windows.Forms.Panel();
this.imgList32 = new System.Windows.Forms.ImageList(this.components);
this.topToolStrip.SuspendLayout();
this.cmsGraph.SuspendLayout();
this.logPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.tabControlTop.SuspendLayout();
this.tabPage2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.logChart)).BeginInit();
this.contextMenuHistoryChart.SuspendLayout();
this.tabFullLog.SuspendLayout();
this.contextMenuTabs.SuspendLayout();
this.tabPage1.SuspendLayout();
this.panelHelp.SuspendLayout();
this.tabPageMidi.SuspendLayout();
this.commandPanel.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.bottomPanel.SuspendLayout();
this.bodyPanel.SuspendLayout();
this.SuspendLayout();
//
// topToolStrip
//
this.topToolStrip.Dock = System.Windows.Forms.DockStyle.None;
this.topToolStrip.ImageScalingSize = new System.Drawing.Size(32, 32);
this.topToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripSeparator1});
this.topToolStrip.Location = new System.Drawing.Point(3, 9);
this.topToolStrip.Name = "topToolStrip";
this.topToolStrip.Size = new System.Drawing.Size(18, 25);
this.topToolStrip.TabIndex = 0;
this.topToolStrip.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.topToolStrip_ItemClicked);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// cmsGraph
//
this.cmsGraph.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem3});
this.cmsGraph.Name = "contextMenuStrip1";
this.cmsGraph.Size = new System.Drawing.Size(134, 26);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem3.Image")));
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(133, 22);
this.toolStripMenuItem3.Text = "Next Graph";
//
// logPanel
//
this.logPanel.AutoSize = true;
this.logPanel.Controls.Add(this.splitContainer1);
this.logPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.logPanel.Location = new System.Drawing.Point(0, 0);
this.logPanel.Name = "logPanel";
this.logPanel.Padding = new System.Windows.Forms.Padding(3);
this.logPanel.Size = new System.Drawing.Size(884, 503);
this.logPanel.TabIndex = 1;
//
// splitContainer1
//
this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(3, 3);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.tabControlTop);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.tabControlFilters);
this.splitContainer1.Size = new System.Drawing.Size(878, 497);
this.splitContainer1.SplitterDistance = 204;
this.splitContainer1.TabIndex = 2;
//
// tabControlTop
//
this.tabControlTop.Controls.Add(this.tabPage2);
this.tabControlTop.Controls.Add(this.tabFullLog);
this.tabControlTop.Controls.Add(this.tabPage1);
this.tabControlTop.Controls.Add(this.tabPageMidi);
this.tabControlTop.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControlTop.Location = new System.Drawing.Point(0, 0);
this.tabControlTop.Name = "tabControlTop";
this.tabControlTop.SelectedIndex = 0;
this.tabControlTop.Size = new System.Drawing.Size(874, 200);
this.tabControlTop.TabIndex = 2;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.logChart);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(866, 174);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Chart";
this.tabPage2.UseVisualStyleBackColor = true;
//
// logChart
//
this.logChart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
chartArea1.Name = "ChartArea1";
this.logChart.ChartAreas.Add(chartArea1);
this.logChart.ContextMenuStrip = this.contextMenuHistoryChart;
this.logChart.Dock = System.Windows.Forms.DockStyle.Fill;
legend1.Name = "Legend1";
this.logChart.Legends.Add(legend1);
this.logChart.Location = new System.Drawing.Point(3, 3);
this.logChart.Name = "logChart";
this.logChart.Size = new System.Drawing.Size(860, 168);
this.logChart.TabIndex = 16;
//
// contextMenuHistoryChart
//
this.contextMenuHistoryChart.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.historyChartViewMenu,
this.toolStripSeparator3,
this.historyChartClear});
this.contextMenuHistoryChart.Name = "contextMenuStrip1";
this.contextMenuHistoryChart.Size = new System.Drawing.Size(102, 54);
this.contextMenuHistoryChart.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuHistoryChart_Opening);
//
// historyChartViewMenu
//
this.historyChartViewMenu.Image = ((System.Drawing.Image)(resources.GetObject("historyChartViewMenu.Image")));
this.historyChartViewMenu.Name = "historyChartViewMenu";
this.historyChartViewMenu.Size = new System.Drawing.Size(101, 22);
this.historyChartViewMenu.Text = "View";
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(98, 6);
//
// historyChartClear
//
this.historyChartClear.Image = ((System.Drawing.Image)(resources.GetObject("historyChartClear.Image")));
this.historyChartClear.Name = "historyChartClear";
this.historyChartClear.Size = new System.Drawing.Size(101, 22);
this.historyChartClear.Text = "Clear";
this.historyChartClear.Click += new System.EventHandler(this.historyChartClear_Click);
//
// tabFullLog
//
this.tabFullLog.Controls.Add(this.fullLogConsole);
this.tabFullLog.Location = new System.Drawing.Point(4, 22);
this.tabFullLog.Name = "tabFullLog";
this.tabFullLog.Padding = new System.Windows.Forms.Padding(3);
this.tabFullLog.Size = new System.Drawing.Size(866, 174);
this.tabFullLog.TabIndex = 0;
this.tabFullLog.Text = "Full Log";
this.tabFullLog.UseVisualStyleBackColor = true;
//
// fullLogConsole
//
this.fullLogConsole.BackColor = System.Drawing.SystemColors.WindowText;
this.fullLogConsole.ContextMenuStrip = this.contextMenuTabs;
this.fullLogConsole.Dock = System.Windows.Forms.DockStyle.Fill;
this.fullLogConsole.ForeColor = System.Drawing.Color.Silver;
this.fullLogConsole.Location = new System.Drawing.Point(3, 3);
this.fullLogConsole.Name = "fullLogConsole";
this.fullLogConsole.ReadOnly = true;
this.fullLogConsole.Size = new System.Drawing.Size(860, 168);
this.fullLogConsole.TabIndex = 0;
this.fullLogConsole.Text = "";
//
// contextMenuTabs
//
this.contextMenuTabs.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.actionSelectAll,
this.actionCopy,
this.toolStripSeparator2,
this.actionClear,
this.toolStripSeparator4,
this.actionClearAll,
this.toolStripSeparator5,
this.actionEditFiltersFile,
this.lalala,
this.lalala2,
this.toolStripSeparator6});
this.contextMenuTabs.Name = "contextMenuStrip1";
this.contextMenuTabs.Size = new System.Drawing.Size(176, 188);
//
// actionSelectAll
//
this.actionSelectAll.Name = "actionSelectAll";
this.actionSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.actionSelectAll.Size = new System.Drawing.Size(175, 22);
this.actionSelectAll.Text = "Select All";
this.actionSelectAll.Click += new System.EventHandler(this.actionSelectAll_Click);
//
// actionCopy
//
this.actionCopy.Image = ((System.Drawing.Image)(resources.GetObject("actionCopy.Image")));
this.actionCopy.Name = "actionCopy";
this.actionCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
this.actionCopy.Size = new System.Drawing.Size(175, 22);
this.actionCopy.Text = "Copy";
this.actionCopy.Click += new System.EventHandler(this.actionCopy_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(172, 6);
//
// actionClear
//
this.actionClear.Image = ((System.Drawing.Image)(resources.GetObject("actionClear.Image")));
this.actionClear.Name = "actionClear";
this.actionClear.ShortcutKeys = System.Windows.Forms.Keys.Delete;
this.actionClear.Size = new System.Drawing.Size(175, 22);
this.actionClear.Text = "Clear";
this.actionClear.Click += new System.EventHandler(this.actionClear_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(172, 6);
//
// actionClearAll
//
this.actionClearAll.Image = ((System.Drawing.Image)(resources.GetObject("actionClearAll.Image")));
this.actionClearAll.Name = "actionClearAll";
this.actionClearAll.Size = new System.Drawing.Size(175, 22);
this.actionClearAll.Text = "Clear ALL Filters";
this.actionClearAll.Click += new System.EventHandler(this.actionClearAll_Click);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(172, 6);
//
// actionEditFiltersFile
//
this.actionEditFiltersFile.Image = ((System.Drawing.Image)(resources.GetObject("actionEditFiltersFile.Image")));
this.actionEditFiltersFile.Name = "actionEditFiltersFile";
this.actionEditFiltersFile.Size = new System.Drawing.Size(175, 22);
this.actionEditFiltersFile.Text = "-- Edit Filters File --";
this.actionEditFiltersFile.Click += new System.EventHandler(this.actionEditFiltersFile_Click);
//
// lalala
//
this.lalala.Enabled = false;
this.lalala.Name = "lalala";
this.lalala.Size = new System.Drawing.Size(100, 23);
this.lalala.Text = "PORT";
//
// lalala2
//
this.lalala2.Name = "lalala2";
this.lalala2.Size = new System.Drawing.Size(100, 23);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(172, 6);
//
// tabPage1
//
this.tabPage1.Controls.Add(this.panelHelp);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(866, 174);
this.tabPage1.TabIndex = 2;
this.tabPage1.Text = "About/Help";
this.tabPage1.UseVisualStyleBackColor = true;
//
// panelHelp
//
this.panelHelp.Controls.Add(this.richTextBox1);
this.panelHelp.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelHelp.Location = new System.Drawing.Point(3, 3);
this.panelHelp.Name = "panelHelp";
this.panelHelp.Size = new System.Drawing.Size(860, 168);
this.panelHelp.TabIndex = 0;
//
// richTextBox1
//
this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.richTextBox1.Location = new System.Drawing.Point(0, 0);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.ReadOnly = true;
this.richTextBox1.Size = new System.Drawing.Size(860, 168);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = resources.GetString("richTextBox1.Text");
//
// tabPageMidi
//
this.tabPageMidi.Controls.Add(this.lvMidiLog);
this.tabPageMidi.Location = new System.Drawing.Point(4, 22);
this.tabPageMidi.Name = "tabPageMidi";
this.tabPageMidi.Padding = new System.Windows.Forms.Padding(3);
this.tabPageMidi.Size = new System.Drawing.Size(866, 174);
this.tabPageMidi.TabIndex = 3;
this.tabPageMidi.Text = "Midi Debug";
this.tabPageMidi.UseVisualStyleBackColor = true;
//
// lvMidiLog
//
this.lvMidiLog.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.cHNum,
this.cHLog,
this.cHChannel,
this.chMode,
this.chCode,
this.chVelocity});
this.lvMidiLog.Dock = System.Windows.Forms.DockStyle.Fill;
this.lvMidiLog.Location = new System.Drawing.Point(3, 3);
this.lvMidiLog.Name = "lvMidiLog";
this.lvMidiLog.Size = new System.Drawing.Size(860, 168);
this.lvMidiLog.TabIndex = 0;
this.lvMidiLog.UseCompatibleStateImageBehavior = false;
this.lvMidiLog.View = System.Windows.Forms.View.Details;
//
// cHNum
//
this.cHNum.Text = "#";
//
// cHLog
//
this.cHLog.Text = "Log";
this.cHLog.Width = 278;
//
// cHChannel
//
this.cHChannel.Text = "Channel";
//
// chMode
//
this.chMode.Text = "Mode";
//
// chCode
//
this.chCode.Text = "Code";
//
// chVelocity
//
this.chVelocity.Text = "Vel";
//
// tabControlFilters
//
this.tabControlFilters.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControlFilters.Location = new System.Drawing.Point(0, 0);
this.tabControlFilters.Name = "tabControlFilters";
this.tabControlFilters.SelectedIndex = 0;
this.tabControlFilters.Size = new System.Drawing.Size(874, 285);
this.tabControlFilters.TabIndex = 1;
//
// commandPanel
//
this.commandPanel.AutoSize = true;
this.commandPanel.Controls.Add(this.label1);
this.commandPanel.Controls.Add(this.editInput);
this.commandPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.commandPanel.Location = new System.Drawing.Point(0, 0);
this.commandPanel.MaximumSize = new System.Drawing.Size(0, 26);
this.commandPanel.MinimumSize = new System.Drawing.Size(0, 26);
this.commandPanel.Name = "commandPanel";
this.commandPanel.Padding = new System.Windows.Forms.Padding(3);
this.commandPanel.Size = new System.Drawing.Size(884, 26);
this.commandPanel.TabIndex = 2;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(5, 7);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(92, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Type a command:";
//
// editInput
//
this.editInput.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.editInput.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.editInput.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource;
this.editInput.BackColor = System.Drawing.Color.Black;
this.editInput.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.editInput.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.editInput.Location = new System.Drawing.Point(103, 0);
this.editInput.Name = "editInput";
this.editInput.Size = new System.Drawing.Size(6768, 23);
this.editInput.TabIndex = 0;
this.editInput.KeyUp += new System.Windows.Forms.KeyEventHandler(this.editInput_KeyUp);
//
// imgList
//
this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream")));
this.imgList.TransparentColor = System.Drawing.Color.Transparent;
this.imgList.Images.SetKeyName(0, "red.png");
this.imgList.Images.SetKeyName(1, "green.png");
this.imgList.Images.SetKeyName(2, "clear.png");
this.imgList.Images.SetKeyName(3, "copy.png");
this.imgList.Images.SetKeyName(4, "pc");
this.imgList.Images.SetKeyName(6, "UnknownTarget");
this.imgList.Images.SetKeyName(7, "videoClipRecord");
this.imgList.Images.SetKeyName(8, "screenShoot");
this.imgList.Images.SetKeyName(9, "PcMouseImg");
this.imgList.Images.SetKeyName(10, "EditIpImg");
this.imgList.Images.SetKeyName(11, "IpImg");
this.imgList.Images.SetKeyName(12, "ModeFullImg");
this.imgList.Images.SetKeyName(13, "ModeCmdImg");
this.imgList.Images.SetKeyName(14, "ModeFileImg");
this.imgList.Images.SetKeyName(15, "PortImg");
this.imgList.Images.SetKeyName(16, "WinLogoImg16");
this.imgList.Images.SetKeyName(17, "provo");
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel2,
this.toolStripStatusLabel1,
this.statusLabelTarget,
this.statusLabelIp,
this.labelSeparator,
this.toolStripStatusLabel4,
this.statusLabelMode,
this.toolStripStatusLabel5,
this.statusLabelMidi,
this.forceRightAlignment,
this.statusMenuLabel,
this.menuStatusText,
this.statusLabelFilters,
this.filtersTextStatus,
this.toolStripStatusLabel3,
this.statusConnectedImg,
this.statusLabelConnected});
this.statusStrip1.Location = new System.Drawing.Point(0, 26);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(884, 24);
this.statusStrip1.TabIndex = 3;
this.statusStrip1.Text = "statusStrip1";
//
// toolStripStatusLabel2
//
this.toolStripStatusLabel2.Name = "toolStripStatusLabel2";
this.toolStripStatusLabel2.Size = new System.Drawing.Size(0, 19);
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(43, 19);
this.toolStripStatusLabel1.Text = "Target:";
//
// statusLabelTarget
//
this.statusLabelTarget.Name = "statusLabelTarget";
this.statusLabelTarget.Size = new System.Drawing.Size(54, 19);
this.statusLabelTarget.Text = "[Not Set]";
//
// statusLabelIp
//
this.statusLabelIp.Name = "statusLabelIp";
this.statusLabelIp.Size = new System.Drawing.Size(25, 19);
this.statusLabelIp.Text = "[IP]";
//
// labelSeparator
//
this.labelSeparator.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)));
this.labelSeparator.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.labelSeparator.Name = "labelSeparator";
this.labelSeparator.Size = new System.Drawing.Size(4, 19);
//
// toolStripStatusLabel4
//
this.toolStripStatusLabel4.Name = "toolStripStatusLabel4";
this.toolStripStatusLabel4.Size = new System.Drawing.Size(41, 19);
this.toolStripStatusLabel4.Text = "Mode:";
//
// statusLabelMode
//
this.statusLabelMode.ImageTransparentColor = System.Drawing.Color.Magenta;
this.statusLabelMode.Name = "statusLabelMode";
this.statusLabelMode.Size = new System.Drawing.Size(38, 19);
this.statusLabelMode.Text = "Mode";
//
// toolStripStatusLabel5
//
this.toolStripStatusLabel5.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
this.toolStripStatusLabel5.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.toolStripStatusLabel5.Name = "toolStripStatusLabel5";
this.toolStripStatusLabel5.Size = new System.Drawing.Size(38, 19);
this.toolStripStatusLabel5.Text = "Midi:";
//
// statusLabelMidi
//
this.statusLabelMidi.Name = "statusLabelMidi";
this.statusLabelMidi.Size = new System.Drawing.Size(118, 19);
this.statusLabelMidi.Text = "toolStripStatusLabel6";
//
// forceRightAlignment
//
this.forceRightAlignment.Name = "forceRightAlignment";
this.forceRightAlignment.Size = new System.Drawing.Size(177, 19);
this.forceRightAlignment.Spring = true;
//
// statusMenuLabel
//
this.statusMenuLabel.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
this.statusMenuLabel.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.statusMenuLabel.Name = "statusMenuLabel";
this.statusMenuLabel.Size = new System.Drawing.Size(45, 19);
this.statusMenuLabel.Text = "Menu:";
//
// menuStatusText
//
this.menuStatusText.Name = "menuStatusText";
this.menuStatusText.Size = new System.Drawing.Size(48, 19);
this.menuStatusText.Text = "Missing";
//
// statusLabelFilters
//
this.statusLabelFilters.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
this.statusLabelFilters.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.statusLabelFilters.Name = "statusLabelFilters";
this.statusLabelFilters.Size = new System.Drawing.Size(45, 19);
this.statusLabelFilters.Text = "Filters:";
//
// filtersTextStatus
//
this.filtersTextStatus.Name = "filtersTextStatus";
this.filtersTextStatus.Size = new System.Drawing.Size(48, 19);
this.filtersTextStatus.Text = "Missing";
//
// toolStripStatusLabel3
//
this.toolStripStatusLabel3.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
this.toolStripStatusLabel3.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.toolStripStatusLabel3.Name = "toolStripStatusLabel3";
this.toolStripStatusLabel3.Size = new System.Drawing.Size(46, 19);
this.toolStripStatusLabel3.Text = "Status:";
//
// statusConnectedImg
//
this.statusConnectedImg.Image = ((System.Drawing.Image)(resources.GetObject("statusConnectedImg.Image")));
this.statusConnectedImg.Name = "statusConnectedImg";
this.statusConnectedImg.Size = new System.Drawing.Size(16, 19);
//
// statusLabelConnected
//
this.statusLabelConnected.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right;
this.statusLabelConnected.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.statusLabelConnected.Name = "statusLabelConnected";
this.statusLabelConnected.Size = new System.Drawing.Size(83, 19);
this.statusLabelConnected.Text = "Disconnected";
//
// bottomPanel
//
this.bottomPanel.Controls.Add(this.commandPanel);
this.bottomPanel.Controls.Add(this.statusStrip1);
this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.bottomPanel.Location = new System.Drawing.Point(0, 503);
this.bottomPanel.Name = "bottomPanel";
this.bottomPanel.Size = new System.Drawing.Size(884, 50);
this.bottomPanel.TabIndex = 4;
//
// bodyPanel
//
this.bodyPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.bodyPanel.Controls.Add(this.logPanel);
this.bodyPanel.Controls.Add(this.bottomPanel);
this.bodyPanel.Location = new System.Drawing.Point(0, 53);
this.bodyPanel.Name = "bodyPanel";
this.bodyPanel.Size = new System.Drawing.Size(884, 553);
this.bodyPanel.TabIndex = 1;
//
// imgList32
//
this.imgList32.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList32.ImageStream")));
this.imgList32.TransparentColor = System.Drawing.Color.Transparent;
this.imgList32.Images.SetKeyName(0, "Spanner");
this.imgList32.Images.SetKeyName(1, "TargetImg1");
this.imgList32.Images.SetKeyName(2, "TargetImg3");
this.imgList32.Images.SetKeyName(3, "GamePlayImg2");
this.imgList32.Images.SetKeyName(4, "ExtraMacrosImg");
this.imgList32.Images.SetKeyName(5, "ModeFilesImg32");
this.imgList32.Images.SetKeyName(6, "ListImg");
this.imgList32.Images.SetKeyName(7, "GamePlayImg3");
this.imgList32.Images.SetKeyName(8, "TargetImg3");
this.imgList32.Images.SetKeyName(9, "ModeImg32");
this.imgList32.Images.SetKeyName(10, "ModeImg32_Cmd");
this.imgList32.Images.SetKeyName(11, "ModeImg32_File");
this.imgList32.Images.SetKeyName(12, "AnalogImg32");
this.imgList32.Images.SetKeyName(13, "GamePlayImg");
this.imgList32.Images.SetKeyName(14, "TargetImg2");
this.imgList32.Images.SetKeyName(15, "RadImg32");
this.imgList32.Images.SetKeyName(16, "EarthImg32");
this.imgList32.Images.SetKeyName(17, "SettingsImg32");
this.imgList32.Images.SetKeyName(18, "SlidersImg32");
this.imgList32.Images.SetKeyName(19, "ToolsImg32");
this.imgList32.Images.SetKeyName(20, "ModeCmdImg32");
this.imgList32.Images.SetKeyName(21, "ModeFullImg32");
this.imgList32.Images.SetKeyName(22, "EmptyImg32");
this.imgList32.Images.SetKeyName(23, "FileImg32");
this.imgList32.Images.SetKeyName(24, "FullImg32");
this.imgList32.Images.SetKeyName(25, "NoImg32");
this.imgList32.Images.SetKeyName(26, "OkImg32");
this.imgList32.Images.SetKeyName(27, "BubbleImg32");
this.imgList32.Images.SetKeyName(28, "UpIcon32");
//
// MainForm
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(884, 606);
this.Controls.Add(this.topToolStrip);
this.Controls.Add(this.bodyPanel);
this.DoubleBuffered = true;
this.HelpButton = true;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimumSize = new System.Drawing.Size(715, 250);
this.Name = "MainForm";
this.Text = "Universal Remote Console";
this.Load += new System.EventHandler(this.Form1_Load);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.MainForm_DragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.MainForm_DragEnter);
this.topToolStrip.ResumeLayout(false);
this.topToolStrip.PerformLayout();
this.cmsGraph.ResumeLayout(false);
this.logPanel.ResumeLayout(false);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.tabControlTop.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.logChart)).EndInit();
this.contextMenuHistoryChart.ResumeLayout(false);
this.tabFullLog.ResumeLayout(false);
this.contextMenuTabs.ResumeLayout(false);
this.contextMenuTabs.PerformLayout();
this.tabPage1.ResumeLayout(false);
this.panelHelp.ResumeLayout(false);
this.tabPageMidi.ResumeLayout(false);
this.commandPanel.ResumeLayout(false);
this.commandPanel.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.bottomPanel.ResumeLayout(false);
this.bottomPanel.PerformLayout();
this.bodyPanel.ResumeLayout(false);
this.bodyPanel.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel logPanel;
private System.Windows.Forms.RichTextBox fullLogConsole;
private System.Windows.Forms.Panel commandPanel;
private System.Windows.Forms.TextBox editInput;
private System.Windows.Forms.ImageList imgList;
private System.Windows.Forms.ContextMenuStrip contextMenuTabs;
private System.Windows.Forms.ToolStripMenuItem actionSelectAll;
private System.Windows.Forms.ToolStripMenuItem actionCopy;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem actionClear;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.TabControl tabControlFilters;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.ContextMenuStrip cmsGraph;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.Panel bottomPanel;
private System.Windows.Forms.ToolStripStatusLabel statusLabelConnected;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel2;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.ToolStripStatusLabel labelSeparator;
private System.Windows.Forms.ToolStripStatusLabel forceRightAlignment;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel3;
private System.Windows.Forms.ToolStripStatusLabel statusLabelTarget;
private System.Windows.Forms.ToolStripStatusLabel statusConnectedImg;
private System.Windows.Forms.ToolStripStatusLabel statusLabelIp;
private System.Windows.Forms.Panel bodyPanel;
private System.Windows.Forms.TabControl tabControlTop;
private System.Windows.Forms.TabPage tabFullLog;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.DataVisualization.Charting.Chart logChart;
private System.Windows.Forms.ContextMenuStrip contextMenuHistoryChart;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripMenuItem historyChartClear;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem actionClearAll;
private System.Windows.Forms.ToolStripStatusLabel statusLabelFilters;
private System.Windows.Forms.ToolStripStatusLabel filtersTextStatus;
private System.Windows.Forms.ToolStripStatusLabel statusMenuLabel;
private System.Windows.Forms.ToolStripStatusLabel menuStatusText;
private System.Windows.Forms.ToolStripMenuItem historyChartViewMenu;
private System.Windows.Forms.ImageList imgList32;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.Panel panelHelp;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripMenuItem actionEditFiltersFile;
private System.Windows.Forms.ToolStripTextBox lalala2;
private System.Windows.Forms.ToolStripTextBox lalala;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel4;
private System.Windows.Forms.ToolStripStatusLabel statusLabelMode;
private System.Windows.Forms.ToolStrip topToolStrip;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel5;
private System.Windows.Forms.ToolStripStatusLabel statusLabelMidi;
private System.Windows.Forms.TabPage tabPageMidi;
private System.Windows.Forms.ListView lvMidiLog;
private System.Windows.Forms.ColumnHeader cHNum;
private System.Windows.Forms.ColumnHeader cHLog;
private System.Windows.Forms.ColumnHeader cHChannel;
private System.Windows.Forms.ColumnHeader chMode;
private System.Windows.Forms.ColumnHeader chCode;
private System.Windows.Forms.ColumnHeader chVelocity;
private System.Windows.Forms.Label label1;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,149 +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.
*
*/
namespace RemoteConsole
{
partial class FormAbout
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.rtbMidi = new System.Windows.Forms.RichTextBox();
this.label4 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// panel1
//
this.panel1.BackgroundImage = global::RemoteConsole.Properties.Resources.fractal;
this.panel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.panel1.Location = new System.Drawing.Point(1, 2);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(228, 147);
this.panel1.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.SystemColors.HotTrack;
this.label1.Location = new System.Drawing.Point(12, 152);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(199, 17);
this.label1.TabIndex = 1;
this.label1.Text = "Universal Remote Console";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(107, 178);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(109, 13);
this.label3.TabIndex = 3;
this.label3.Text = "Author: Dario Sancho";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(12, 178);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(94, 13);
this.label2.TabIndex = 4;
this.label2.Text = "(c) Crytek 2014";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// rtbMidi
//
this.rtbMidi.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.rtbMidi.BackColor = System.Drawing.SystemColors.Control;
this.rtbMidi.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.rtbMidi.Location = new System.Drawing.Point(15, 231);
this.rtbMidi.Name = "rtbMidi";
this.rtbMidi.ReadOnly = true;
this.rtbMidi.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None;
this.rtbMidi.Size = new System.Drawing.Size(201, 57);
this.rtbMidi.TabIndex = 5;
this.rtbMidi.TabStop = false;
this.rtbMidi.Text = "The Midi code is based on Tom Lokovic\'s [https://code.google.com/p/midi-dot-net/]" +
" project, adapted by Ramon Villadomat and Dario Sancho.";
this.rtbMidi.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.rtbMidi_LinkClicked);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.Location = new System.Drawing.Point(62, 210);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(92, 13);
this.label4.TabIndex = 6;
this.label4.Text = "Acknoledgements";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// FormAbout
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(228, 300);
this.Controls.Add(this.label4);
this.Controls.Add(this.rtbMidi);
this.Controls.Add(this.label2);
this.Controls.Add(this.label3);
this.Controls.Add(this.label1);
this.Controls.Add(this.panel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "FormAbout";
this.Text = "About";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormAbout_FormClosing);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.RichTextBox rtbMidi;
private System.Windows.Forms.Label label4;
}
}
@@ -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.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RemoteConsole
{
public partial class FormAbout : Form
{
public FormAbout()
{
InitializeComponent();
rtbMidi.SelectAll();
rtbMidi.SelectionAlignment = HorizontalAlignment.Center;
}
private void FormAbout_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
private void rtbMidi_LinkClicked(object sender, LinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(e.LinkText);
}
}
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,77 +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.
*
*/
namespace RemoteConsole
{
partial class FormButtons
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lvToggles = new System.Windows.Forms.ListView();
this.SuspendLayout();
//
// lvToggles
//
this.lvToggles.CheckBoxes = true;
this.lvToggles.Dock = System.Windows.Forms.DockStyle.Fill;
this.lvToggles.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvToggles.Location = new System.Drawing.Point(0, 0);
this.lvToggles.MultiSelect = false;
this.lvToggles.Name = "lvToggles";
this.lvToggles.Size = new System.Drawing.Size(283, 354);
this.lvToggles.TabIndex = 3;
this.lvToggles.UseCompatibleStateImageBehavior = false;
this.lvToggles.View = System.Windows.Forms.View.Details;
this.lvToggles.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lvToggles_ItemChecked);
//
// FormButtons
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(283, 354);
this.Controls.Add(this.lvToggles);
this.Name = "FormButtons";
this.Text = "Toggle Buttons";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormButtons_FormClosing_1);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView lvToggles;
}
}
@@ -1,142 +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.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
namespace RemoteConsole
{
public partial class FormButtons : Form
{
DelSendCommandToTarget delSendCommand;
public FormButtons()
{
InitializeComponent();
}
public void SetEntries(List<ParamsFileInfo.CEntry> entries, DelSendCommandToTarget callabck)
{
delSendCommand = null;
lvToggles.Clear();
lvToggles.FullRowSelect = true;
lvToggles.GridLines = true;
lvToggles.Location = new System.Drawing.Point(3, 3);
lvToggles.UseCompatibleStateImageBehavior = false;
lvToggles.View = System.Windows.Forms.View.Details;
// lvToggles.ContextMenuStrip = contextMenu;
ColumnHeader columnHeader0 = new ColumnHeader();
columnHeader0.Text = "Toggle";
columnHeader0.Width = -1;
lvToggles.Columns.AddRange(new ColumnHeader[] { columnHeader0 });
lvToggles.Width = -1; // autosize it to the width of the widest element in the column
foreach (var entry in entries)
{
if (entry.ToggleParams != null)
{
// Populate List View
ListViewItem lvi = new ListViewItem(entry.Name);
lvi.Tag = entry;
//lvi.ToolTipText =
ListViewGroup group;
int gIdx = GetGroupIndex(entry.ToggleParams.GroupName);
if (gIdx < 0)
{
group = new ListViewGroup(entry.ToggleParams.GroupName);
lvToggles.Groups.Add(group);
}
else
{
group = lvToggles.Groups[gIdx];
}
group.Items.Add(lvi);
lvToggles.Items.Add(lvi);
}
}
lvToggles.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
lvToggles.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
delSendCommand = callabck;
}
// ------------------------------------------------------------------------
private void SendSliderCommand(ParamsFileInfo.CEntry entry, int value)
{
if (delSendCommand != null)
{
ParamsFileInfo.CEntryTag tag = entry.GenerateEntryTag();
// Send commands
tag.ModCmds = new List<string>();
for (int k = 0; k < tag.Entry.Data.Count; ++k)
{
string s = value.ToString();
tag.ModCmds.Add(tag.Entry.Data[k].Replace("#", s));
}
delSendCommand(tag);
}
}
// ------------------------------------------------------------------------
private int GetGroupIndex(string name)
{
int index = -1;
for (int i = 0; i < lvToggles.Groups.Count; ++i)
{
ListViewGroup g = lvToggles.Groups[i];
if (g.Header == name)
{
index = i;
break;
}
}
return index;
}
// ------------------------------------------------------------------------
private void lvToggles_ItemChecked(object sender, ItemCheckedEventArgs e)
{
if (e.Item.Tag != null && delSendCommand != null)
{
ParamsFileInfo.CEntry entry = (ParamsFileInfo.CEntry)e.Item.Tag;
if (entry.ToggleParams != null)
{
int value = e.Item.Checked ? entry.ToggleParams.On : entry.ToggleParams.Off;
SendSliderCommand(entry, value);
}
}
}
// ------------------------------------------------------------------------
private void FormButtons_FormClosing_1(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
}
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,164 +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.
*
*/
namespace RemoteConsole
{
partial class FormSettings
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.cbMode = new System.Windows.Forms.ComboBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.btEditFilters = new System.Windows.Forms.Button();
this.btEditMenus = new System.Windows.Forms.Button();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.cbDebugMidi = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.cbMode);
this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(229, 53);
this.groupBox1.TabIndex = 1;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Operation Mode";
//
// cbMode
//
this.cbMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbMode.FormattingEnabled = true;
this.cbMode.Location = new System.Drawing.Point(6, 19);
this.cbMode.Name = "cbMode";
this.cbMode.Size = new System.Drawing.Size(207, 21);
this.cbMode.TabIndex = 0;
this.cbMode.SelectedIndexChanged += new System.EventHandler(this.cbMode_SelectedIndexChanged);
//
// groupBox2
//
this.groupBox2.Controls.Add(this.btEditFilters);
this.groupBox2.Controls.Add(this.btEditMenus);
this.groupBox2.Location = new System.Drawing.Point(12, 71);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(229, 61);
this.groupBox2.TabIndex = 2;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Edit Configuration Files";
//
// btEditFilters
//
this.btEditFilters.FlatAppearance.BorderSize = 2;
this.btEditFilters.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btEditFilters.Location = new System.Drawing.Point(138, 20);
this.btEditFilters.Name = "btEditFilters";
this.btEditFilters.Size = new System.Drawing.Size(75, 35);
this.btEditFilters.TabIndex = 1;
this.btEditFilters.Text = "Filters";
this.btEditFilters.UseVisualStyleBackColor = true;
this.btEditFilters.Click += new System.EventHandler(this.btEditFilters_Click);
//
// btEditMenus
//
this.btEditMenus.FlatAppearance.BorderSize = 2;
this.btEditMenus.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btEditMenus.Location = new System.Drawing.Point(6, 20);
this.btEditMenus.Name = "btEditMenus";
this.btEditMenus.Size = new System.Drawing.Size(75, 35);
this.btEditMenus.TabIndex = 0;
this.btEditMenus.Text = "Menus";
this.btEditMenus.UseVisualStyleBackColor = true;
this.btEditMenus.Click += new System.EventHandler(this.btEditMenus_Click);
//
// groupBox3
//
this.groupBox3.Controls.Add(this.cbDebugMidi);
this.groupBox3.Location = new System.Drawing.Point(18, 139);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(200, 51);
this.groupBox3.TabIndex = 3;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Debug";
//
// cbDebugMidi
//
this.cbDebugMidi.AutoSize = true;
this.cbDebugMidi.Location = new System.Drawing.Point(7, 20);
this.cbDebugMidi.Name = "cbDebugMidi";
this.cbDebugMidi.Size = new System.Drawing.Size(45, 17);
this.cbDebugMidi.TabIndex = 0;
this.cbDebugMidi.Text = "Midi";
this.cbDebugMidi.UseVisualStyleBackColor = true;
this.cbDebugMidi.CheckedChanged += new System.EventHandler(this.cbDebugMidi_CheckedChanged);
//
// FormSettings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(251, 202);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.HelpButton = true;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FormSettings";
this.Text = "Settings";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormSettings_FormClosing);
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox cbMode;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button btEditFilters;
private System.Windows.Forms.Button btEditMenus;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.CheckBox cbDebugMidi;
}
}
@@ -1,110 +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.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RemoteConsole
{
public partial class FormSettings : Form
{
private DelSettingsChange delSettingsChange;
private CSettings settings = new CSettings();
public FormSettings()
{
InitializeComponent();
cbMode.Items.Clear();
cbMode.Items.Add("Online [Full]");
cbMode.Items.Add("Online [Commands Only]");
cbMode.Items.Add("Online [Files Only]");
cbMode.SelectedIndex = 0;
cbMode.Select();
}
public void SetSettingsChangeDelegate(DelSettingsChange callback)
{
delSettingsChange = callback;
}
private void WarnAboutMissingFiles(string fileName)
{
string message =
"Missing file: " + fileName + "\nPlease please the file in the given directory (same folder as the executable).";
const string caption = "Missing Config File!";
var result = MessageBox.Show(message, caption,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
private void btEditMenus_Click(object sender, EventArgs e)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(Common.MenusFileFullPath);
if (fileInfo.Exists == true)
{
System.Diagnostics.Process.Start(/*"notepad.exe", */Common.MenusFileFullPath);
}
else
{
WarnAboutMissingFiles(Common.MenusFileFullPath);
}
}
private void btEditFilters_Click(object sender, EventArgs e)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(Common.FiltersFileFullPath);
if (fileInfo.Exists == true)
{
System.Diagnostics.Process.Start(/*"notepad.exe", */Common.FiltersFileFullPath);
}
else
{
WarnAboutMissingFiles(Common.FiltersFileFullPath);
}
}
private void FormSettings_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
private void cbMode_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateSettings();
if (delSettingsChange != null) delSettingsChange(settings);
}
private void cbDebugMidi_CheckedChanged(object sender, EventArgs e)
{
UpdateSettings();
if (delSettingsChange != null) delSettingsChange(settings);
}
private void UpdateSettings()
{
settings.DebugMidi = cbDebugMidi.Checked;
if (cbMode.SelectedIndex >= 0)
settings.Mode = (CSettings.EMode)cbMode.SelectedIndex;
}
}
}
@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -1,218 +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.
*
*/
namespace RemoteConsole
{
partial class FormSliders
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormSliders));
this.panelSlider = new System.Windows.Forms.Panel();
this.layoutPanelSlider = new System.Windows.Forms.TableLayoutPanel();
this.trackBar1 = new System.Windows.Forms.TrackBar();
this.lblMax = new System.Windows.Forms.Label();
this.lblMin = new System.Windows.Forms.Label();
this.lblName = new System.Windows.Forms.Label();
this.rtbValue = new System.Windows.Forms.TextBox();
this.lvSliders = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.rtbDescription = new System.Windows.Forms.RichTextBox();
this.label1 = new System.Windows.Forms.Label();
this.panelSlider.SuspendLayout();
this.layoutPanelSlider.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
this.SuspendLayout();
//
// panelSlider
//
this.panelSlider.Controls.Add(this.layoutPanelSlider);
this.panelSlider.Location = new System.Drawing.Point(251, 12);
this.panelSlider.Name = "panelSlider";
this.panelSlider.Size = new System.Drawing.Size(300, 90);
this.panelSlider.TabIndex = 0;
//
// layoutPanelSlider
//
this.layoutPanelSlider.ColumnCount = 3;
this.layoutPanelSlider.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.layoutPanelSlider.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 70F));
this.layoutPanelSlider.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.layoutPanelSlider.Controls.Add(this.trackBar1, 1, 1);
this.layoutPanelSlider.Controls.Add(this.lblMax, 2, 1);
this.layoutPanelSlider.Controls.Add(this.lblMin, 0, 1);
this.layoutPanelSlider.Controls.Add(this.lblName, 1, 0);
this.layoutPanelSlider.Controls.Add(this.rtbValue, 1, 2);
this.layoutPanelSlider.Dock = System.Windows.Forms.DockStyle.Fill;
this.layoutPanelSlider.Location = new System.Drawing.Point(0, 0);
this.layoutPanelSlider.Name = "layoutPanelSlider";
this.layoutPanelSlider.RowCount = 3;
this.layoutPanelSlider.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.layoutPanelSlider.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.layoutPanelSlider.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.layoutPanelSlider.Size = new System.Drawing.Size(300, 90);
this.layoutPanelSlider.TabIndex = 1;
//
// trackBar1
//
this.trackBar1.Dock = System.Windows.Forms.DockStyle.Fill;
this.trackBar1.Location = new System.Drawing.Point(48, 23);
this.trackBar1.Name = "trackBar1";
this.trackBar1.Size = new System.Drawing.Size(204, 34);
this.trackBar1.TabIndex = 0;
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);
//
// lblMax
//
this.lblMax.AutoSize = true;
this.lblMax.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblMax.Location = new System.Drawing.Point(258, 20);
this.lblMax.Name = "lblMax";
this.lblMax.Size = new System.Drawing.Size(39, 40);
this.lblMax.TabIndex = 2;
this.lblMax.Text = "1";
this.lblMax.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lblMin
//
this.lblMin.AutoSize = true;
this.lblMin.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblMin.Location = new System.Drawing.Point(3, 20);
this.lblMin.Name = "lblMin";
this.lblMin.Size = new System.Drawing.Size(39, 40);
this.lblMin.TabIndex = 1;
this.lblMin.Text = "0";
this.lblMin.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lblName
//
this.lblName.AutoSize = true;
this.lblName.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblName.Location = new System.Drawing.Point(48, 0);
this.lblName.Name = "lblName";
this.lblName.Size = new System.Drawing.Size(204, 20);
this.lblName.TabIndex = 3;
this.lblName.Text = "Slider Name";
this.lblName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// rtbValue
//
this.rtbValue.Dock = System.Windows.Forms.DockStyle.Fill;
this.rtbValue.Location = new System.Drawing.Point(48, 63);
this.rtbValue.Name = "rtbValue";
this.rtbValue.Size = new System.Drawing.Size(204, 20);
this.rtbValue.TabIndex = 4;
this.rtbValue.Text = "0";
this.rtbValue.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.rtbValue.KeyUp += new System.Windows.Forms.KeyEventHandler(this.rtbValue_KeyUp);
//
// lvSliders
//
this.lvSliders.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1});
this.lvSliders.FullRowSelect = true;
this.lvSliders.GridLines = true;
this.lvSliders.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvSliders.HideSelection = false;
this.lvSliders.Location = new System.Drawing.Point(13, 12);
this.lvSliders.Name = "lvSliders";
this.lvSliders.Size = new System.Drawing.Size(213, 184);
this.lvSliders.TabIndex = 1;
this.lvSliders.UseCompatibleStateImageBehavior = false;
this.lvSliders.View = System.Windows.Forms.View.Details;
this.lvSliders.SelectedIndexChanged += new System.EventHandler(this.lvSliders_SelectedIndexChanged);
//
// columnHeader1
//
this.columnHeader1.Text = "Select a Slider";
//
// rtbDescription
//
this.rtbDescription.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.rtbDescription.Enabled = false;
this.rtbDescription.Location = new System.Drawing.Point(251, 136);
this.rtbDescription.Name = "rtbDescription";
this.rtbDescription.Size = new System.Drawing.Size(300, 60);
this.rtbDescription.TabIndex = 2;
this.rtbDescription.Text = "";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(372, 120);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(59, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Commands";
//
// FormSliders
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(561, 208);
this.Controls.Add(this.label1);
this.Controls.Add(this.rtbDescription);
this.Controls.Add(this.lvSliders);
this.Controls.Add(this.panelSlider);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FormSliders";
this.Text = "Sliders";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormSliders_FormClosing);
this.panelSlider.ResumeLayout(false);
this.layoutPanelSlider.ResumeLayout(false);
this.layoutPanelSlider.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panelSlider;
private System.Windows.Forms.TableLayoutPanel layoutPanelSlider;
private System.Windows.Forms.TrackBar trackBar1;
private System.Windows.Forms.Label lblMax;
private System.Windows.Forms.Label lblMin;
private System.Windows.Forms.Label lblName;
private System.Windows.Forms.TextBox rtbValue;
private System.Windows.Forms.ListView lvSliders;
private System.Windows.Forms.RichTextBox rtbDescription;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.Label label1;
}
}
@@ -1,193 +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.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RemoteConsole
{
public partial class FormSliders : Form
{
DelSendCommandToTarget delSendCommand;
public FormSliders()
{
InitializeComponent();
lvSliders.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
lvSliders.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}
public void SetEntries(List<ParamsFileInfo.CEntry> entries, DelSendCommandToTarget callabck)
{
lvSliders.Items.Clear();
foreach (var entry in entries)
{
// Populate List View
ListViewItem lvi = new ListViewItem(entry.Name);
//lvi.BackColor = System.Drawing.Color.Aqua;
lvi.Tag = entry;
lvSliders.Items.Add(lvi);
}
// select first element
if (entries.Count > 0)
{
lvSliders.SelectedIndices.Add(0);
lvSliders.Select();
}
delSendCommand = callabck;
}
private void SendSliderCommand(bool forceTextBoxValue = false)
{
if (delSendCommand != null)
{
ListView.SelectedListViewItemCollection items = this.lvSliders.SelectedItems;
if (items.Count > 0)
{
ParamsFileInfo.CEntry entry = (ParamsFileInfo.CEntry)items[0].Tag;
ParamsFileInfo.CEntryTag tag = entry.GenerateEntryTag();
// Update UI
if (forceTextBoxValue)
{
entry.SliderParams.CurrentValue = float.Parse(rtbValue.Text);
entry.SliderParams.CurrentValue = Common.Clamp(entry.SliderParams.CurrentValue, entry.SliderParams.Min, entry.SliderParams.Max);
}
else
{
float v = CalculateSliderValue(entry);
entry.SliderParams.CurrentValue = Common.Clamp(v, entry.SliderParams.Min, entry.SliderParams.Max);
}
rtbValue.Text = entry.SliderParams.CurrentValue.ToString();
UpdateSliderPosition();
// Send commands
tag.ModCmds = new List<string>();
for (int k = 0; k < tag.Entry.Data.Count; ++k)
{
string s = rtbValue.Text.Replace(',', '.');
tag.ModCmds.Add(tag.Entry.Data[k].Replace("#", s));
}
delSendCommand(tag);
}
}
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
// Send command
SendSliderCommand();
}
private void UpdateSliderPosition()
{
}
private void lvSliders_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection items = this.lvSliders.SelectedItems;
if (items.Count > 0)
{
ParamsFileInfo.CEntry entry = (ParamsFileInfo.CEntry)items[0].Tag;
setSliderUi(entry);
foreach (var s in entry.Data)
rtbDescription.Text = s;
}
}
private float CalculateSliderValue(ParamsFileInfo.CEntry entry)
{
if (entry.SliderParams != null)
{
if (entry.SliderParams.ForceInt)
{
return (float)trackBar1.Value;
}
else
{
float t = (float)(trackBar1.Value) / 1000f;
float v = entry.SliderParams.Lerp(t);
return v;
}
}
return 0f;
}
private void setSliderUi(ParamsFileInfo.CEntry entry)
{
lblName.Text = entry.Name;
if (entry.SliderParams != null)
{
if (entry.SliderParams.ForceInt)
{
trackBar1.TickFrequency = (int)(entry.SliderParams.Delta);
trackBar1.Minimum = (int)entry.SliderParams.Min;
trackBar1.Maximum = (int)entry.SliderParams.Max;
trackBar1.Value = (int)entry.SliderParams.CurrentValue;
}
else
{
float size = entry.SliderParams.Max - entry.SliderParams.Min;
float w = size > 0f ? size / (entry.SliderParams.Delta > 0 ? entry.SliderParams.Delta : 1f) : 1f;
trackBar1.TickFrequency = (int)(1000f / w);
trackBar1.Minimum = 0;
trackBar1.Maximum = 1000;
int v = (int)(1000f * (entry.SliderParams.CurrentValue - entry.SliderParams.Min) / size);
trackBar1.Value = Common.Clamp(v, 0, 1000);
}
lblMin.Text = entry.SliderParams.Min.ToString();
lblMax.Text = entry.SliderParams.Max.ToString();
rtbValue.Text = entry.SliderParams.CurrentValue.ToString();
}
}
private void rtbValue_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
float v = float.Parse(rtbValue.Text, System.Globalization.CultureInfo.InvariantCulture);
SendSliderCommand(true);
}
catch (System.Exception)
{
}
}
else if (e.KeyCode == Keys.Escape)
{
((RichTextBox)sender).Undo();
}
}
private void FormSliders_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,178 +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.
// Description : Stores and splits the log string into types message warning error
// Functionality to adds the latest log to a textbox and to query some info about the log
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
namespace RemoteConsole
{
class LogBuffer
{
private System.Text.StringBuilder sb = new System.Text.StringBuilder(4048);
private List<Color> selColors = new List<Color>();
private List<int> selIndex = new List<int>();
private List<Color> colors = new List<Color>();
private System.Text.StringBuilder sbSingleLine = new System.Text.StringBuilder(256);
private List<string> linesMessage = new List<string>();
private List<string> linesError = new List<string>();
private List<string> linesWarning = new List<string>();
public LogBuffer()
{
colors.Add(Color.Black);
colors.Add(Color.White);
colors.Add(Color.Blue);
colors.Add(Color.Green);
colors.Add(Color.Red);
colors.Add(Color.LightBlue);
colors.Add(Color.Yellow);
colors.Add(Color.Magenta);
colors.Add(Color.Orange);
colors.Add(Color.LightGray);
}
public void clear()
{
sb.Clear();
linesMessage.Clear();
linesError.Clear();
linesWarning.Clear();
}
public List<string> GetLinesInBuffer(EMessageType msgType)
{
switch (msgType)
{
case EMessageType.eMT_Message: return linesMessage;
case EMessageType.eMT_Warning: return linesWarning;
case EMessageType.eMT_Error: return linesError;
}
return null;
}
public int GetNumLinesInBuffer()
{
return linesMessage.Count + linesWarning.Count + linesError.Count;
}
public bool IsBufferEmpty()
{
return sb.Length == 0;
}
public bool IsTagInBuffer(string tag)
{
return sb.ToString().Contains(tag);
}
public void addLine(string line, Color color, EMessageType msgType)
{
sbSingleLine.Clear();
// color input
selColors.Add(color);
int len = sb.Length;
selIndex.Add(len);
// append new line
int f = 0;
for (int i = 0; i < line.Length && line[i] != '\0'; ++i)
{
if (line[i] == '$' && i + 1 < line.Length && line[i + 1] >= '0' && line[i + 1] <= '9')
{
int colIdx = int.Parse(line[i + 1].ToString());
selColors.Add(colors[colIdx]);
selIndex.Add(len + i - f);
f += 2;
i++;
}
else
{
sb.Append(line.Substring(i, 1));
sbSingleLine.Append(line.Substring(i, 1));
}
}
sb.Append("\n");
sbSingleLine.Append("\n");
switch (msgType)
{
case EMessageType.eMT_Message: linesMessage.Add(sbSingleLine.ToString()); break;
case EMessageType.eMT_Warning: linesWarning.Add(sbSingleLine.ToString()); break;
case EMessageType.eMT_Error: linesError.Add(sbSingleLine.ToString()); break;
default: linesMessage.Add(sbSingleLine.ToString()); break;
}
}
[DllImport("user32.dll")]
public static extern int SendMessage(System.IntPtr hWnd, System.Int32 wMsg, bool wParam, System.Int32 lParam);
private const int WM_SETREDRAW = 11;
public void addToTextBox(System.Windows.Forms.RichTextBox b, bool bClear = true, bool bFlatColor = false)
{
if (sb.Length > 0)
{
if (!Common.IsRunningOnMono())
SendMessage(b.Handle, WM_SETREDRAW, false, 0);
int selStart = b.SelectionStart;
int selLen = b.SelectionLength;
int length = b.TextLength;
int lenAdd = sb.Length;
string text = sb.ToString();
b.AppendText(text);
if (bClear)
{
sb.Clear();
}
selIndex.Add(lenAdd);
if (bFlatColor == true)
{
b.SelectionColor = Color.White;
}
else
{
for (int i = 0; i < selColors.Count; ++i)
{
b.Select(length + selIndex[i], selIndex[i + 1] - selIndex[i]);
b.SelectionColor = selColors[i];
}
}
if (selStart == length)
{
selStart = length + lenAdd;
selLen = 0;
}
b.Select(selStart, selLen);
b.ScrollToCaret();
selColors.Clear();
selIndex.Clear();
if (!Common.IsRunningOnMono())
SendMessage(b.Handle, WM_SETREDRAW, true, 0);
b.Refresh();
}
}
}
}
@@ -1,103 +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.
namespace RemoteConsole
{
class LogChart
{
private System.Windows.Forms.DataVisualization.Charting.Chart chart;
public LogChart(System.Windows.Forms.DataVisualization.Charting.Chart theChart)
{
chart = theChart;
if (chart != null)
{
chart.ChartAreas.Clear();
chart.ChartAreas.Add("Full");
}
}
public System.Windows.Forms.DataVisualization.Charting.SeriesCollection GetSeries() { return chart.Series; }
public void ClearSeries() { if (chart!=null) chart.Series.Clear(); }
public void AddSeries(string seriesName)
{
if (chart != null && !Common.IsRunningOnMono())
{
chart.Series.Add(seriesName);
for (var i = 0; i < LogFilterManager.SingleFilterHistory.BufferSize; ++i)
{
chart.Series[seriesName].Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint(i, 0));
}
chart.Series[seriesName].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
chart.ChartAreas["Full"].AxisY.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount;
chart.ChartAreas["Full"].AxisY.Maximum = 10;
chart.ChartAreas["Full"].AxisY.Minimum = 0;
chart.ChartAreas["Full"].AxisX.Minimum = 0;
}
}
public void ClearData()
{
if (chart != null)
{
foreach (var serie in chart.Series)
{
for (var i = 0; i < LogFilterManager.SingleFilterHistory.BufferSize; ++i)
{
serie.Points[i].SetValueY(0);
}
}
}
}
public void Refresh()
{
if (chart != null) chart.Refresh();
}
public void SetYValue(string seriesName, int pointIndex, float value)
{
if (chart != null && !Common.IsRunningOnMono()) chart.Series[seriesName].Points[pointIndex].SetValueY(value);
}
public void ShowHideLegend(string seriesName, bool isChecked)
{
if (chart != null)
{
if (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Control)
{
// Select All
foreach (var s in chart.Series)
{
s.IsVisibleInLegend = s.Enabled = isChecked;
}
}
else if (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Shift)
{
// Toggle All
foreach (var s in chart.Series)
{
s.IsVisibleInLegend = s.Enabled = !isChecked;
}
}
// Toggle Selected
var selected = chart.Series[seriesName];
if (selected != null)
{
selected.IsVisibleInLegend = selected.Enabled = isChecked;
}
}
}
}
}
@@ -1,143 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Control to display the log data it could be either a LISTVIEW or a RICHTEXTBOX
using System.Windows.Forms;
namespace RemoteConsole
{
class LogDisplayControl
{
private ListView lv = null;
private RichTextBox rtb = null;
public enum EType
{
eT_ListView = 0,
eT_RichTextBox
}
public Control GetControl()
{
if (lv != null)
return lv;
else
return rtb;
}
public LogDisplayControl(EType controlType, ContextMenuStrip contextMenu, int textColor)
{
if (controlType == EType.eT_ListView)
{
lv = new ListView();
lv.Dock = System.Windows.Forms.DockStyle.Fill;
lv.FullRowSelect = true;
lv.GridLines = true;
lv.Location = new System.Drawing.Point(3, 3);
lv.Size = new System.Drawing.Size(797, 118);
lv.UseCompatibleStateImageBehavior = false;
lv.View = System.Windows.Forms.View.Details;
lv.ContextMenuStrip = contextMenu;
lv.Columns.Add("I");
lv.Columns.Add("Description");
lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
lv.ForeColor = System.Drawing.Color.FromArgb(textColor);
}
else
{
rtb = new RichTextBox();
rtb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
rtb.BackColor = System.Drawing.SystemColors.WindowText;
rtb.ContextMenuStrip = contextMenu;
rtb.ForeColor = System.Drawing.Color.Silver;
rtb.Location = new System.Drawing.Point(3, 6);
rtb.ReadOnly = true;
rtb.Size = new System.Drawing.Size(700, 233);
rtb.TabIndex = 1;
rtb.Text = "";
rtb.ScrollBars = RichTextBoxScrollBars.Both;
rtb.Dock = DockStyle.Fill;
rtb.ForeColor = System.Drawing.Color.FromArgb(textColor);
}
}
public int GetNumItems()
{
return (lv != null) ? lv.Items.Count : rtb.Lines.Length;
}
public void AddLine(string line)
{
if (lv != null)
{
ListViewItem lvi = new ListViewItem(lv.Items.Count.ToString());
lvi.SubItems.Add(line);
lv.Items.Add(lvi);
lv.EnsureVisible(lv.Items.Count - 1);
}
else
{
rtb.AppendText(line);
}
}
public void Clear()
{
if (lv != null)
lv.Items.Clear();
else if (rtb != null)
rtb.Clear();
}
public void Copy()
{
if (lv != null)
{
Clipboard.Clear();
string fullText = "";
foreach (ListViewItem item in lv.SelectedItems)
{
fullText += item.SubItems[1].Text;// +Environment.NewLine;
}
Clipboard.SetText(fullText);
}
else if (rtb != null)
{
rtb.Copy();
}
}
public void SelectAll()
{
if (lv != null)
{
foreach (ListViewItem item in lv.Items)
{
item.Selected = true;
}
}
else
{
rtb.SelectAll();
}
}
}
}
@@ -1,381 +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.
*
*/
/*
* Project: Universal Remote Console
* File: LogFilterManager.cs
* Author: Dario Sancho (2014)
*
* Description:
* Manages the display of log data
* Adds log display controls to the Main Form, keeps statistic data buffer,
* handles context menus on display log controls
*/
#define USE_LIST_BOX
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace RemoteConsole
{
class LogFilterManager
{
public const string TotalCountSeriesName = "Total";
private const string strFullLogTabName = "Full Log";
public History StatsHistory { get; private set; }
private TabPage fullLogTabPtr;
private List<LogData> customFilters;
private List<LogData> standardFilters;
public enum EContextMenuAction
{
eCM_SelectAll = 0,
eCM_Clear,
eCM_Copy,
eCM_ClearAllLogs,
}
class LogData
{
public TabPage TabPtr { get; private set; }
public LogDisplayControl ControlPtr { get; private set; }
public FilterData Data { get; private set; }
public int LineCountPerTick { get; private set; }
public LogData(LogDisplayControl ctrl, TabPage tab, FilterData data)
{
TabPtr = tab;
ControlPtr = ctrl;
Data = data;
LineCountPerTick = 0;
}
public void AddLine(string line)
{
ControlPtr.AddLine(line);
++LineCountPerTick;
}
public void ClearPerTickCounter() { LineCountPerTick = 0; }
public void UpdateFilterLabel()
{
TabPtr.Text = Data.Label + "[" + ControlPtr.GetNumItems() + "]";
}
public void Clear()
{
ControlPtr.Clear();
LineCountPerTick = 0;
UpdateFilterLabel();
}
}
public class SingleFilterHistory
{
public const int BufferSize = 600;
public string Name { get; private set; }
public int Back { get; private set; }
public int Front { get; private set; }
public List<float> Buffer { get; private set; }
public int Iterator { get; private set; }
public SingleFilterHistory(string name)
{
Name = name;
Buffer = new List<float>(BufferSize);
for (int i = 0; i < BufferSize; ++i)
{
Buffer.Add(0);
}
Back = 0; Front = 0;
}
public void Clear()
{
Back = Front = 0;
ResetIterator();
for (int i = 0; i < BufferSize; ++i)
Buffer[i] = 0;
}
public void Add(float value)
{
Buffer[Front++] = value;
if (Front >= BufferSize)
{
Front = 0;
}
if (Front <= Back)
Back = Front + 1;
if (Back >= BufferSize)
Back = 0;
}
public void ResetIterator() { Iterator = Back; }
public bool NextIterator()
{
if (++Iterator >= BufferSize)
Iterator = 0;
return (Iterator != Front);
}
}
public class History
{
public List<SingleFilterHistory> Data { get; private set; }
public History() { Data = new List<SingleFilterHistory>(); }
public void Clear()
{
foreach (var h in Data)
h.Clear();
}
public void AddSeries(string name)
{
if (GetSeries(name) == null)
{
Data.Add(new SingleFilterHistory(name));
}
}
public SingleFilterHistory GetSeries(string name)
{
string lowerName = name.ToLower();
foreach (var h in Data)
{
if (h.Name.ToLower() == lowerName)
{
return h;
}
}
return null;
}
}
public LogFilterManager()
{
customFilters = new List<LogData>();
standardFilters = new List<LogData>();
StatsHistory = new History();
}
public void SetFullLogTab(TabPage tp) { fullLogTabPtr = tp; }
public void Clear()
{
customFilters.Clear();
standardFilters.Clear();
StatsHistory.Data.Clear();
}
public void ClearHistory()
{
StatsHistory.Clear();
}
public void AddFilter(FilterData data, TabControl targetTabControl, ContextMenuStrip contextMenuStrip)
{
// Create Tab
TabPage tab = new TabPage(data.Label);
// Create Control to display the log info
#if USE_LIST_BOX
LogDisplayControl ctl = new LogDisplayControl(LogDisplayControl.EType.eT_ListView, contextMenuStrip, data.TextColor);
#else
LogDisplayControl ctl = new LogDisplayControl(LogDisplayControl.EType.eT_RichTextBox, contextMenuStrip, data.TextColor);
#endif
// Add tab to tab controller
tab.Controls.Add(ctl.GetControl());
targetTabControl.TabPages.Add(tab);
targetTabControl.Dock = DockStyle.Fill;
// keep track
LogData logData = new LogData(ctl, tab, data);
if (data.MsgType == EMessageType.eMT_Message)
customFilters.Add(logData);
else
standardFilters.Add(logData);
}
public bool UpdateTabs(LogBuffer buffer, ref List<FilterData.Exec> execList)
{
bool res = false;
int totalCount = 0;
if (buffer.IsBufferEmpty() == false)
{
// Full Log Tab
fullLogTabPtr.Text = "Full Log [" + ((RichTextBox)fullLogTabPtr.Controls[0]).Lines.Length.ToString() + "]";
// Standard Tabs
foreach (LogData filter in standardFilters)
{
List<string> lines = buffer.GetLinesInBuffer(filter.Data.MsgType);
foreach (string line in lines)
{
filter.AddLine(line);
totalCount++;
res = true;
}
filter.UpdateFilterLabel();
}
// Custom Tabs
List<string> lines1 = buffer.GetLinesInBuffer(EMessageType.eMT_Message);
foreach (LogData filter in customFilters)
{
foreach (string line in lines1)
{
bool found = false;
// Check Label
if (line.Contains(filter.Data.Tag))
{
found = true;
}
// Check RegExp
else if (filter.Data.RegExpText != null && filter.Data.RegExpText.Length > 0)
{
Regex rgx = new Regex(filter.Data.RegExpText);
if (rgx.IsMatch(line))
{
found = true;
}
}
if (found)
{
filter.AddLine(line);
totalCount++;
res = true;
// Apply Exec Commands
if (filter.Data.Execute != null)
{
foreach (FilterData.Exec e in filter.Data.Execute)
{
if (e.Type != FilterData.Exec.EExecType.eET_None)
execList.Add(e);
}
}
}
}
filter.UpdateFilterLabel();
}
}
foreach (var f in standardFilters)
{
if (f.Data.Label != null)
StatsHistory.GetSeries(f.Data.Label).Add(f.LineCountPerTick);
f.ClearPerTickCounter();
}
foreach (var f in customFilters)
{
if (f.Data.Label != null)
StatsHistory.GetSeries(f.Data.Label).Add(f.LineCountPerTick);
f.ClearPerTickCounter();
}
var h = StatsHistory.GetSeries(LogFilterManager.TotalCountSeriesName);
if (h != null)
h.Add(totalCount);
return res;
}
private void ExecuteContextMenu_InternalFullLog(Control ctrl, EContextMenuAction action)
{
switch (action)
{
case EContextMenuAction.eCM_SelectAll:
((RichTextBox)ctrl).SelectAll();
return;
case EContextMenuAction.eCM_Clear:
((RichTextBox)ctrl).Clear();
return;
case EContextMenuAction.eCM_Copy:
((RichTextBox)ctrl).Copy();
return;
}
}
private void ExecuteContextMenu_Internal(LogData data, EContextMenuAction action)
{
switch (action)
{
case EContextMenuAction.eCM_SelectAll:
data.ControlPtr.SelectAll();
return;
case EContextMenuAction.eCM_Clear:
data.Clear();
return;
case EContextMenuAction.eCM_Copy:
data.ControlPtr.Copy();
return;
}
}
public void ExecuteContextMenu(Control ctrl, EContextMenuAction action)
{
if (action == EContextMenuAction.eCM_ClearAllLogs)
{
((RichTextBox)fullLogTabPtr.Controls[0]).Clear();
fullLogTabPtr.Text = strFullLogTabName + " [0]";
foreach (LogData data in customFilters)
data.Clear();
foreach (LogData data in standardFilters)
data.Clear();
return;
}
if (fullLogTabPtr.Controls[0] == ctrl)
{
ExecuteContextMenu_InternalFullLog(ctrl, action);
fullLogTabPtr.Text = strFullLogTabName + " [0]";
return;
}
foreach (LogData data in customFilters)
{
Control c = data.ControlPtr.GetControl();
if ( c== ctrl)
{
ExecuteContextMenu_Internal(data, action);
return;
}
}
foreach (LogData data in standardFilters)
{
Control c = data.ControlPtr.GetControl();
if (c == ctrl)
{
ExecuteContextMenu_Internal(data, action);
return;
}
}
}
}
}
@@ -1,72 +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.
*
*/
// Copyright (c) 2009, Tom Lokovic
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
namespace Midi
{
/// <summary>
/// Common base class for input and output devices.
/// </summary>
/// This base class exists mainly so that input and output devices can both go into the same
/// kinds of MidiMessages.
public class DeviceBase
{
/// <summary>
/// Protected constructor.
/// </summary>
/// <param name="name">The name of this device.</param>
protected DeviceBase(string name)
{
Name = name;
}
/// <summary>
/// The name of this device.
/// </summary>
public string Name { get; private set; }
}
/// <summary>
/// Exception thrown when an operation on a MIDI device cannot be satisfied.
/// </summary>
public class DeviceException : System.ApplicationException
{
/// <summary>
/// Constructs exception with a specific error message.
/// </summary>
/// <param name="message"></param>
public DeviceException(string message) { }
}
}
@@ -1,385 +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.
*
*/
// Copyright (c) 2009, Tom Lokovic
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections.ObjectModel;
using System.Text;
namespace Midi
{
/// <summary>
/// A MIDI input device.
/// </summary>
public class InputDevice : DeviceBase
{
#region Delegates
/// <summary>
/// Delegate called when an input device receives a midi message.
/// </summary>
public delegate void MidiHandler(MidiMessage msg);
#endregion
#region Events
/// <summary>
/// Event called when an input device receives a midi message.
/// </summary>
public event MidiHandler MidiTrigger;
/// <summary>
/// Removes all event handlers from the input events on this device.
/// </summary>
public void RemoveAllEventHandlers()
{
MidiTrigger = null;
}
#endregion
#region Public Methods and Properties
/// <summary>
/// List of input devices installed on this system.
/// </summary>
public static ReadOnlyCollection<InputDevice> InstalledDevices
{
get
{
lock (staticLock)
{
if (installedDevices == null)
{
installedDevices = MakeDeviceList();
}
return new ReadOnlyCollection<InputDevice>(installedDevices);
}
}
}
/// <summary>
/// True if this device has been successfully opened.
/// </summary>
public bool IsOpen
{
get
{
if (isInsideInputHandler)
{
return true;
}
lock (this)
{
return isOpen;
}
}
}
/// <summary>
/// Opens this input device.
/// </summary>
/// <exception cref="InvalidOperationException">The device is already open.</exception>
/// <exception cref="DeviceException">The device cannot be opened.</exception>
/// <remarks>Note that Open() establishes a connection to the device, but no messages will
/// be received until <see cref="StartReceiving"/> is called.</remarks>
public void Open()
{
if (isInsideInputHandler)
{
throw new InvalidOperationException("Device is open.");
}
lock (this)
{
CheckNotOpen();
CheckReturnCode(Win32API.midiInOpen(out handle, deviceId,
inputCallbackDelegate, (UIntPtr)0));
isOpen = true;
}
}
/// <summary>
/// Closes this input device.
/// </summary>
/// <exception cref="InvalidOperationException">The device is not open or is still
/// receiving.</exception>
/// <exception cref="DeviceException">The device cannot be closed.</exception>
public void Close()
{
if (isInsideInputHandler)
{
throw new InvalidOperationException("Device is receiving.");
}
lock (this)
{
CheckOpen();
CheckReturnCode(Win32API.midiInClose(handle));
isOpen = false;
}
}
/// <summary>
/// True if this device is receiving messages.
/// </summary>
public bool IsReceiving
{
get
{
if (isInsideInputHandler)
{
return true;
}
lock (this)
{
return isReceiving;
}
}
}
/// <summary>
/// Starts this input device receiving messages.
/// </summary>
public void StartReceiving()//Clock clock)
{
if (isInsideInputHandler)
{
throw new InvalidOperationException("Device is receiving.");
}
lock (this)
{
CheckOpen();
CheckNotReceiving();
CheckReturnCode(Win32API.midiInStart(handle));
isReceiving = true;
//this.clock = clock;
}
}
/// <summary>
/// Stops this input device from receiving messages.
/// </summary>
/// <remarks>
/// <para>This method waits for all in-progress input event handlers to finish, and then
/// joins (shuts down) the background thread that was created in
/// <see cref="StartReceiving"/>. Thus, when this function returns you can be sure that no
/// more event handlers will be invoked.</para>
/// <para>It is illegal to call this method from an input event handler (ie, from the
/// background thread), and doing so throws an exception. If an event handler really needs
/// to call this method, consider using BeginInvoke to schedule it on another thread.</para>
/// </remarks>
/// <exception cref="InvalidOperationException">The device is not open; is not receiving;
/// or called from within an event handler (ie, from the background thread).</exception>
/// <exception cref="DeviceException">The device cannot start receiving.</exception>
public void StopReceiving()
{
if (isInsideInputHandler)
{
throw new InvalidOperationException(
"Can't call StopReceiving() from inside an input handler.");
}
lock (this)
{
CheckReceiving();
CheckReturnCode(Win32API.midiInStop(handle));
//clock = null;
isReceiving = false;
}
}
#endregion
#region Private Methods
/// <summary>
/// Makes sure rc is MidiWin32Wrapper.MMSYSERR_NOERROR. If not, throws an exception with an
/// appropriate error message.
/// </summary>
/// <param name="rc"></param>
private static void CheckReturnCode(Win32API.MMRESULT rc)
{
if (rc != Win32API.MMRESULT.MMSYSERR_NOERROR)
{
StringBuilder errorMsg = new StringBuilder(128);
rc = Win32API.midiInGetErrorText(rc, errorMsg);
if (rc != Win32API.MMRESULT.MMSYSERR_NOERROR)
{
throw new DeviceException("no error details");
}
throw new DeviceException(errorMsg.ToString());
}
}
/// <summary>
/// Throws a MidiDeviceException if this device is not open.
/// </summary>
private void CheckOpen()
{
if (!isOpen)
{
throw new InvalidOperationException("Device is not open.");
}
}
/// <summary>
/// Throws a MidiDeviceException if this device is open.
/// </summary>
private void CheckNotOpen()
{
if (isOpen)
{
throw new InvalidOperationException("Device is open.");
}
}
/// <summary>
/// Throws a MidiDeviceException if this device is not receiving.
/// </summary>
private void CheckReceiving()
{
if (!isReceiving)
{
throw new DeviceException("device not receiving");
}
}
/// <summary>
/// Throws a MidiDeviceException if this device is receiving.
/// </summary>
private void CheckNotReceiving()
{
if (isReceiving)
{
throw new DeviceException("device receiving");
}
}
/// <summary>
/// Private Constructor, only called by the getter for the InstalledDevices property.
/// </summary>
/// <param name="deviceId">Position of this device in the list of all devices.</param>
/// <param name="caps">Win32 Struct with device metadata</param>
private InputDevice(UIntPtr deviceId, Win32API.MIDIINCAPS caps)
: base(caps.szPname)
{
this.deviceId = deviceId;
this.caps = caps;
this.inputCallbackDelegate = new Win32API.MidiInProc(this.InputCallback);
this.isOpen = false;
//this.clock = null;
}
/// <summary>
/// Private method for constructing the array of MidiInputDevices by calling the Win32 api.
/// </summary>
/// <returns></returns>
private static InputDevice[] MakeDeviceList()
{
#if __MonoCS__
return new InputDevice[0];
#else
uint inDevs = Win32API.midiInGetNumDevs();
InputDevice[] result = new InputDevice[inDevs];
for (uint deviceId = 0; deviceId < inDevs; deviceId++)
{
Win32API.MIDIINCAPS caps = new Win32API.MIDIINCAPS();
Win32API.midiInGetDevCaps((UIntPtr)deviceId, out caps);
result[deviceId] = new InputDevice((UIntPtr)deviceId, caps);
}
return result;
#endif
}
/// <summary>
/// The input callback for midiOutOpen.
/// </summary>
private void InputCallback(Win32API.HMIDIIN hMidiIn, Win32API.MidiInMessage wMsg,
UIntPtr dwInstance, UIntPtr dwParam1, UIntPtr dwParam2)
{
isInsideInputHandler = true;
try
{
if (wMsg == Win32API.MidiInMessage.MIM_DATA)
{
int channel;
int mode;
int code;
int velocity;
UInt32 win32Timestamp;
if (MidiTrigger != null)
{
ShortMsg.DecodeMsg(dwParam1, dwParam2, out channel, out mode, out code, out velocity, out win32Timestamp);
MidiTrigger(new MidiMessage(this, channel, mode, code, velocity));
}
}
}
finally
{
isInsideInputHandler = false;
}
}
#endregion
#region Private Fields
// Access to the global state is guarded by lock(staticLock).
private static Object staticLock = new Object();
private static InputDevice[] installedDevices = null;
// These fields initialized in the constructor never change after construction,
// so they don't need to be guarded by a lock. We keep a reference to the
// callback delegate because we pass it to unmanaged code (midiInOpen) and unmanaged code
// cannot prevent the garbage collector from collecting the delegate.
private UIntPtr deviceId;
private Win32API.MIDIINCAPS caps;
private Win32API.MidiInProc inputCallbackDelegate;
// Access to the Open/Close state is guarded by lock(this).
private bool isOpen;
private bool isReceiving;
//private Clock clock;
private Win32API.HMIDIIN handle;
/// <summary>
/// Thread-local, set to true when called by an input handler, false in all other threads.
/// </summary>
[ThreadStatic]
static bool isInsideInputHandler = false;
#endregion
}
}
@@ -1,101 +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.
*
*/
// Copyright (c) 2009, Tom Lokovic
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
using System;
namespace Midi
{
/// <summary>
/// Base class for messages relevant to a specific device.
/// </summary>
public abstract class DeviceMessage
{
/// <summary>
/// Protected constructor.
/// </summary>
protected DeviceMessage(DeviceBase device)//, float time) : base(time)
{
if (device == null)
{
throw new ArgumentNullException("device");
}
Device = device;
}
/// <summary>
/// The device from which this message originated, or for which it is destined.
/// </summary>
public DeviceBase Device { get; private set; }
}
/// <summary>
/// Note On message.
/// </summary>
public class MidiMessage : DeviceMessage
{
/// <summary>
/// Constructs a Midi message.
/// </summary>
public MidiMessage(DeviceBase device, int channel, int mode, int code, int velocity)
:base(device)
{
Channel = channel;
Mode = mode;
Code = code;
Velocity = velocity;
}
/// <summary>
/// Channel.
/// </summary>
public int Channel { get; private set; }
/// <summary>
/// Mode.
/// </summary>
public int Mode { get; private set; }
/// <summary>
/// Code.
/// </summary>
public int Code { get; private set; }
/// <summary>
/// Velocity.
/// </summary>
public int Velocity { get; private set; }
}
}
@@ -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.
*
*/
// Copyright (c) 2009, Tom Lokovic
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections.Generic;
namespace Midi
{
/// <summary>
/// Utility functions for encoding and decoding short messages.
/// </summary>
static class ShortMsg
{
/// <summary>
/// Decodes a Note On short message.
/// </summary>
public static void DecodeMsg(UIntPtr dwParam1, UIntPtr dwParam2,
out int channel, out int mode, out int code, out int velocity, out UInt32 timestamp)
{
channel = (int)dwParam1 & 0x0f;
mode = ((int)dwParam1 & 0xf0) >> 4;
code = ((int)dwParam1 & 0xff00) >> 8;
velocity = ((int)dwParam1 & 0xff0000) >> 16;
timestamp = (UInt32)dwParam2;
}
/// <summary>
/// Encodes a Note On short message.
/// </summary>
public static UInt32 EncodeMsg(int channel, int code, int velocity)
{
return (UInt32)(0x90 | (channel) | (code << 8) | (velocity << 16));
}
}
}
@@ -1,428 +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.
*
*/
// Copyright (c) 2009, Tom Lokovic
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Midi
{
/// <summary>
/// C# wrappers for the Win32 MIDI API.
/// </summary>
/// Because .NET does not provide MIDI support itself, in C# we must use P/Invoke to wrap the
/// Win32 API. That API consists of the MMSystem.h C header and the winmm.dll library. The API
/// is described in detail here: http://msdn.microsoft.com/en-us/library/ms712733(VS.85).aspx.
/// The P/Invoke interop mechanism is described here:
/// http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx.
///
/// This file covers the subset of the MIDI protocol needed to manage input and output devices
/// and send and receive Note On/Off, Control Change, Pitch Bend and Program Change messages.
/// Other portions of the MIDI protocol (such as sysex events) are supported in the Win32 API
/// but are not wrapped here.
///
/// Some of the C functions are not typesafe when wrapped, so those wrappers are made private
/// and typesafe variants are provided.
static class Win32API
{
#region Constants
// The following constants come from MMSystem.h.
/// <summary>
/// Max length of a manufacturer name in the Win32 API.
/// </summary>
public const UInt32 MAXPNAMELEN = 32;
/// <summary>
/// Status type returned from most functions in the Win32 API.
/// </summary>
public enum MMRESULT : uint
{
// General return codes.
MMSYSERR_BASE = 0,
MMSYSERR_NOERROR = MMSYSERR_BASE + 0,
MMSYSERR_ERROR = MMSYSERR_BASE + 1,
MMSYSERR_BADDEVICEID = MMSYSERR_BASE + 2,
MMSYSERR_NOTENABLED = MMSYSERR_BASE + 3,
MMSYSERR_ALLOCATED = MMSYSERR_BASE + 4,
MMSYSERR_INVALHANDLE = MMSYSERR_BASE + 5,
MMSYSERR_NODRIVER = MMSYSERR_BASE + 6,
MMSYSERR_NOMEM = MMSYSERR_BASE + 7,
MMSYSERR_NOTSUPPORTED = MMSYSERR_BASE + 8,
MMSYSERR_BADERRNUM = MMSYSERR_BASE + 9,
MMSYSERR_INVALFLAG = MMSYSERR_BASE + 10,
MMSYSERR_INVALPARAM = MMSYSERR_BASE + 11,
MMSYSERR_HANDLEBUSY = MMSYSERR_BASE + 12,
MMSYSERR_INVALIDALIAS = MMSYSERR_BASE + 13,
MMSYSERR_BADDB = MMSYSERR_BASE + 14,
MMSYSERR_KEYNOTFOUND = MMSYSERR_BASE + 15,
MMSYSERR_READERROR = MMSYSERR_BASE + 16,
MMSYSERR_WRITEERROR = MMSYSERR_BASE + 17,
MMSYSERR_DELETEERROR = MMSYSERR_BASE + 18,
MMSYSERR_VALNOTFOUND = MMSYSERR_BASE + 19,
MMSYSERR_NODRIVERCB = MMSYSERR_BASE + 20,
MMSYSERR_MOREDATA = MMSYSERR_BASE + 21,
MMSYSERR_LASTERROR = MMSYSERR_BASE + 21,
// MIDI-specific return codes.
MIDIERR_BASE = 64,
MIDIERR_UNPREPARED = MIDIERR_BASE + 0,
MIDIERR_STILLPLAYING = MIDIERR_BASE + 1,
MIDIERR_NOMAP = MIDIERR_BASE + 2,
MIDIERR_NOTREADY = MIDIERR_BASE + 3,
MIDIERR_NODEVICE = MIDIERR_BASE + 4,
MIDIERR_INVALIDSETUP = MIDIERR_BASE + 5,
MIDIERR_BADOPENMODE = MIDIERR_BASE + 6,
MIDIERR_DONT_CONTINUE = MIDIERR_BASE + 7,
MIDIERR_LASTERROR = MIDIERR_BASE + 7
}
/// <summary>
/// Flags passed to midiInOpen() and midiOutOpen().
/// </summary>
public enum MidiOpenFlags : uint
{
CALLBACK_TYPEMASK = 0x70000,
CALLBACK_NULL = 0x00000,
CALLBACK_WINDOW = 0x10000,
CALLBACK_TASK = 0x20000,
CALLBACK_FUNCTION = 0x30000,
CALLBACK_THREAD = CALLBACK_TASK,
CALLBACK_EVENT = 0x50000,
MIDI_IO_STATUS = 0x00020
}
/// <summary>
/// Values for wTechnology field of MIDIOUTCAPS structure.
/// </summary>
public enum MidiDeviceType : ushort
{
MOD_MIDIPORT = 1,
MOD_SYNTH = 2,
MOD_SQSYNTH = 3,
MOD_FMSYNTH = 4,
MOD_MAPPER = 5,
MOD_WAVETABLE = 6,
MOD_SWSYNTH = 7
}
/// <summary>
/// Flags for dwSupport field of MIDIOUTCAPS structure.
/// </summary>
public enum MidiExtraFeatures : uint
{
MIDICAPS_VOLUME = 0x0001,
MIDICAPS_LRVOLUME = 0x0002,
MIDICAPS_CACHE = 0x0004,
MIDICAPS_STREAM = 0x0008
}
/// <summary>
/// "Midi Out Messages", passed to wMsg param of MidiOutProc.
/// </summary>
public enum MidiOutMessage : uint
{
MOM_OPEN = 0x3C7,
MOM_CLOSE = 0x3C8,
MOM_DONE = 0x3C9
}
/// <summary>
/// "Midi In Messages", passed to wMsg param of MidiInProc.
/// </summary>
public enum MidiInMessage : uint
{
MIM_OPEN = 0x3C1,
MIM_CLOSE = 0x3C2,
MIM_DATA = 0x3C3,
MIM_LONGDATA = 0x3C4,
MIM_ERROR = 0x3C5,
MIM_LONGERROR = 0x3C6,
MIM_MOREDATA = 0x3CC
}
#endregion
#region Handles
/// <summary>
/// Win32 handle for a MIDI output device.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct HMIDIOUT
{
public Int32 handle;
}
/// <summary>
/// Win32 handle for a MIDI input device.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct HMIDIIN
{
public Int32 handle;
}
#endregion
#region Structs
/// <summary>
/// Struct representing the capabilities of an output device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711619(VS.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct MIDIOUTCAPS
{
public UInt16 wMid;
public UInt16 wPid;
public UInt32 vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAXPNAMELEN)]
public string szPname;
public MidiDeviceType wTechnology;
public UInt16 wVoices;
public UInt16 wNotes;
public UInt16 wChannelMask;
public MidiExtraFeatures dwSupport;
}
/// <summary>
/// Struct representing the capabilities of an input device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711596(VS.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct MIDIINCAPS
{
public UInt16 wMid;
public UInt16 wPid;
public UInt32 vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAXPNAMELEN)]
public string szPname;
public UInt32 dwSupport;
}
#endregion
#region Functions for MIDI Output
/// <summary>
/// Returns the number of MIDI output devices on this system.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711627(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern UInt32 midiOutGetNumDevs();
/// <summary>
/// Fills in the capabilities struct for a specific output device.
/// </summary>
/// NOTE: This is adapted from the original Win32 function in order to make it typesafe.
///
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711621(VS.85).aspx
public static MMRESULT midiOutGetDevCaps(UIntPtr uDeviceID, out MIDIOUTCAPS caps)
{
return midiOutGetDevCaps(uDeviceID, out caps,
(UInt32)Marshal.SizeOf(typeof(MIDIOUTCAPS)));
}
/// <summary>
/// Callback invoked when a MIDI output device is opened, closed, or finished with a buffer.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711637(VS.85).aspx
public delegate void MidiOutProc(HMIDIOUT hmo, MidiOutMessage wMsg, UIntPtr dwInstance,
UIntPtr dwParam1, UIntPtr dwParam2);
/// <summary>
/// Opens a MIDI output device.
/// </summary>
/// NOTE: This is adapted from the original Win32 function in order to make it typesafe.
///
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711632(VS.85).aspx
public static MMRESULT midiOutOpen(out HMIDIOUT lphmo, UIntPtr uDeviceID,
MidiOutProc dwCallback, UIntPtr dwCallbackInstance)
{
return midiOutOpen(out lphmo, uDeviceID, dwCallback, dwCallbackInstance,
dwCallback == null ? MidiOpenFlags.CALLBACK_NULL : MidiOpenFlags.CALLBACK_FUNCTION);
}
/// <summary>
/// Turns off all notes and sustains on a MIDI output device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/dd798479(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiOutReset(HMIDIOUT hmo);
/// <summary>
/// Closes a MIDI output device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711620(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiOutClose(HMIDIOUT hmo);
/// <summary>
/// Sends a short MIDI message (anything but sysex or stream).
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711640(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiOutShortMsg(HMIDIOUT hmo, UInt32 dwMsg);
/// <summary>
/// Gets the error text for a return code related to an output device.
/// </summary>
/// NOTE: This is adapted from the original Win32 function in order to make it typesafe.
///
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711622(VS.85).aspx
public static MMRESULT midiOutGetErrorText(MMRESULT mmrError, StringBuilder lpText)
{
return midiOutGetErrorText(mmrError, lpText, (UInt32)lpText.Capacity);
}
#endregion
#region Functions for MIDI Input
/// <summary>
/// Returns the number of MIDI input devices on this system.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711608(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern UInt32 midiInGetNumDevs();
/// <summary>
/// Fills in the capabilities struct for a specific input device.
/// </summary>
/// NOTE: This is adapted from the original Win32 function in order to make it typesafe.
///
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711604(VS.85).aspx
public static MMRESULT midiInGetDevCaps(UIntPtr uDeviceID, out MIDIINCAPS caps)
{
return midiInGetDevCaps(uDeviceID, out caps,
(UInt32)Marshal.SizeOf(typeof(MIDIINCAPS)));
}
/// <summary>
/// Callback invoked when a MIDI event is received from an input device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711612(VS.85).aspx
public delegate void MidiInProc(HMIDIIN hMidiIn, MidiInMessage wMsg, UIntPtr dwInstance,
UIntPtr dwParam1, UIntPtr dwParam2);
/// <summary>
/// Opens a MIDI input device.
/// </summary>
/// NOTE: This is adapted from the original Win32 function in order to make it typesafe.
///
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711610(VS.85).aspx
public static MMRESULT midiInOpen(out HMIDIIN lphMidiIn, UIntPtr uDeviceID,
MidiInProc dwCallback, UIntPtr dwCallbackInstance)
{
return midiInOpen(out lphMidiIn, uDeviceID, dwCallback, dwCallbackInstance,
dwCallback == null ? MidiOpenFlags.CALLBACK_NULL : MidiOpenFlags.CALLBACK_FUNCTION);
}
/// <summary>
/// Starts input on a MIDI input device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711614(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiInStart(HMIDIIN hMidiIn);
/// <summary>
/// Stops input on a MIDI input device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711615(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiInStop(HMIDIIN hMidiIn);
/// <summary>
/// Resets input on a MIDI input device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711613(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiInReset(HMIDIIN hMidiIn);
/// <summary>
/// Closes a MIDI input device.
/// </summary>
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711602(VS.85).aspx
[DllImport("winmm.dll", SetLastError = true)]
public static extern MMRESULT midiInClose(HMIDIIN hMidiIn);
/// <summary>
/// Gets the error text for a return code related to an input device.
/// </summary>
/// NOTE: This is adapted from the original Win32 function in order to make it typesafe.
///
/// Win32 docs: http://msdn.microsoft.com/en-us/library/ms711605(VS.85).aspx
public static MMRESULT midiInGetErrorText(MMRESULT mmrError, StringBuilder lpText)
{
return midiInGetErrorText(mmrError, lpText, (UInt32)lpText.Capacity);
}
#endregion
#region Non-Typesafe Bindings
// The bindings in this section are not typesafe, so we make them private and privide
// typesafe variants above.
[DllImport("winmm.dll", SetLastError = true)]
private static extern MMRESULT midiOutGetDevCaps(UIntPtr uDeviceID, out MIDIOUTCAPS caps,
UInt32 cbMidiOutCaps);
[DllImport("winmm.dll", SetLastError = true)]
private static extern MMRESULT midiOutOpen(out HMIDIOUT lphmo, UIntPtr uDeviceID,
MidiOutProc dwCallback, UIntPtr dwCallbackInstance, MidiOpenFlags dwFlags);
[DllImport("winmm.dll", SetLastError = true)]
private static extern MMRESULT midiOutGetErrorText(MMRESULT mmrError, StringBuilder lpText,
UInt32 cchText);
[DllImport("winmm.dll", SetLastError = true)]
private static extern MMRESULT midiInGetDevCaps(UIntPtr uDeviceID, out MIDIINCAPS caps,
UInt32 cbMidiInCaps);
[DllImport("winmm.dll", SetLastError = true)]
private static extern MMRESULT midiInOpen(out HMIDIIN lphMidiIn, UIntPtr uDeviceID,
MidiInProc dwCallback, UIntPtr dwCallbackInstance, MidiOpenFlags dwFlags);
[DllImport("winmm.dll", SetLastError = true)]
private static extern MMRESULT midiInGetErrorText(MMRESULT mmrError, StringBuilder lpText,
UInt32 cchText);
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More