diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h index 7ec1c785e5..ca1de2cdc1 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h @@ -99,6 +99,7 @@ namespace GradientSignal void SetupDependencies(); void GetSubImageData(); + float GetValueFromImageData(const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue) const; // ImageGradientRequestBus overrides... AZStd::string GetImageAssetPath() const override; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/ImageAsset.h b/Gems/GradientSignal/Code/Include/GradientSignal/ImageAsset.h index 500251d924..14920a2370 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/ImageAsset.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/ImageAsset.h @@ -62,6 +62,4 @@ namespace GradientSignal } }; - float GetValueFromImageAsset(AZStd::span imageData, const AZ::RHI::ImageDescriptor& imageDescriptor, const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue); - } // namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp index fe4c134ed2..ddbba771d7 100644 --- a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -226,6 +227,60 @@ namespace GradientSignal m_imageData = m_configuration.m_imageAsset->GetSubImageData(0, 0); } + float ImageGradientComponent::GetValueFromImageData(const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue) const + { + if (!m_imageData.empty()) + { + const AZ::RHI::ImageDescriptor& imageDescriptor = m_configuration.m_imageAsset->GetImageDescriptor(); + auto width = imageDescriptor.m_size.m_width; + auto height = imageDescriptor.m_size.m_height; + + if (width > 0 && height > 0) + { + // When "rasterizing" from uvs, a range of 0-1 has slightly different meanings depending on the sampler state. + // For repeating states (Unbounded/None, Repeat), a uv value of 1 should wrap around back to our 0th pixel. + // For clamping states (Clamp to Zero, Clamp to Edge), a uv value of 1 should point to the last pixel. + + // We assume here that the code handling sampler states has handled this for us in the clamping cases + // by reducing our uv by a small delta value such that anything that wants the last pixel has a value + // just slightly less than 1. + + // Keeping that in mind, we scale our uv from 0-1 to 0-image size inclusive. So a 4-pixel image will scale + // uv values of 0-1 to 0-4, not 0-3 as you might expect. This is because we want the following range mappings: + // [0 - 1/4) = pixel 0 + // [1/4 - 1/2) = pixel 1 + // [1/2 - 3/4) = pixel 2 + // [3/4 - 1) = pixel 3 + // [1 - 1 1/4) = pixel 0 + // ... + + // Also, based on our tiling settings, we extend the size of our image virtually by a factor of tilingX and tilingY. + // A 16x16 pixel image and tilingX = tilingY = 1 maps the uv range of 0-1 to 0-16 pixels. + // A 16x16 pixel image and tilingX = tilingY = 1.5 maps the uv range of 0-1 to 0-24 pixels. + + const AZ::Vector3 tiledDimensions((width * tilingX), + (height * tilingY), + 0.0f); + + // Convert from uv space back to pixel space + AZ::Vector3 pixelLookup = (uvw * tiledDimensions); + + // UVs outside the 0-1 range are treated as infinitely tiling, so that we behave the same as the + // other gradient generators. As mentioned above, if clamping is desired, we expect it to be applied + // outside of this function. + auto x = aznumeric_cast(pixelLookup.GetX()) % width; + auto y = aznumeric_cast(pixelLookup.GetY()) % height; + + // Flip the y because images are stored in reverse of our world axes + y = (height - 1) - y; + + return AZ::RPI::GetImageDataPixelValue(m_imageData, imageDescriptor, x, y); + } + } + + return defaultValue; + } + void ImageGradientComponent::Activate() { // This will immediately call OnGradientTransformChanged and initialize m_gradientTransform. @@ -325,8 +380,8 @@ namespace GradientSignal if (!wasPointRejected) { - return GetValueFromImageAsset( - m_imageData, m_configuration.m_imageAsset->GetImageDescriptor(), uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f); + return GetValueFromImageData( + uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f); } } @@ -358,8 +413,8 @@ namespace GradientSignal if (!wasPointRejected) { - outValues[index] = GetValueFromImageAsset( - m_imageData, m_configuration.m_imageAsset->GetImageDescriptor(), uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f); + outValues[index] = GetValueFromImageData( + uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f); } else { diff --git a/Gems/GradientSignal/Code/Source/Editor/EditorImageBuilderComponent.cpp b/Gems/GradientSignal/Code/Source/Editor/EditorImageBuilderComponent.cpp deleted file mode 100644 index 062f34b644..0000000000 --- a/Gems/GradientSignal/Code/Source/Editor/EditorImageBuilderComponent.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EditorImageBuilderComponent.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace GradientSignal -{ - EditorImageBuilderPluginComponent::EditorImageBuilderPluginComponent() - { - // AZ Components should only initialize their members to null and empty in constructor - // after construction, they may be deserialized from file. - } - - EditorImageBuilderPluginComponent::~EditorImageBuilderPluginComponent() - { - } - - void EditorImageBuilderPluginComponent::Init() - { - } - - void EditorImageBuilderPluginComponent::Activate() - { - // Activate is where you'd perform registration with other objects and systems. - // Since we want to register our builder, we do that here: - AssetBuilderSDK::AssetBuilderDesc builderDescriptor; - builderDescriptor.m_name = "Gradient Image Builder"; - builderDescriptor.m_version = 1; - - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.tif", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.tiff", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.png", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.bmp", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.jpg", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.jpeg", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.tga", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.gif", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.bt", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - - builderDescriptor.m_busId = EditorImageBuilderWorker::GetUUID(); - builderDescriptor.m_createJobFunction = AZStd::bind(&EditorImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_processJobFunction = AZStd::bind(&EditorImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - m_imageBuilder.BusConnect(builderDescriptor.m_busId); - - EBUS_EVENT(AssetBuilderSDK::AssetBuilderBus, RegisterBuilderInformation, builderDescriptor); - } - - void EditorImageBuilderPluginComponent::Deactivate() - { - m_imageBuilder.BusDisconnect(); - } - - void EditorImageBuilderPluginComponent::Reflect(AZ::ReflectContext* context) - { - ImageSettings::Reflect(context); - - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class()->Version(0) - ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })); - } - } - - EditorImageBuilderWorker::EditorImageBuilderWorker() - { - } - - EditorImageBuilderWorker::~EditorImageBuilderWorker() - { - } - - void EditorImageBuilderWorker::ShutDown() - { - // it is important to note that this will be called on a different thread than your process job thread - m_isShuttingDown = true; - } - - // this happens early on in the file scanning pass - // this function should consistently always create the same jobs, and should do no checking whether the job is up to date or not - just be consistent. - void EditorImageBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) - { - AZStd::string fullPath; - AzFramework::StringFunc::Path::Join(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, true, true); - - // Check file for _GSI suffix/pattern which assumes processing will occur whether or not settings are provided - AZStd::string patternPath = fullPath; - AZStd::to_upper(patternPath.begin(), patternPath.end()); - bool patternMatched = patternPath.rfind("_GSI.") != AZStd::string::npos; - - // Determine if a settings file has been provided - AZStd::string settingsPath = fullPath + "." + s_gradientImageSettingsExtension; - bool settingsExist = AZ::IO::SystemFile::Exists(settingsPath.data()); - - // If the settings file is modified the image must be reprocessed - AssetBuilderSDK::SourceFileDependency sourceFileDependency; - sourceFileDependency.m_sourceFileDependencyPath = settingsPath; - response.m_sourceFileDependencyList.push_back(sourceFileDependency); - - // If no settings file was provided then skip the file, unless the file name matches the convenience pattern - if (!patternMatched && !settingsExist) - { - //do nothing if settings aren't provided - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - return; - } - - AZStd::unique_ptr settingsPtr; - if (settingsExist) - { - settingsPtr.reset(AZ::Utils::LoadObjectFromFile(settingsPath)); - } - - // If the settings file didn't load then skip the file, unless the file name matches the convenience pattern - if (!patternMatched && !settingsPtr) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Failed to create gradient image conversion job for %s.\nFailed loading settings %s.\n", fullPath.data(), settingsPath.data()); - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed; - return; - } - - // If settings loaded but processing is disabled then skip the file - if (settingsPtr && !settingsPtr->m_shouldProcess) - { - //do nothing if settings disable processing - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - return; - } - - // Get the extension of the file - AZStd::string ext; - AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.data(), ext, false); - AZStd::to_upper(ext.begin(), ext.end()); - - // We process the same file for all platforms - for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms) - { - AssetBuilderSDK::JobDescriptor descriptor; - descriptor.m_jobKey = ext + " Compile (Gradient Image)"; - descriptor.SetPlatformIdentifier(info.m_identifier.data()); - descriptor.m_critical = false; - response.m_createJobOutputs.push_back(descriptor); - } - - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - return; - } - - // later on, this function will be called for jobs that actually need doing. - // the request will contain the CreateJobResponse you constructed earlier, including any keys and values you placed into the hash table - void EditorImageBuilderWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) - { - // Before we begin, let's make sure we are not meant to abort. - AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId); - if (jobCancelListener.IsCancelled()) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Cancelled gradient image conversion job for %s.\nCancellation requested.\n", request.m_fullPath.data()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; - return; - } - - if (m_isShuttingDown) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Cancelled gradient image conversion job for %s.\nShutdown requested.\n", request.m_fullPath.data()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; - return; - } - - // Do conversion and get exported file's path - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Performing gradient image conversion job for %s\n", request.m_fullPath.data()); - - auto imageAsset = LoadImageFromPath(request.m_fullPath); - - if (!imageAsset) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Failed gradient image conversion job for %s.\nFailed loading source image %s.\n", request.m_fullPath.data(), request.m_fullPath.data()); - return; - } - - auto imageSettings = LoadImageSettingsFromPath(request.m_fullPath); - - if (!imageSettings) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Failed gradient image conversion job for %s.\nFailed loading source image %s.\n", request.m_fullPath.data(), request.m_fullPath.data()); - return; - } - - // ChannelMask is 8 bits, and the bits are assumed to be as follows: 0b0000ABGR - imageAsset = ConvertImage(*imageAsset, *imageSettings); - - //generate export file name - QDir dir(request.m_tempDirPath.data()); - if (!dir.exists()) - { - dir.mkpath("."); - } - - AZStd::string fileName; - AZStd::string outputPath; - AzFramework::StringFunc::Path::GetFileName(request.m_fullPath.data(), fileName); - fileName += AZStd::string(".") + s_gradientImageExtension; - AzFramework::StringFunc::Path::Join(request.m_tempDirPath.data(), fileName.data(), outputPath, true, true); - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Output path for gradient image conversion: %s\n", outputPath.data()); - - //save asset - if (!AZ::Utils::SaveObjectToFile(outputPath, AZ::DataStream::ST_XML, imageAsset.get())) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Failed gradient image conversion job for %s.\nFailed saving output file %s.\n", request.m_fullPath.data(), outputPath.data()); - return; - } - - // Report the image-import result - AssetBuilderSDK::JobProduct jobProduct; - if(!AssetBuilderSDK::OutputObject(imageAsset.get(), outputPath, azrtti_typeid(), 2, jobProduct)) - { - AZ_Error(AssetBuilderSDK::ErrorWindow, false, "Failed to output product dependencies."); - return; - } - - response.m_outputProducts.push_back(jobProduct); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Completed gradient image conversion job for %s.\nSucceeded saving output file %s.\n", request.m_fullPath.data(), outputPath.data()); - } - - AZ::Uuid EditorImageBuilderWorker::GetUUID() - { - return AZ::Uuid::CreateString("{7520DF20-16CA-4CF6-A6DB-D96759A09EE4}"); - } - - static AZStd::unique_ptr AtomLoadImageFromPath(const AZStd::string& fullPath) - { - ImageProcessingAtom::IImageObjectPtr imageObject; - ImageProcessingAtom::ImageProcessingRequestBus::BroadcastResult(imageObject, &ImageProcessingAtom::ImageProcessingRequests::LoadImage, - fullPath); - - if (!imageObject) - { - return {}; - } - - //create a new image asset - auto imageAsset = AZStd::make_unique(); - - if (!imageAsset) - { - return {}; - } - - imageAsset->m_imageWidth = imageObject->GetWidth(0); - imageAsset->m_imageHeight = imageObject->GetHeight(0); - imageAsset->m_imageFormat = imageObject->GetPixelFormat(); - - AZ::u8* mem = nullptr; - AZ::u32 pitch = 0; - AZ::u32 mipBufferSize = imageObject->GetMipBufSize(0); - imageObject->GetImagePointer(0, mem, pitch); - - imageAsset->m_imageData = { mem, mem + mipBufferSize }; - - return imageAsset; - } - - AZStd::unique_ptr EditorImageBuilderWorker::LoadImageFromPath(const AZStd::string& fullPath) - { - return AtomLoadImageFromPath(fullPath); - } - - AZStd::unique_ptr EditorImageBuilderWorker::LoadImageSettingsFromPath(const AZStd::string& fullPath) - { - // Determine if a settings file has been provided - AZStd::string settingsPath = fullPath + "." + s_gradientImageSettingsExtension; - bool settingsExist = AZ::IO::SystemFile::Exists(settingsPath.data()); - - if (settingsExist) - { - return AZStd::unique_ptr{AZ::Utils::LoadObjectFromFile(settingsPath)}; - } - else - { - return AZStd::make_unique(); - } - } - -} // namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/Editor/EditorImageBuilderComponent.h b/Gems/GradientSignal/Code/Source/Editor/EditorImageBuilderComponent.h deleted file mode 100644 index 60fa985bf7..0000000000 --- a/Gems/GradientSignal/Code/Source/Editor/EditorImageBuilderComponent.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include -#include - -namespace GradientSignal -{ - class ImageAsset; - class ImageSettings; - - //! Builder to process images - class EditorImageBuilderWorker - : public AssetBuilderSDK::AssetBuilderCommandBus::Handler - { - public: - AZ_CLASS_ALLOCATOR(EditorImageBuilderWorker, AZ::SystemAllocator, 0); - - EditorImageBuilderWorker(); - ~EditorImageBuilderWorker(); - - //! Asset Builder Callback Functions - void CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response); - void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response); - - ////////////////////////////////////////////////////////////////////////// - //!AssetBuilderSDK::AssetBuilderCommandBus interface - void ShutDown() override; // if you get this you must fail all existing jobs and return. - ////////////////////////////////////////////////////////////////////////// - - static AZ::Uuid GetUUID(); - static AZStd::unique_ptr LoadImageFromPath(const AZStd::string& fullPath); - static AZStd::unique_ptr LoadImageSettingsFromPath(const AZStd::string& fullPath); - - private: - bool m_isShuttingDown = false; - }; - - //! EditorImageBuilderPluginComponent is to handle the lifecycle of ImageBuilder module. - class EditorImageBuilderPluginComponent - : public AZ::Component - { - public: - AZ_COMPONENT(EditorImageBuilderPluginComponent, "{BF60FBB2-E124-4CB9-91CD-E6E640424C99}"); - static void Reflect(AZ::ReflectContext* context); - - EditorImageBuilderPluginComponent(); // avoid initialization here. - - ////////////////////////////////////////////////////////////////////////// - // AZ::Component - virtual void Init(); // create objects, allocate memory and initialize yourself without reaching out to the outside world - virtual void Activate(); // reach out to the outside world and connect up to what you need to, register things, etc. - virtual void Deactivate(); // unregister things, disconnect from the outside world - ////////////////////////////////////////////////////////////////////////// - - virtual ~EditorImageBuilderPluginComponent(); // free memory an uninitialize yourself. - - private: - EditorImageBuilderWorker m_imageBuilder; - }; - -}// namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/Editor/EditorImageProcessingSystemComponent.cpp b/Gems/GradientSignal/Code/Source/Editor/EditorImageProcessingSystemComponent.cpp deleted file mode 100644 index e665d46468..0000000000 --- a/Gems/GradientSignal/Code/Source/Editor/EditorImageProcessingSystemComponent.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EditorImageProcessingSystemComponent.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// warning C4800: 'uint': forcing value to bool 'true' or 'false' (performance warning) -// warning C4251: 'QBrush::d': class 'QScopedPointer' needs to have dll-interface to be used by clients of class 'QBrush' -AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING -#include -#include - -namespace GradientSignal -{ - void EditorImageProcessingSystemComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(0) - ; - - if (auto editContext = serializeContext->GetEditContext()) - { - editContext->Class("EditorImageProcessingSystemComponent", "Handles adding gradient image setting context menus") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ; - } - } - } - - void EditorImageProcessingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) - { - services.push_back(AZ_CRC("GradientImageBuilderService", 0x00cea88a)); - } - - void EditorImageProcessingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) - { - services.push_back(AZ_CRC("GradientImageBuilderService", 0x00cea88a)); - } - - void EditorImageProcessingSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services) - { - (void)services; - } - - void EditorImageProcessingSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services) - { - (void)services; - } - - void EditorImageProcessingSystemComponent::Init() - { - - } - - void EditorImageProcessingSystemComponent::Activate() - { - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); - } - - void EditorImageProcessingSystemComponent::Deactivate() - { - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); - } - - void EditorImageProcessingSystemComponent::AddContextMenuActions(QWidget* /*caller*/, QMenu* menu, const AZStd::vector& entries) - { - // Register right click menu - using namespace AzToolsFramework::AssetBrowser; - auto entryIt = AZStd::find_if(entries.begin(), entries.end(), [](const AssetBrowserEntry* entry) - { - return entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source; - }); - - if (entryIt == entries.end()) - { - return; - } - - auto source = azrtti_cast(*entryIt); - if (!HandlesSource(source)) - { - return; - } - - AZStd::string settingsPath = source->GetFullPath() + "." + s_gradientImageSettingsExtension; - bool settingsExist = AZ::IO::SystemFile::Exists(settingsPath.data()); - - if(settingsExist) - { - menu->addAction("Edit Gradient Image Settings...", [settingsPath]() - { - bool result = false; - AZ::Data::AssetInfo assetInfo; - AZStd::string rootPath; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, settingsPath.data(), assetInfo, rootPath); - if (result) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset(assetInfo.m_assetId, AZ::Data::AssetLoadBehavior::Default); - AzToolsFramework::AssetEditor::AssetEditorRequestsBus::Broadcast(&AzToolsFramework::AssetEditor::AssetEditorRequests::OpenAssetEditor, asset); - } - }); - } - else - { - menu->addAction("Enable Gradient Image Settings", [settingsPath]() - { - GradientSignal::ImageSettings imageSettings; - AZ::Utils::SaveObjectToFile(settingsPath, AZ::DataStream::ST_XML, &imageSettings); - }); - } - } - - bool EditorImageProcessingSystemComponent::HandlesSource(const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry) const - { - AZStd::string targetExtension = entry->GetExtension(); - - return AZStd::wildcard_match("*.tif", targetExtension.data()) - || AZStd::wildcard_match("*.tiff", targetExtension.data()) - || AZStd::wildcard_match("*.png", targetExtension.data()) - || AZStd::wildcard_match("*.bmp", targetExtension.data()) - || AZStd::wildcard_match("*.jpg", targetExtension.data()) - || AZStd::wildcard_match("*.jpeg", targetExtension.data()) - || AZStd::wildcard_match("*.tga", targetExtension.data()) - || AZStd::wildcard_match("*.gif", targetExtension.data()); - } -} // namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/Editor/EditorImageProcessingSystemComponent.h b/Gems/GradientSignal/Code/Source/Editor/EditorImageProcessingSystemComponent.h deleted file mode 100644 index e8ec38a933..0000000000 --- a/Gems/GradientSignal/Code/Source/Editor/EditorImageProcessingSystemComponent.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include -#include - -namespace GradientSignal -{ - class EditorImageProcessingSystemComponent - : public AZ::Component - , protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler - { - public: - AZ_COMPONENT(EditorImageProcessingSystemComponent, "{3AF5AB01-161C-4762-A73F-BBDD2B878F6A}"); - - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services); - - protected: - - //////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Init() override; - void Activate() override; - void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler - void AddContextMenuActions(QWidget* /*caller*/, QMenu* menu, const AZStd::vector& entries) override; - //////////////////////////////////////////////////////////////////////// - - private: - bool HandlesSource(const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry) const; - }; -} // namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/GradientSignalEditorModule.cpp b/Gems/GradientSignal/Code/Source/GradientSignalEditorModule.cpp index a8b578737e..098261ba7f 100644 --- a/Gems/GradientSignal/Code/Source/GradientSignalEditorModule.cpp +++ b/Gems/GradientSignal/Code/Source/GradientSignalEditorModule.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -29,7 +28,6 @@ #include #include #include -#include namespace GradientSignal { @@ -37,13 +35,11 @@ namespace GradientSignal { m_descriptors.insert(m_descriptors.end(), { GradientSignalEditorSystemComponent::CreateDescriptor(), - EditorImageProcessingSystemComponent::CreateDescriptor(), EditorSurfaceAltitudeGradientComponent::CreateDescriptor(), EditorSmoothStepGradientComponent::CreateDescriptor(), EditorSurfaceSlopeGradientComponent::CreateDescriptor(), EditorMixedGradientComponent::CreateDescriptor(), - EditorImageBuilderPluginComponent::CreateDescriptor(), EditorImageGradientComponent::CreateDescriptor(), EditorConstantGradientComponent::CreateDescriptor(), EditorThresholdGradientComponent::CreateDescriptor(), @@ -66,7 +62,6 @@ namespace GradientSignal AZ::ComponentTypeList requiredComponents = GradientSignalModule::GetRequiredSystemComponents(); requiredComponents.push_back(azrtti_typeid()); - requiredComponents.push_back(azrtti_typeid()); return requiredComponents; } diff --git a/Gems/GradientSignal/Code/Source/ImageAsset.cpp b/Gems/GradientSignal/Code/Source/ImageAsset.cpp index 05ad13d193..a8b41df949 100644 --- a/Gems/GradientSignal/Code/Source/ImageAsset.cpp +++ b/Gems/GradientSignal/Code/Source/ImageAsset.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -77,57 +76,4 @@ namespace GradientSignal return true; } - - float GetValueFromImageAsset(AZStd::span imageData, const AZ::RHI::ImageDescriptor& imageDescriptor, const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue) - { - if (!imageData.empty()) - { - auto width = imageDescriptor.m_size.m_width; - auto height = imageDescriptor.m_size.m_height; - - if (width > 0 && height > 0) - { - // When "rasterizing" from uvs, a range of 0-1 has slightly different meanings depending on the sampler state. - // For repeating states (Unbounded/None, Repeat), a uv value of 1 should wrap around back to our 0th pixel. - // For clamping states (Clamp to Zero, Clamp to Edge), a uv value of 1 should point to the last pixel. - - // We assume here that the code handling sampler states has handled this for us in the clamping cases - // by reducing our uv by a small delta value such that anything that wants the last pixel has a value - // just slightly less than 1. - - // Keeping that in mind, we scale our uv from 0-1 to 0-image size inclusive. So a 4-pixel image will scale - // uv values of 0-1 to 0-4, not 0-3 as you might expect. This is because we want the following range mappings: - // [0 - 1/4) = pixel 0 - // [1/4 - 1/2) = pixel 1 - // [1/2 - 3/4) = pixel 2 - // [3/4 - 1) = pixel 3 - // [1 - 1 1/4) = pixel 0 - // ... - - // Also, based on our tiling settings, we extend the size of our image virtually by a factor of tilingX and tilingY. - // A 16x16 pixel image and tilingX = tilingY = 1 maps the uv range of 0-1 to 0-16 pixels. - // A 16x16 pixel image and tilingX = tilingY = 1.5 maps the uv range of 0-1 to 0-24 pixels. - - const AZ::Vector3 tiledDimensions((width * tilingX), - (height * tilingY), - 0.0f); - - // Convert from uv space back to pixel space - AZ::Vector3 pixelLookup = (uvw * tiledDimensions); - - // UVs outside the 0-1 range are treated as infinitely tiling, so that we behave the same as the - // other gradient generators. As mentioned above, if clamping is desired, we expect it to be applied - // outside of this function. - auto x = aznumeric_cast(pixelLookup.GetX()) % width; - auto y = aznumeric_cast(pixelLookup.GetY()) % height; - - // Flip the y because images are stored in reverse of our world axes - y = (height - 1) - y; - - return AZ::RPI::GetImageDataPixelValue(imageData, imageDescriptor, x, y); - } - } - - return defaultValue; - } } diff --git a/Gems/GradientSignal/Code/gradientsignal_editor_files.cmake b/Gems/GradientSignal/Code/gradientsignal_editor_files.cmake index b32e776b82..bde565bc69 100644 --- a/Gems/GradientSignal/Code/gradientsignal_editor_files.cmake +++ b/Gems/GradientSignal/Code/gradientsignal_editor_files.cmake @@ -15,8 +15,6 @@ set(FILES Source/UI/GradientPreviewDataWidget.h Source/UI/GradientPreviewWidget.cpp Source/UI/GradientPreviewWidget.h - Source/Editor/EditorImageProcessingSystemComponent.cpp - Source/Editor/EditorImageProcessingSystemComponent.h Source/Editor/EditorConstantGradientComponent.cpp Source/Editor/EditorConstantGradientComponent.h Source/Editor/EditorDitherGradientComponent.cpp @@ -25,8 +23,6 @@ set(FILES Source/Editor/EditorGradientSurfaceDataComponent.h Source/Editor/EditorGradientTransformComponent.cpp Source/Editor/EditorGradientTransformComponent.h - Source/Editor/EditorImageBuilderComponent.cpp - Source/Editor/EditorImageBuilderComponent.h Source/Editor/EditorImageGradientComponent.cpp Source/Editor/EditorImageGradientComponent.h Source/Editor/EditorInvertGradientComponent.cpp