Merge pull request #7679 from aws-lumberyard-dev/cgalvan/RemovedGradientImageBuilder

Removed unused Gradient Signal image builder and image processing component
monroegm-disable-blank-issue-2
Chris Galvan 4 years ago committed by GitHub
commit 3f2aa7470a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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;

@ -62,6 +62,4 @@ namespace GradientSignal
}
};
float GetValueFromImageAsset(AZStd::span<const uint8_t> imageData, const AZ::RHI::ImageDescriptor& imageDescriptor, const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue);
} // namespace GradientSignal

@ -8,6 +8,7 @@
#include <GradientSignal/Components/ImageGradientComponent.h>
#include <Atom/ImageProcessing/ImageProcessingDefines.h>
#include <Atom/RPI.Public/RPIUtils.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Asset/AssetSerializer.h>
#include <AzCore/Debug/Profiler.h>
@ -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<AZ::u32>(pixelLookup.GetX()) % width;
auto y = aznumeric_cast<AZ::u32>(pixelLookup.GetY()) % height;
// Flip the y because images are stored in reverse of our world axes
y = (height - 1) - y;
return AZ::RPI::GetImageDataPixelValue<float>(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
{

@ -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 <AssetBuilderSDK/SerializationDependencies.h>
#include <GradientSignal/ImageAsset.h>
#include <GradientSignal/ImageSettings.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Debug/Trace.h>
#include <AzCore/Interface/Interface.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <QImageReader>
#include <QDirIterator>
#include <GradientSignalSystemComponent.h>
#include <GradientSignal/GradientImageConversion.h>
#include <Atom/ImageProcessing/ImageObject.h>
#include <Atom/ImageProcessing/ImageProcessingBus.h>
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<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<EditorImageBuilderPluginComponent, AZ::Component>()->Version(0)
->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector<AZ::Crc32>({ 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<ImageSettings> settingsPtr;
if (settingsExist)
{
settingsPtr.reset(AZ::Utils::LoadObjectFromFile<ImageSettings>(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<ImageAsset>(), 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<ImageAsset> 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<ImageAsset>();
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<ImageAsset> EditorImageBuilderWorker::LoadImageFromPath(const AZStd::string& fullPath)
{
return AtomLoadImageFromPath(fullPath);
}
AZStd::unique_ptr<ImageSettings> 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<ImageSettings>{AZ::Utils::LoadObjectFromFile<ImageSettings>(settingsPath)};
}
else
{
return AZStd::make_unique<ImageSettings>();
}
}
} // namespace GradientSignal

@ -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 <AzCore/Component/Component.h>
#include <AssetBuilderSDK/AssetBuilderBusses.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
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<ImageAsset> LoadImageFromPath(const AZStd::string& fullPath);
static AZStd::unique_ptr<ImageSettings> 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

@ -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 <AzCore/Asset/AssetManager.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/string/wildcard.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
#include <GradientSignal/ImageSettings.h>
// warning C4800: 'uint': forcing value to bool 'true' or 'false' (performance warning)
// warning C4251: 'QBrush::d': class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush'
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
#include <QMenu>
AZ_POP_DISABLE_WARNING
#include <AzCore/IO/SystemFile.h>
#include <GradientSignalSystemComponent.h>
namespace GradientSignal
{
void EditorImageProcessingSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<EditorImageProcessingSystemComponent, AZ::Component>()
->Version(0)
;
if (auto editContext = serializeContext->GetEditContext())
{
editContext->Class<EditorImageProcessingSystemComponent>("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<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>& 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<SourceAssetBrowserEntry*>(*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<GradientSignal::ImageSettings> asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset<GradientSignal::ImageSettings>(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

@ -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 <AzCore/Component/Component.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
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<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>& entries) override;
////////////////////////////////////////////////////////////////////////
private:
bool HandlesSource(const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry) const;
};
} // namespace GradientSignal

@ -11,7 +11,6 @@
#include <Editor/EditorSmoothStepGradientComponent.h>
#include <Editor/EditorSurfaceSlopeGradientComponent.h>
#include <Editor/EditorMixedGradientComponent.h>
#include <Editor/EditorImageBuilderComponent.h>
#include <Editor/EditorImageGradientComponent.h>
#include <Editor/EditorConstantGradientComponent.h>
#include <Editor/EditorThresholdGradientComponent.h>
@ -29,7 +28,6 @@
#include <Editor/EditorGradientSurfaceDataComponent.h>
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
#include <UI/GradientPreviewDataWidget.h>
#include <Editor/EditorImageProcessingSystemComponent.h>
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<GradientSignalEditorSystemComponent>());
requiredComponents.push_back(azrtti_typeid<EditorImageProcessingSystemComponent>());
return requiredComponents;
}

@ -15,7 +15,6 @@
#include <AzCore/Debug/Profiler.h>
#include <Atom/ImageProcessing/PixelFormats.h>
#include <Atom/RPI.Public/RPIUtils.h>
#include <GradientSignal/Util.h>
#include <numeric>
@ -77,57 +76,4 @@ namespace GradientSignal
return true;
}
float GetValueFromImageAsset(AZStd::span<const uint8_t> 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<AZ::u32>(pixelLookup.GetX()) % width;
auto y = aznumeric_cast<AZ::u32>(pixelLookup.GetY()) % height;
// Flip the y because images are stored in reverse of our world axes
y = (height - 1) - y;
return AZ::RPI::GetImageDataPixelValue<float>(imageData, imageDescriptor, x, y);
}
}
return defaultValue;
}
}

@ -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

Loading…
Cancel
Save