merging from main
This commit is contained in:
@@ -43,6 +43,7 @@ ly_add_target(
|
||||
Gem::AtomLyIntegration_CommonFeatures.Public
|
||||
Gem::LmbrCentral.Static
|
||||
Gem::GradientSignal.Static
|
||||
Gem::SurfaceData.Static
|
||||
Gem::Atom_Feature_Common.Static
|
||||
Gem::Atom_Bootstrap.Headers
|
||||
)
|
||||
|
||||
+66
@@ -77,6 +77,72 @@ namespace AZ
|
||||
|
||||
//! Sets the photometric unit to the one provided and converts the intensity to the photometric unit so actual light intensity remains constant.
|
||||
virtual void ConvertToIntensityMode(PhotometricUnit intensityMode) = 0;
|
||||
|
||||
// Shutters
|
||||
|
||||
//! Returns true if shutters are enabled.
|
||||
virtual bool GetEnableShutters() const = 0;
|
||||
|
||||
//! Sets if shutters should be enabled.
|
||||
virtual void SetEnableShutters(bool enabled) = 0;
|
||||
|
||||
//! Returns the inner angle of the shutters in degrees
|
||||
virtual float GetInnerShutterAngle() const = 0;
|
||||
|
||||
//! Sets the inner angle of the shutters in degrees
|
||||
virtual void SetInnerShutterAngle(float degrees) = 0;
|
||||
|
||||
//! Returns the outer angle of the shutters in degrees
|
||||
virtual float GetOuterShutterAngle() const = 0;
|
||||
|
||||
//! Sets the outer angle of the shutters in degrees
|
||||
virtual void SetOuterShutterAngle(float degrees) = 0;
|
||||
|
||||
// Shadows
|
||||
|
||||
//! Returns true if shadows are enabled.
|
||||
virtual bool GetEnableShadow() const = 0;
|
||||
|
||||
//! Sets if shadows should be enabled.
|
||||
virtual void SetEnableShadow(bool enabled) = 0;
|
||||
|
||||
//! Returns the maximum width and height of shadowmap.
|
||||
virtual ShadowmapSize GetShadowmapMaxSize() const = 0;
|
||||
|
||||
//! Sets the maximum width and height of shadowmap.
|
||||
virtual void SetShadowmapMaxSize(ShadowmapSize size) = 0;
|
||||
|
||||
//! Returns the filter method of shadows.
|
||||
virtual ShadowFilterMethod GetShadowFilterMethod() const = 0;
|
||||
|
||||
//! Sets the filter method of shadows.
|
||||
virtual void SetShadowFilterMethod(ShadowFilterMethod method) = 0;
|
||||
|
||||
//! Gets the width of softening boundary between shadowed area and lit area in degrees.
|
||||
virtual float GetSofteningBoundaryWidthAngle() const = 0;
|
||||
|
||||
//! Sets the width of softening boundary between shadowed area and lit area in degrees.
|
||||
//! 0 disables softening.
|
||||
virtual void SetSofteningBoundaryWidthAngle(float degrees) = 0;
|
||||
|
||||
//! Gets the sample count to predict boundary of shadow.
|
||||
virtual uint32_t GetPredictionSampleCount() const = 0;
|
||||
|
||||
//! Sets the sample count to predict boundary of shadow. Maximum 16, and should also be
|
||||
//! less than the filtering sample count.
|
||||
virtual void SetPredictionSampleCount(uint32_t count) = 0;
|
||||
|
||||
//! Gets the sample count for filtering of the shadow boundary.
|
||||
virtual uint32_t GetFilteringSampleCount() const = 0;
|
||||
|
||||
//! Sets the sample count for filtering of the shadow boundary. Maximum 64.
|
||||
virtual void SetFilteringSampleCount(uint32_t count) = 0;
|
||||
|
||||
//! Gets the type of Pcf (percentage-closer filtering) to use.
|
||||
virtual PcfMethod GetPcfMethod() const = 0;
|
||||
|
||||
//! Sets the type of Pcf (percentage-closer filtering) to use.
|
||||
virtual void SetPcfMethod(PcfMethod method) = 0;
|
||||
};
|
||||
|
||||
//! The EBus for requests to for setting and getting light component properties.
|
||||
|
||||
+59
-3
@@ -14,9 +14,9 @@
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/CoreLightsConstants.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -28,6 +28,20 @@ namespace AZ
|
||||
AZ_RTTI(AZ::Render::AreaLightComponentConfig, "{11C08FED-7F94-4926-8517-46D08E4DD837}", ComponentConfig);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
enum class LightType : uint8_t
|
||||
{
|
||||
Unknown,
|
||||
Sphere,
|
||||
SpotDisk,
|
||||
Capsule,
|
||||
Quad,
|
||||
Polygon,
|
||||
SimplePoint,
|
||||
SimpleSpot,
|
||||
|
||||
LightTypeCount,
|
||||
};
|
||||
|
||||
static constexpr float CutoffIntensity = 0.1f;
|
||||
|
||||
AZ::Color m_color = AZ::Color::CreateOne();
|
||||
@@ -39,17 +53,50 @@ namespace AZ
|
||||
bool m_useFastApproximation = false;
|
||||
AZ::Crc32 m_shapeType;
|
||||
|
||||
bool m_enableShutters = false;
|
||||
LightType m_lightType = LightType::Unknown;
|
||||
float m_innerShutterAngleDegrees = 35.0f;
|
||||
float m_outerShutterAngleDegrees = 45.0f;
|
||||
|
||||
// Shadows (only used for supported shapes)
|
||||
bool m_enableShadow = false;
|
||||
ShadowmapSize m_shadowmapMaxSize = ShadowmapSize::Size256;
|
||||
ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None;
|
||||
PcfMethod m_pcfMethod = PcfMethod::BoundarySearch;
|
||||
float m_boundaryWidthInDegrees = 0.25f;
|
||||
uint16_t m_predictionSampleCount = 4;
|
||||
uint16_t m_filteringSampleCount = 12;
|
||||
|
||||
// The following functions provide information to an EditContext...
|
||||
|
||||
AZStd::vector<Edit::EnumConstant<PhotometricUnit>> GetValidPhotometricUnits() const;
|
||||
|
||||
bool RequiresShapeComponent() const;
|
||||
|
||||
//! Returns true if m_attenuationRadiusMode is set to LightAttenuationRadiusMode::Automatic
|
||||
bool IsAttenuationRadiusModeAutomatic() const;
|
||||
|
||||
//! Returns true if the shape type is a 2D surface
|
||||
bool Is2DSurface() const;
|
||||
//! Returns true if the shape type can emit light from both sides
|
||||
bool SupportsBothDirections() const;
|
||||
|
||||
//! Returns true if the light type supports a faster and less accurate approximation for the lighting algorithm.
|
||||
bool SupportsFastApproximation() const;
|
||||
|
||||
//! Returns true if the light type supports restricting the light beam to an angle
|
||||
bool SupportsShutters() const;
|
||||
|
||||
//! Returns true if the light type supports shutters, but they must be turned on.
|
||||
bool ShuttersMustBeEnabled() const;
|
||||
|
||||
//! Returns true if shutters are turned off
|
||||
bool ShuttersDisabled() const;
|
||||
|
||||
//! Returns true if the light type supports shadows.
|
||||
bool SupportsShadows() const;
|
||||
|
||||
//! Returns true if shadows are turned on
|
||||
bool ShadowsDisabled() const;
|
||||
|
||||
//! Returns characters for a suffix for the light type including a space. " lm" for lumens for example.
|
||||
const char* GetIntensitySuffix() const;
|
||||
|
||||
@@ -65,6 +112,15 @@ namespace AZ
|
||||
//! Returns the maximum intensity value for UI depending on the m_intensityMode, but users may still type in a greater value depending on GetIntensityMin().
|
||||
float GetIntensitySoftMax() const;
|
||||
|
||||
//! Returns true if shadow filtering is disabled.
|
||||
bool IsShadowFilteringDisabled() const;
|
||||
|
||||
//! Returns true if pcf shadows are disabled.
|
||||
bool IsShadowPcfDisabled() const;
|
||||
|
||||
//! Returns true if pcf boundary search is disabled.
|
||||
bool IsPcfBoundarySearchDisabled() const;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -22,10 +22,6 @@ namespace AZ
|
||||
{
|
||||
static constexpr const char* const AreaLightComponentTypeId = "{744B3961-6242-4461-983F-2817D9D29C30}";
|
||||
static constexpr const char* const EditorAreaLightComponentTypeId = "{8B605C0C-9027-4E0B-BA8C-19E396F8F262}";
|
||||
static constexpr const char* const PointLightComponentTypeId = "{0A0E44AB-F583-481F-8AE8-68C4B1F9CD05}";
|
||||
static constexpr const char* const EditorPointLightComponentTypeId = "{C4D354BE-5247-41FD-9A8D-550C6772EE5B}";
|
||||
static constexpr const char* const SpotLightComponentTypeId = "{441DF0EC-6B70-451E-AEBE-6452A17BB852}";
|
||||
static constexpr const char* const EditorSpotLightComponentTypeId = "{9A32D37B-C5D2-43A7-B574-E2EA1CDC7D64}";
|
||||
static constexpr const char* const DirectionalLightComponentTypeId = "{13054592-2753-46C2-B19E-59670D4CE03D}";
|
||||
static constexpr const char* const EditorDirectionalLightComponentTypeId = "{45B97527-6E72-411B-BC23-00068CF01580}";
|
||||
|
||||
|
||||
+7
@@ -182,6 +182,13 @@ namespace AZ
|
||||
//! This sets the sample count for filtering of the shadow boundary.
|
||||
//! @param count Sample Count for filtering (up to 64)
|
||||
virtual void SetFilteringSampleCount(uint32_t count) = 0;
|
||||
|
||||
//! This gets the type of Pcf (percentage-closer filtering) to use.
|
||||
virtual PcfMethod GetPcfMethod() const = 0;
|
||||
|
||||
//! This sets the type of Pcf (percentage-closer filtering) to use.
|
||||
//! @param method The Pcf method to use.
|
||||
virtual void SetPcfMethod(PcfMethod method) = 0;
|
||||
};
|
||||
using DirectionalLightRequestBus = EBus<DirectionalLightRequests>;
|
||||
|
||||
|
||||
+3
@@ -117,11 +117,14 @@ namespace AZ
|
||||
//! It is used only when the pixel is predicted as on the boundary.
|
||||
uint16_t m_filteringSampleCount = 32;
|
||||
|
||||
PcfMethod m_pcfMethod = PcfMethod::BoundarySearch;
|
||||
|
||||
bool IsSplitManual() const;
|
||||
bool IsSplitAutomatic() const;
|
||||
bool IsCascadeCorrectionDisabled() const;
|
||||
bool IsShadowFilteringDisabled() const;
|
||||
bool IsShadowPcfDisabled() const;
|
||||
bool IsPcfBoundarySearchDisabled() const;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/ComponentBus.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/PointLightComponentConfig.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class PointLightRequests
|
||||
: public ComponentBus
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(PointLightRequests, "{359BE514-DBEB-4D6A-B283-F8C5E83CD477}");
|
||||
|
||||
/// Overrides the default AZ::EBusTraits handler policy to allow one listener only.
|
||||
static const EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single;
|
||||
|
||||
virtual ~PointLightRequests() {}
|
||||
|
||||
/// Gets a point light's color. This value is indepedent from its intensity.
|
||||
virtual const Color& GetColor() const = 0;
|
||||
|
||||
/// Sets a point light's color. This value is indepedent from its intensity.
|
||||
virtual void SetColor(const Color& color) = 0;
|
||||
|
||||
/// Gets a point light's intensity. This value is indepedent from its color.
|
||||
virtual float GetIntensity() const = 0;
|
||||
|
||||
//! Gets a point light's photometric type.
|
||||
virtual PhotometricUnit GetIntensityMode() const = 0;
|
||||
|
||||
/// Sets a point light's intensity. This value is indepedent from its color.
|
||||
virtual void SetIntensity(float intensity) = 0;
|
||||
|
||||
//! Sets a point light's intensity and intensity mode. This value is indepedent from its color.
|
||||
virtual void SetIntensity(float intensity, PhotometricUnit intensityMode) = 0;
|
||||
|
||||
/// Gets the distance at which the point light will no longer affect lighting.
|
||||
virtual float GetAttenuationRadius() const = 0;
|
||||
|
||||
/// Set the distance and which a point light will no longer affect lighitng. Setting this forces the RadiusCalculation to Explicit mode.
|
||||
virtual void SetAttenuationRadius(float radius) = 0;
|
||||
|
||||
/// Gets the size in meters of the sphere representing the light bulb.
|
||||
virtual float GetBulbRadius() const = 0;
|
||||
|
||||
/// Sets the size in meters of the sphere representing the light bulb in meters.
|
||||
virtual void SetBulbRadius(float bulbSize) = 0;
|
||||
|
||||
/*
|
||||
* If this is set to Automatic, the radius will immediately be recalculated based on the intensity.
|
||||
* If this is set to Explicit, the radius value will be unchanged from its previous value.
|
||||
*/
|
||||
virtual void SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode) = 0;
|
||||
|
||||
/// Gets the flag whether attenuation radius calculation is automatic or not.
|
||||
virtual bool GetAttenuationRadiusIsAutomatic() const = 0;
|
||||
|
||||
/// Sets the flag whether attenuation radius calculation is automatic or not.
|
||||
virtual void SetAttenuationRadiusIsAutomatic(bool flag)
|
||||
{
|
||||
SetAttenuationRadiusMode(flag ? LightAttenuationRadiusMode::Automatic : LightAttenuationRadiusMode::Explicit);
|
||||
}
|
||||
|
||||
//! Sets the photometric unit to the one provided and converts the intensity to the photometric unit so actual light intensity remains constant.
|
||||
virtual void ConvertToIntensityMode(PhotometricUnit intensityMode) = 0;
|
||||
};
|
||||
|
||||
/// The EBus for requests to for setting and getting light component properties.
|
||||
typedef AZ::EBus<PointLightRequests> PointLightRequestBus;
|
||||
|
||||
class PointLightNotifications
|
||||
: public ComponentBus
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(PointLightNotifications, "{7363728D-E3EE-4AC8-AAA7-C299782763F0}");
|
||||
|
||||
virtual ~PointLightNotifications() {}
|
||||
|
||||
/**
|
||||
* Signals that the color of the light changed.
|
||||
* @param color A reference to the new color of the light.
|
||||
*/
|
||||
virtual void OnColorChanged(const Color& /*color*/) { }
|
||||
|
||||
/**
|
||||
* Signals that the intensity of the light changed.
|
||||
* @param color A reference to the new intensity of the light.
|
||||
*/
|
||||
virtual void OnIntensityChanged(float /*intensity*/) { }
|
||||
|
||||
/**
|
||||
* Signals that the color or intensity of the light changed. This is useful when both the color and intensity are need in the same call.
|
||||
* @param color A reference to the new color of the light.
|
||||
* @param color A reference to the new intensity of the light.
|
||||
*/
|
||||
virtual void OnColorOrIntensityChanged(const Color& /*color*/, float /*intensity*/) { }
|
||||
|
||||
/**
|
||||
* Signals that the attenuation radius of the light changed.
|
||||
* @param attenuationRadius The distance at which this light no longer affects lighting.
|
||||
*/
|
||||
virtual void OnAttenutationRadiusChanged(float /*attenuationRadius*/) { }
|
||||
|
||||
/**
|
||||
* Signals that the bulb size of the light changed.
|
||||
* @param bulbRadius The size in meters of the sphere representing the light bulb in meters.
|
||||
*/
|
||||
virtual void OnBulbRadiusChanged(float /*bulbRadius*/) { }
|
||||
|
||||
};
|
||||
|
||||
/// The EBus for light notification events.
|
||||
typedef AZ::EBus<PointLightNotifications> PointLightNotificationBus;
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-113
@@ -1,113 +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/Component/Component.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/CoreLightsConstants.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
struct PointLightComponentConfig final
|
||||
: public ComponentConfig
|
||||
{
|
||||
AZ_RTTI(PointLightComponentConfig, "{B6FC35BA-D22F-4C20-BFFC-3FE7A48858FA}", ComponentConfig);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static constexpr float DefaultIntensity = 800.0f; // 800 lumes is roughly equivalent to a 60 watt incandescent bulb
|
||||
static constexpr float DefaultBulbRadius = 0.05f; // 5cm
|
||||
|
||||
AZ::Color m_color = AZ::Color::CreateOne();
|
||||
PhotometricUnit m_intensityMode = PhotometricUnit::Lumen;
|
||||
float m_intensity = DefaultIntensity;
|
||||
float m_attenuationRadius = 0.0f;
|
||||
float m_bulbRadius = DefaultBulbRadius;
|
||||
LightAttenuationRadiusMode m_attenuationRadiusMode = LightAttenuationRadiusMode::Automatic;
|
||||
|
||||
// Not serialized, but used to keep scaled and unscaled properties in sync.
|
||||
float m_scale = 1.0f;
|
||||
|
||||
// These values are used to deal adjusting the brightness and bulb radius based on the transform component's scale
|
||||
// so that point lights scale concistently with meshes. Not serialized.
|
||||
float m_unscaledIntensity = DefaultIntensity;
|
||||
float m_unscaledBulbRadius = DefaultBulbRadius;
|
||||
|
||||
//! Updates scale and adjusts the values of intensity and bulb radius based on the new scale and the unscaled values.
|
||||
void UpdateScale(float newScale)
|
||||
{
|
||||
m_scale = newScale;
|
||||
|
||||
m_intensity = m_unscaledIntensity;
|
||||
|
||||
// Lumens & Candela aren't based on surface area, so scale them.
|
||||
if (!IsAreaBasedIntensityMode())
|
||||
{
|
||||
// Light surface area and brightness increases at scale^2 because of equation of sphere surface area.
|
||||
m_intensity *= m_scale * m_scale;
|
||||
}
|
||||
|
||||
m_bulbRadius = m_unscaledBulbRadius * m_scale;
|
||||
}
|
||||
|
||||
//! Updates the unscaled intensity based on the current scaled value.
|
||||
void UpdateUnscaledIntensity()
|
||||
{
|
||||
m_unscaledIntensity = m_intensity;
|
||||
|
||||
// Lumens & Candela aren't based on surface area, so scale them.
|
||||
if (!IsAreaBasedIntensityMode())
|
||||
{
|
||||
// Light surface area and brightness increases at scale^2 because of equation of sphere surface area.
|
||||
m_unscaledIntensity /= m_scale * m_scale;
|
||||
}
|
||||
}
|
||||
|
||||
//! Updates the unscaled bulb radius based on the current scaled value.
|
||||
void UpdateUnscaledBulbRadius()
|
||||
{
|
||||
m_unscaledBulbRadius = m_bulbRadius / m_scale;
|
||||
}
|
||||
|
||||
// Returns true if the intensity mode is an area based light unit (not lumens or candela)
|
||||
bool IsAreaBasedIntensityMode()
|
||||
{
|
||||
return m_intensityMode != PhotometricUnit::Lumen && m_intensityMode != PhotometricUnit::Candela;
|
||||
}
|
||||
|
||||
// Returns the surface area of the light bulb. 4.0 * pi * m_bulbRadius^2
|
||||
float GetArea()
|
||||
{
|
||||
return 4.0f * Constants::Pi * m_bulbRadius * m_bulbRadius;
|
||||
}
|
||||
|
||||
// The following functions provide information to an EditContext...
|
||||
|
||||
//! Returns true if m_attenuationRadiusMode is set to LightAttenuationRadiusMode::Automatic
|
||||
bool IsAttenuationRadiusModeAutomatic() const
|
||||
{
|
||||
return m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic;
|
||||
}
|
||||
|
||||
//! Returns characters for a suffix for the light type including a space. " lm" for lumens for example.
|
||||
const char* GetIntensitySuffix() const
|
||||
{
|
||||
return PhotometricValue::GetTypeSuffix(m_intensityMode);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
-172
@@ -1,172 +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/Component/ComponentBus.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/SpotLightComponentConfig.h>
|
||||
#include <Atom/Feature/CoreLights/ShadowConstants.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class SpotLightRequests
|
||||
: public ComponentBus
|
||||
{
|
||||
public:
|
||||
//! Overrides the default AZ::EBusTraits handler policy to allow one listener only.
|
||||
static const EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single;
|
||||
|
||||
virtual ~SpotLightRequests() = default;
|
||||
|
||||
//! Gets a spot light's color. This value is independent from its intensity.
|
||||
virtual const Color& GetColor() const = 0;
|
||||
|
||||
//! Sets a spot light's color. This value is independent from its intensity.
|
||||
virtual void SetColor(const Color& color) = 0;
|
||||
|
||||
//! Gets a spot light's intensity. This value is independent from its color.
|
||||
virtual float GetIntensity() const = 0;
|
||||
|
||||
//! Sets a spot light's intensity. This value is independent from its color.
|
||||
virtual void SetIntensity(float intensity) = 0;
|
||||
|
||||
//! Gets a spot light's bulb radius in meters.
|
||||
virtual float GetBulbRadius() const = 0;
|
||||
|
||||
//! Sets a spot light's bulb radius in meters.
|
||||
virtual void SetBulbRadius(float bulbRadius) = 0;
|
||||
|
||||
//! @return Returns inner cone angle of the spot light in degrees.
|
||||
virtual float GetInnerConeAngleInDegrees() const = 0;
|
||||
//! @brief Sets inner cone angle of the spot light in degrees.
|
||||
virtual void SetInnerConeAngleInDegrees(float degrees) = 0;
|
||||
|
||||
//! @return Returns outer cone angle of the spot light in degrees.
|
||||
virtual float GetOuterConeAngleInDegrees() const = 0;
|
||||
//! @brief Sets outer cone angle of the spot light in degrees.
|
||||
virtual void SetOuterConeAngleInDegrees(float degrees) = 0;
|
||||
|
||||
//! @return Returns penumbra bias for the falloff curve of the spot light.
|
||||
virtual float GetPenumbraBias() const = 0;
|
||||
//! @brief Sets penumbra bias for the falloff curve of the spot light.
|
||||
virtual void SetPenumbraBias(float penumbraBias) = 0;
|
||||
|
||||
//! @return Returns radius attenuation of the spot light.
|
||||
virtual float GetAttenuationRadius() const = 0;
|
||||
//! @return Sets radius attenuation of the spot light.
|
||||
virtual void SetAttenuationRadius(float radius) = 0;
|
||||
|
||||
//! @return Returns radius attenuation mode (Auto or Explicit).
|
||||
virtual LightAttenuationRadiusMode GetAttenuationRadiusMode() const = 0;
|
||||
//! If this is set to Automatic, the radius will immediately be recalculated based on the intensity.
|
||||
//! If this is set to Explicit, the radius value will be unchanged from its previous value.
|
||||
virtual void SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode) = 0;
|
||||
|
||||
//! @return the flag whether attenuation radius calculation is automatic or not.
|
||||
virtual bool GetAttenuationRadiusIsAutomatic() const
|
||||
{
|
||||
return (GetAttenuationRadiusMode() == LightAttenuationRadiusMode::Automatic);
|
||||
}
|
||||
//! This sets flag whether attenuation radius calculation is automatic or not.
|
||||
//! @param flag flag whether attenuation radius calculation is automatic or not.
|
||||
virtual void SetAttenuationRadiusIsAutomatic(bool flag)
|
||||
{
|
||||
SetAttenuationRadiusMode(flag ? LightAttenuationRadiusMode::Automatic : LightAttenuationRadiusMode::Explicit);
|
||||
}
|
||||
|
||||
//! @return the flag indicates this light have shadow or not.
|
||||
virtual bool GetEnableShadow() const = 0;
|
||||
//! This specify this spot light uses shadow or not.
|
||||
//! @param enabled true if shadow is used, false otherwise.
|
||||
virtual void SetEnableShadow(bool enabled) = 0;
|
||||
|
||||
//! @return the size of shadowmap (width and height).
|
||||
virtual ShadowmapSize GetShadowmapSize() const = 0;
|
||||
|
||||
//! This specifies the size of shadowmap to size x size.
|
||||
virtual void SetShadowmapSize(ShadowmapSize size) = 0;
|
||||
|
||||
//! This gets the filter method of shadows.
|
||||
//! @return filter method
|
||||
virtual ShadowFilterMethod GetShadowFilterMethod() const = 0;
|
||||
|
||||
//! This specifies filter method of shadows.
|
||||
//! @param method Filter method.
|
||||
virtual void SetShadowFilterMethod(ShadowFilterMethod method) = 0;
|
||||
|
||||
//! This gets the width of boundary between shadowed area and lit area.
|
||||
//! The width is given by the angle, and the units are in degrees.
|
||||
//! @return Boundary width. The degree of the shadowed region is gradually changed on the boundary.
|
||||
virtual float GetSofteningBoundaryWidthAngle() const = 0;
|
||||
|
||||
//! This specifies the width of boundary between shadowed area and lit area.
|
||||
//! @param width Boundary width. The degree of shadowed is gradually changed on the boundary.
|
||||
//! If width == 0, softening edge is disabled. Units are in degrees.
|
||||
virtual void SetSofteningBoundaryWidthAngle(float degrees) = 0;
|
||||
|
||||
//! This gets the sample count to predict boundary of shadow.
|
||||
//! @return Sample Count for prediction of whether the pixel is on the boundary (up to 16)
|
||||
virtual uint32_t GetPredictionSampleCount() const = 0;
|
||||
|
||||
//! This sets the sample count to predict boundary of shadow.
|
||||
//! @param count Sample count for prediction of whether the pixel is on the boundary (up to 16)
|
||||
//! This value should be less than or equal to m_filteringSampleCount.
|
||||
virtual void SetPredictionSampleCount(uint32_t count) = 0;
|
||||
|
||||
//! This gets the sample count for filtering of the shadow boundary.
|
||||
//! @return Sample Count for filtering (up to 64)
|
||||
virtual uint32_t GetFilteringSampleCount() const = 0;
|
||||
|
||||
//! This sets the sample count for filtering of the shadow boundary.
|
||||
//! @param count Sample Count for filtering (up to 64)
|
||||
virtual void SetFilteringSampleCount(uint32_t count) = 0;
|
||||
|
||||
//! This gets the type of Pcf (percentage-closer filtering) to use.
|
||||
virtual PcfMethod GetPcfMethod() const = 0;
|
||||
|
||||
//! This sets the type of Pcf (percentage-closer filtering) to use.
|
||||
//! @param method The Pcf method to use.
|
||||
virtual void SetPcfMethod(PcfMethod method) = 0;
|
||||
};
|
||||
|
||||
/// The EBus for requests to for setting and getting spot light component properties.
|
||||
typedef AZ::EBus<SpotLightRequests> SpotLightRequestBus;
|
||||
|
||||
class SpotLightNotifications
|
||||
: public ComponentBus
|
||||
{
|
||||
public:
|
||||
virtual ~SpotLightNotifications() = default;
|
||||
|
||||
//! @brief Signals that the intensity of the light changed.
|
||||
virtual void OnIntensityChanged(float intensity) { AZ_UNUSED(intensity); }
|
||||
|
||||
//! @brief Signals that the color of the light changed.
|
||||
virtual void OnColorChanged(const Color& color) { AZ_UNUSED(color); }
|
||||
|
||||
//! @brief Signals that the cone angles of the spot light have changed.
|
||||
virtual void OnConeAnglesChanged(float innerConeAngleDegrees, float outerConeAngleDegrees) { AZ_UNUSED(innerConeAngleDegrees); AZ_UNUSED(outerConeAngleDegrees); }
|
||||
|
||||
//! @brief Signals that the attenuation radius has changed.
|
||||
virtual void OnAttenuationRadiusChanged(float attenuationRadius) { AZ_UNUSED(attenuationRadius); }
|
||||
|
||||
//! @brief Signals that the penumbra bias has changed.
|
||||
virtual void OnPenumbraBiasChanged(float penumbraBias) { AZ_UNUSED(penumbraBias); }
|
||||
};
|
||||
|
||||
//! The EBus for spot light notification events.
|
||||
typedef AZ::EBus<SpotLightNotifications> SpotLightNotificationBus;
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-62
@@ -1,62 +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/Component/Component.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <Atom/Feature/CoreLights/ShadowConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/CoreLightsConstants.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
struct SpotLightComponentConfig final
|
||||
: ComponentConfig
|
||||
{
|
||||
AZ_RTTI(SpotLightComponentConfig, "{20C882C8-615E-4272-93A8-BE9102E6EFED}", ComponentConfig);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZ::Color m_color = AZ::Color::CreateOne();
|
||||
float m_intensity = 100.0f;
|
||||
PhotometricUnit m_intensityMode = PhotometricUnit::Lumen;
|
||||
float m_bulbRadius = 0.075;
|
||||
float m_innerConeDegrees = 45.0f;
|
||||
float m_outerConeDegrees = 55.0f;
|
||||
float m_attenuationRadius = 20.0f;
|
||||
float m_penumbraBias = 0.0f;
|
||||
LightAttenuationRadiusMode m_attenuationRadiusMode = LightAttenuationRadiusMode::Automatic;
|
||||
bool m_enabledShadow = false;
|
||||
ShadowmapSize m_shadowmapSize = MaxShadowmapImageSize;
|
||||
ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None;
|
||||
PcfMethod m_pcfMethod = PcfMethod::BoundarySearch;
|
||||
float m_boundaryWidthInDegrees = 0.25f;
|
||||
uint16_t m_predictionSampleCount = 4;
|
||||
uint16_t m_filteringSampleCount = 32;
|
||||
|
||||
// The following functions provide information to an EditContext...
|
||||
|
||||
//! Returns true if m_attenuationRadiusMode is set to LightAttenuationRadiusMode::Automatic
|
||||
bool IsAttenuationRadiusModeAutomatic() const;
|
||||
|
||||
//! Returns characters for a suffix for the light type including a space. " lm" for lumens for example.
|
||||
const char* GetIntensitySuffix() const;
|
||||
|
||||
float GetConeDegrees() const;
|
||||
bool IsShadowFilteringDisabled() const;
|
||||
bool IsShadowPcfDisabled() const;
|
||||
bool IsPcfBoundarySearchDisabled() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
+27
-1
@@ -60,8 +60,34 @@ namespace AZ
|
||||
{
|
||||
public:
|
||||
virtual void OnModelReady(const Data::Asset<RPI::ModelAsset>& modelAsset, const Data::Instance<RPI::Model>& model) = 0;
|
||||
virtual void OnModelPreDestroy() {}
|
||||
|
||||
/**
|
||||
* When connecting to this bus if the asset is ready you will immediately get an OnModelReady event
|
||||
*/
|
||||
template<class Bus>
|
||||
struct ConnectionPolicy
|
||||
: public AZ::EBusConnectionPolicy<Bus>
|
||||
{
|
||||
static void Connect(
|
||||
typename Bus::BusPtr& busPtr,
|
||||
typename Bus::Context& context,
|
||||
typename Bus::HandlerNode& handler,
|
||||
typename Bus::Context::ConnectLockGuard& connectLock,
|
||||
const typename Bus::BusIdType& id = 0)
|
||||
{
|
||||
AZ::EBusConnectionPolicy<Bus>::Connect(busPtr, context, handler, connectLock, id);
|
||||
|
||||
Data::Instance<RPI::Model> model;
|
||||
MeshComponentRequestBus::EventResult(model, id, &MeshComponentRequestBus::Events::GetModel);
|
||||
if (model &&
|
||||
model->GetModelAsset().GetStatus() == AZ::Data::AssetData::AssetStatus::Ready)
|
||||
{
|
||||
handler->OnModelReady(model->GetModelAsset(), model);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
using MeshComponentNotificationBus = EBus<MeshComponentNotifications>;
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+91
-6
@@ -21,7 +21,8 @@ namespace AZ
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AreaLightComponentConfig, ComponentConfig>()
|
||||
->Version(3)
|
||||
->Version(5) // ATOM-14637
|
||||
->Field("LightType", &AreaLightComponentConfig::m_lightType)
|
||||
->Field("Color", &AreaLightComponentConfig::m_color)
|
||||
->Field("IntensityMode", &AreaLightComponentConfig::m_intensityMode)
|
||||
->Field("Intensity", &AreaLightComponentConfig::m_intensity)
|
||||
@@ -29,25 +30,89 @@ namespace AZ
|
||||
->Field("AttenuationRadius", &AreaLightComponentConfig::m_attenuationRadius)
|
||||
->Field("LightEmitsBothDirections", &AreaLightComponentConfig::m_lightEmitsBothDirections)
|
||||
->Field("UseFastApproximation", &AreaLightComponentConfig::m_useFastApproximation)
|
||||
// Shutters
|
||||
->Field("EnableShutters", &AreaLightComponentConfig::m_enableShutters)
|
||||
->Field("InnerShutterAngleDegrees", &AreaLightComponentConfig::m_innerShutterAngleDegrees)
|
||||
->Field("OuterShutterAngleDegrees", &AreaLightComponentConfig::m_outerShutterAngleDegrees)
|
||||
// Shadows
|
||||
->Field("Enable Shadow", &AreaLightComponentConfig::m_enableShadow)
|
||||
->Field("Shadowmap Max Size", &AreaLightComponentConfig::m_shadowmapMaxSize)
|
||||
->Field("Shadow Filter Method", &AreaLightComponentConfig::m_shadowFilterMethod)
|
||||
->Field("Softening Boundary Width", &AreaLightComponentConfig::m_boundaryWidthInDegrees)
|
||||
->Field("Prediction Sample Count", &AreaLightComponentConfig::m_predictionSampleCount)
|
||||
->Field("Filtering Sample Count", &AreaLightComponentConfig::m_filteringSampleCount)
|
||||
->Field("Pcf Method", &AreaLightComponentConfig::m_pcfMethod);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::vector<Edit::EnumConstant<PhotometricUnit>> AreaLightComponentConfig::GetValidPhotometricUnits() const
|
||||
{
|
||||
AZStd::vector<Edit::EnumConstant<PhotometricUnit>> enumValues =
|
||||
{
|
||||
// Candela & lumen always supported.
|
||||
Edit::EnumConstant<PhotometricUnit>(PhotometricUnit::Candela, "Candela"),
|
||||
Edit::EnumConstant<PhotometricUnit>(PhotometricUnit::Lumen, "Lumen"),
|
||||
};
|
||||
|
||||
if (RequiresShapeComponent())
|
||||
{
|
||||
// Lights with surface area also support nits and ev100.
|
||||
enumValues.push_back(Edit::EnumConstant<PhotometricUnit>(PhotometricUnit::Nit, "Nit"));
|
||||
enumValues.push_back(Edit::EnumConstant<PhotometricUnit>(PhotometricUnit::Ev100Luminance, "Ev100"));
|
||||
}
|
||||
return enumValues;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::RequiresShapeComponent() const
|
||||
{
|
||||
return m_lightType == LightType::Sphere
|
||||
|| m_lightType == LightType::SpotDisk
|
||||
|| m_lightType == LightType::Capsule
|
||||
|| m_lightType == LightType::Quad
|
||||
|| m_lightType == LightType::Polygon;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::IsAttenuationRadiusModeAutomatic() const
|
||||
{
|
||||
return m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::Is2DSurface() const
|
||||
bool AreaLightComponentConfig::SupportsBothDirections() const
|
||||
{
|
||||
return m_shapeType == AZ_CRC_CE("DiskShape")
|
||||
|| m_shapeType == AZ_CRC_CE("QuadShape")
|
||||
|| m_shapeType == AZ_CRC_CE("PolygonPrism");
|
||||
return m_lightType == LightType::Quad
|
||||
|| m_lightType == LightType::Polygon;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::SupportsFastApproximation() const
|
||||
{
|
||||
return m_shapeType == AZ_CRC_CE("QuadShape");
|
||||
return m_lightType == LightType::Quad;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::SupportsShutters() const
|
||||
{
|
||||
return m_lightType == LightType::SimpleSpot
|
||||
|| m_lightType == LightType::SpotDisk;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::ShuttersMustBeEnabled() const
|
||||
{
|
||||
return m_lightType == LightType::SpotDisk;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::ShuttersDisabled() const
|
||||
{
|
||||
return m_lightType == LightType::SpotDisk && !m_enableShutters;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::SupportsShadows() const
|
||||
{
|
||||
return m_shapeType == AZ_CRC_CE("DiskShape");
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::ShadowsDisabled() const
|
||||
{
|
||||
return !m_enableShadow;
|
||||
}
|
||||
|
||||
const char* AreaLightComponentConfig::GetIntensitySuffix() const
|
||||
@@ -109,6 +174,26 @@ namespace AZ
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::IsShadowFilteringDisabled() const
|
||||
{
|
||||
return (m_shadowFilterMethod == ShadowFilterMethod::None);
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::IsShadowPcfDisabled() const
|
||||
{
|
||||
return !(m_shadowFilterMethod == ShadowFilterMethod::Pcf ||
|
||||
m_shadowFilterMethod == ShadowFilterMethod::EsmPcf);
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::IsPcfBoundarySearchDisabled() const
|
||||
{
|
||||
if (IsShadowPcfDisabled())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_pcfMethod != PcfMethod::BoundarySearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+504
-206
@@ -15,6 +15,8 @@
|
||||
#include <CoreLights/DiskLightDelegate.h>
|
||||
#include <CoreLights/PolygonLightDelegate.h>
|
||||
#include <CoreLights/QuadLightDelegate.h>
|
||||
#include <CoreLights/SimplePointLightDelegate.h>
|
||||
#include <CoreLights/SimpleSpotLightDelegate.h>
|
||||
#include <CoreLights/SphereLightDelegate.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
|
||||
@@ -31,297 +33,593 @@
|
||||
#include <LmbrCentral/Shape/PolygonPrismShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/QuadShapeComponentBus.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Render
|
||||
{
|
||||
namespace Render
|
||||
void AreaLightComponentController::Reflect(ReflectContext* context)
|
||||
{
|
||||
void AreaLightComponentController::Reflect(ReflectContext* context)
|
||||
AreaLightComponentConfig::Reflect(context);
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
AreaLightComponentConfig::Reflect(context);
|
||||
serializeContext->Class<AreaLightComponentController>()
|
||||
->Version(1)
|
||||
->Field("Configuration", &AreaLightComponentController::m_configuration);
|
||||
}
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AreaLightComponentController>()
|
||||
->Version(0)
|
||||
->Field("Configuration", &AreaLightComponentController::m_configuration);
|
||||
}
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<AreaLightRequestBus>("AreaLightRequestBus")
|
||||
->Event("GetAttenuationRadius", &AreaLightRequestBus::Events::GetAttenuationRadius)
|
||||
->Event("SetAttenuationRadius", &AreaLightRequestBus::Events::SetAttenuationRadius)
|
||||
->Event("SetAttenuationRadiusMode", &AreaLightRequestBus::Events::SetAttenuationRadiusMode)
|
||||
->Event("GetColor", &AreaLightRequestBus::Events::GetColor)
|
||||
->Event("SetColor", &AreaLightRequestBus::Events::SetColor)
|
||||
->Event("GetEmitsLightBothDirections", &AreaLightRequestBus::Events::GetLightEmitsBothDirections)
|
||||
->Event("SetEmitsLightBothDirections", &AreaLightRequestBus::Events::SetLightEmitsBothDirections)
|
||||
->Event("GetUseFastApproximation", &AreaLightRequestBus::Events::GetUseFastApproximation)
|
||||
->Event("SetUseFastApproximation", &AreaLightRequestBus::Events::SetUseFastApproximation)
|
||||
->Event("GetIntensity", &AreaLightRequestBus::Events::GetIntensity)
|
||||
->Event("SetIntensity", static_cast<void(AreaLightRequestBus::Events::*)(float)>(&AreaLightRequestBus::Events::SetIntensity))
|
||||
->Event("GetIntensityMode", &AreaLightRequestBus::Events::GetIntensityMode)
|
||||
->Event("ConvertToIntensityMode", &AreaLightRequestBus::Events::ConvertToIntensityMode)
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
->Event("GetEnableShutters", &AreaLightRequestBus::Events::GetEnableShutters)
|
||||
->Event("SetEnableShutters", &AreaLightRequestBus::Events::SetEnableShutters)
|
||||
->Event("GetInnerShutterAngle", &AreaLightRequestBus::Events::GetInnerShutterAngle)
|
||||
->Event("SetInnerShutterAngle", &AreaLightRequestBus::Events::SetInnerShutterAngle)
|
||||
->Event("GetOuterShutterAngle", &AreaLightRequestBus::Events::GetOuterShutterAngle)
|
||||
->Event("SetOuterShutterAngle", &AreaLightRequestBus::Events::SetOuterShutterAngle)
|
||||
|
||||
->Event("GetEnableShadow", &AreaLightRequestBus::Events::GetEnableShadow)
|
||||
->Event("SetEnableShadow", &AreaLightRequestBus::Events::SetEnableShadow)
|
||||
->Event("GetShadowmapMaxSize", &AreaLightRequestBus::Events::GetShadowmapMaxSize)
|
||||
->Event("SetShadowmapMaxSize", &AreaLightRequestBus::Events::SetShadowmapMaxSize)
|
||||
->Event("GetShadowFilterMethod", &AreaLightRequestBus::Events::GetShadowFilterMethod)
|
||||
->Event("SetShadowFilterMethod", &AreaLightRequestBus::Events::SetShadowFilterMethod)
|
||||
->Event("GetSofteningBoundaryWidthAngle", &AreaLightRequestBus::Events::GetSofteningBoundaryWidthAngle)
|
||||
->Event("SetSofteningBoundaryWidthAngle", &AreaLightRequestBus::Events::SetSofteningBoundaryWidthAngle)
|
||||
->Event("GetPredictionSampleCount", &AreaLightRequestBus::Events::GetPredictionSampleCount)
|
||||
->Event("SetPredictionSampleCount", &AreaLightRequestBus::Events::SetPredictionSampleCount)
|
||||
->Event("GetFilteringSampleCount", &AreaLightRequestBus::Events::GetFilteringSampleCount)
|
||||
->Event("SetFilteringSampleCount", &AreaLightRequestBus::Events::SetFilteringSampleCount)
|
||||
->Event("GetPcfMethod", &AreaLightRequestBus::Events::GetPcfMethod)
|
||||
->Event("SetPcfMethod", &AreaLightRequestBus::Events::SetPcfMethod)
|
||||
|
||||
->VirtualProperty("AttenuationRadius", "GetAttenuationRadius", "SetAttenuationRadius")
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("EmitsLightBothDirections", "GetEmitsLightBothDirections", "SetEmitsLightBothDirections")
|
||||
->VirtualProperty("UseFastApproximation", "GetUseFastApproximation", "SetUseFastApproximation")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
|
||||
->VirtualProperty("ShuttersEnabled", "GetEnableShutters", "SetEnableShutters")
|
||||
->VirtualProperty("InnerShutterAngle", "GetInnerShutterAngle", "SetInnerShutterAngle")
|
||||
->VirtualProperty("OuterShutterAngle", "GetOuterShutterAngle", "SetOuterShutterAngle")
|
||||
|
||||
->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow")
|
||||
->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("SofteningBoundaryWidthAngle", "GetSofteningBoundaryWidthAngle", "SetSofteningBoundaryWidthAngle")
|
||||
->VirtualProperty("PredictionSampleCount", "GetPredictionSampleCount", "SetPredictionSampleCount")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
->VirtualProperty("PcfMethod", "GetPcfMethod", "SetPcfMethod");
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC_CE("AreaLightService"));
|
||||
}
|
||||
|
||||
void AreaLightComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("AreaLightService"));
|
||||
}
|
||||
|
||||
void AreaLightComponentController::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
dependent.push_back(AZ_CRC_CE("ShapeService"));
|
||||
}
|
||||
|
||||
AreaLightComponentController::AreaLightComponentController(const AreaLightComponentConfig& config)
|
||||
: m_configuration(config)
|
||||
{
|
||||
}
|
||||
|
||||
void AreaLightComponentController::Activate(EntityId entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
|
||||
// Used to determine which features are supported.
|
||||
m_configuration.m_shapeType = 0;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(m_configuration.m_shapeType, m_entityId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetShapeType);
|
||||
|
||||
VerifyLightTypeAndShapeComponent();
|
||||
CreateLightShapeDelegate();
|
||||
|
||||
if (m_configuration.RequiresShapeComponent() && m_lightShapeDelegate == nullptr)
|
||||
{
|
||||
AZ_Error("AreaLightComponentController", false, "AreaLightComponentController activated without having required shape component.");
|
||||
}
|
||||
|
||||
AreaLightRequestBus::Handler::BusConnect(m_entityId);
|
||||
|
||||
ConfigurationChanged();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::Deactivate()
|
||||
{
|
||||
AreaLightRequestBus::Handler::BusDisconnect(m_entityId);
|
||||
m_lightShapeDelegate.reset();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetConfiguration(const AreaLightComponentConfig& config)
|
||||
{
|
||||
m_configuration = config;
|
||||
VerifyLightTypeAndShapeComponent();
|
||||
ConfigurationChanged();
|
||||
}
|
||||
|
||||
const AreaLightComponentConfig& AreaLightComponentController::GetConfiguration() const
|
||||
{
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetVisibiliy(bool isVisible)
|
||||
{
|
||||
m_isVisible = isVisible;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetVisibility(m_isVisible);
|
||||
if (m_isVisible)
|
||||
{
|
||||
behaviorContext->EBus<AreaLightRequestBus>("AreaLightRequestBus")
|
||||
->Event("GetAttenuationRadius", &AreaLightRequestBus::Events::GetAttenuationRadius)
|
||||
->Event("SetAttenuationRadius", &AreaLightRequestBus::Events::SetAttenuationRadius)
|
||||
->Event("SetAttenuationRadiusMode", &AreaLightRequestBus::Events::SetAttenuationRadiusMode)
|
||||
->Event("GetColor", &AreaLightRequestBus::Events::GetColor)
|
||||
->Event("SetColor", &AreaLightRequestBus::Events::SetColor)
|
||||
->Event("GetEmitsLightBothDirections", &AreaLightRequestBus::Events::GetLightEmitsBothDirections)
|
||||
->Event("SetEmitsLightBothDirections", &AreaLightRequestBus::Events::SetLightEmitsBothDirections)
|
||||
->Event("GetUseFastApproximation", &AreaLightRequestBus::Events::GetUseFastApproximation)
|
||||
->Event("SetUseFastApproximation", &AreaLightRequestBus::Events::SetUseFastApproximation)
|
||||
->Event("GetIntensity", &AreaLightRequestBus::Events::GetIntensity)
|
||||
->Event("SetIntensity", static_cast<void(AreaLightRequestBus::Events::*)(float)>(&AreaLightRequestBus::Events::SetIntensity))
|
||||
->Event("GetIntensityMode", &AreaLightRequestBus::Events::GetIntensityMode)
|
||||
->Event("ConvertToIntensityMode", &AreaLightRequestBus::Events::ConvertToIntensityMode)
|
||||
->VirtualProperty("AttenuationRadius", "GetAttenuationRadius", "SetAttenuationRadius")
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("EmitsLightBothDirections", "GetEmitsLightBothDirections", "SetEmitsLightBothDirections")
|
||||
->VirtualProperty("UseFastApproximation", "GetUseFastApproximation", "SetUseFastApproximation")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
;
|
||||
// If the light is made visible, make sure to apply the configuration so all properties as set correctly.
|
||||
ConfigurationChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::VerifyLightTypeAndShapeComponent()
|
||||
{
|
||||
constexpr Crc32 SphereShapeTypeId = AZ_CRC_CE("Sphere");
|
||||
constexpr Crc32 DiskShapeTypeId = AZ_CRC_CE("DiskShape");
|
||||
constexpr Crc32 CapsuleShapeTypeId = AZ_CRC_CE("Capsule");
|
||||
constexpr Crc32 QuadShapeTypeId = AZ_CRC_CE("QuadShape");
|
||||
constexpr Crc32 PoylgonShapeTypeId = AZ_CRC_CE("PolygonPrism");
|
||||
|
||||
void AreaLightComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
if (m_configuration.m_lightType == AreaLightComponentConfig::LightType::Unknown)
|
||||
{
|
||||
provided.push_back(AZ_CRC_CE("AreaLightService"));
|
||||
}
|
||||
|
||||
void AreaLightComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("AreaLightService"));
|
||||
}
|
||||
|
||||
void AreaLightComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC_CE("AreaLightShapeService"));
|
||||
}
|
||||
|
||||
AreaLightComponentController::AreaLightComponentController(const AreaLightComponentConfig& config)
|
||||
: m_configuration(config)
|
||||
{
|
||||
}
|
||||
|
||||
void AreaLightComponentController::Activate(EntityId entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
|
||||
CreateLightShapeDelegate();
|
||||
AZ_Warning("AreaLightComponentController", m_lightShapeDelegate, "AreaLightComponentController activated without having required component.");
|
||||
|
||||
// Used to determine if the shape can be double-sided.
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(m_configuration.m_shapeType, m_entityId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetShapeType);
|
||||
|
||||
AreaLightRequestBus::Handler::BusConnect(m_entityId);
|
||||
|
||||
ConfigurationChanged();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::Deactivate()
|
||||
{
|
||||
AreaLightRequestBus::Handler::BusDisconnect(m_entityId);
|
||||
m_lightShapeDelegate.reset();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetConfiguration(const AreaLightComponentConfig& config)
|
||||
{
|
||||
m_configuration = config;
|
||||
ConfigurationChanged();
|
||||
}
|
||||
|
||||
const AreaLightComponentConfig& AreaLightComponentController::GetConfiguration() const
|
||||
{
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetVisibiliy(bool isVisible)
|
||||
{
|
||||
m_isVisible = isVisible;
|
||||
if (m_lightShapeDelegate)
|
||||
// Light type is unknown, see if it can be determined from a shape component.
|
||||
switch (m_configuration.m_shapeType)
|
||||
{
|
||||
m_lightShapeDelegate->SetVisibility(m_isVisible);
|
||||
case SphereShapeTypeId:
|
||||
m_configuration.m_lightType = AreaLightComponentConfig::LightType::Sphere;
|
||||
break;
|
||||
case DiskShapeTypeId:
|
||||
m_configuration.m_lightType = AreaLightComponentConfig::LightType::SpotDisk;
|
||||
break;
|
||||
case CapsuleShapeTypeId:
|
||||
m_configuration.m_lightType = AreaLightComponentConfig::LightType::Capsule;
|
||||
break;
|
||||
case QuadShapeTypeId:
|
||||
m_configuration.m_lightType = AreaLightComponentConfig::LightType::Quad;
|
||||
break;
|
||||
case PoylgonShapeTypeId:
|
||||
m_configuration.m_lightType = AreaLightComponentConfig::LightType::Polygon;
|
||||
break;
|
||||
default:
|
||||
break; // Light type can't be deduced.
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ConfigurationChanged()
|
||||
else if (m_configuration.m_shapeType == Crc32(0))
|
||||
{
|
||||
ChromaChanged();
|
||||
IntensityChanged();
|
||||
AttenuationRadiusChanged();
|
||||
AZ_Error("AreaLightComponentController", !m_configuration.RequiresShapeComponent(), "The light type used on this area light requires a corresponding shape component");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Validate the the light type matches up with shape type if the light type is an area light.
|
||||
AZ_Error("AreaLightComponentController",
|
||||
!(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Sphere && m_configuration.m_shapeType != SphereShapeTypeId),
|
||||
"The light type is a sphere, but the shape component is not.");
|
||||
AZ_Error("AreaLightComponentController",
|
||||
!(m_configuration.m_lightType == AreaLightComponentConfig::LightType::SpotDisk && m_configuration.m_shapeType != DiskShapeTypeId),
|
||||
"The light type is a disk, but the shape component is not.");
|
||||
AZ_Error("AreaLightComponentController",
|
||||
!(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Capsule && m_configuration.m_shapeType != CapsuleShapeTypeId),
|
||||
"The light type is a capsule, but the shape component is not.");
|
||||
AZ_Error("AreaLightComponentController",
|
||||
!(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Quad && m_configuration.m_shapeType != QuadShapeTypeId),
|
||||
"The light type is a quad, but the shape component is not.");
|
||||
AZ_Error("AreaLightComponentController",
|
||||
!(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Polygon && m_configuration.m_shapeType != PoylgonShapeTypeId),
|
||||
"The light type is a polygon, but the shape component is not.");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lightShapeDelegate)
|
||||
void AreaLightComponentController::ConfigurationChanged()
|
||||
{
|
||||
ChromaChanged();
|
||||
IntensityChanged();
|
||||
AttenuationRadiusChanged();
|
||||
ShuttersChanged();
|
||||
ShadowsChanged();
|
||||
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetLightEmitsBothDirections(m_configuration.m_lightEmitsBothDirections);
|
||||
m_lightShapeDelegate->SetUseFastApproximation(m_configuration.m_useFastApproximation);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::IntensityChanged()
|
||||
{
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnColorOrIntensityChanged, m_configuration.m_color, m_configuration.m_intensity);
|
||||
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetPhotometricUnit(m_configuration.m_intensityMode);
|
||||
m_lightShapeDelegate->SetIntensity(m_configuration.m_intensity);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ChromaChanged()
|
||||
{
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetChroma(m_configuration.m_color);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::AttenuationRadiusChanged()
|
||||
{
|
||||
if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AutoCalculateAttenuationRadius();
|
||||
}
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnAttenutationRadiusChanged, m_configuration.m_attenuationRadius);
|
||||
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetAttenuationRadius(m_configuration.m_attenuationRadius);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ShuttersChanged()
|
||||
{
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetEnableShutters(m_configuration.m_enableShutters);
|
||||
if (m_configuration.m_enableShutters)
|
||||
{
|
||||
m_lightShapeDelegate->SetLightEmitsBothDirections(m_configuration.m_lightEmitsBothDirections);
|
||||
m_lightShapeDelegate->SetUseFastApproximation(m_configuration.m_useFastApproximation);
|
||||
m_lightShapeDelegate->SetShutterAngles(m_configuration.m_innerShutterAngleDegrees, m_configuration.m_outerShutterAngleDegrees);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::IntensityChanged()
|
||||
void AreaLightComponentController::ShadowsChanged()
|
||||
{
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnColorOrIntensityChanged, m_configuration.m_color, m_configuration.m_intensity);
|
||||
|
||||
if (m_lightShapeDelegate)
|
||||
m_lightShapeDelegate->SetEnableShadow(m_configuration.m_enableShadow);
|
||||
if (m_configuration.m_enableShadow)
|
||||
{
|
||||
m_lightShapeDelegate->SetPhotometricUnit(m_configuration.m_intensityMode);
|
||||
m_lightShapeDelegate->SetIntensity(m_configuration.m_intensity);
|
||||
m_lightShapeDelegate->SetShadowmapMaxSize(m_configuration.m_shadowmapMaxSize);
|
||||
m_lightShapeDelegate->SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
|
||||
m_lightShapeDelegate->SetSofteningBoundaryWidthAngle(m_configuration.m_boundaryWidthInDegrees);
|
||||
m_lightShapeDelegate->SetPredictionSampleCount(m_configuration.m_predictionSampleCount);
|
||||
m_lightShapeDelegate->SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
m_lightShapeDelegate->SetPcfMethod(m_configuration.m_pcfMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ChromaChanged()
|
||||
void AreaLightComponentController::AutoCalculateAttenuationRadius()
|
||||
{
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetChroma(m_configuration.m_color);
|
||||
}
|
||||
m_configuration.m_attenuationRadius = m_lightShapeDelegate->CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::AttenuationRadiusChanged()
|
||||
{
|
||||
if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AutoCalculateAttenuationRadius();
|
||||
}
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnAttenutationRadiusChanged, m_configuration.m_attenuationRadius);
|
||||
const Color& AreaLightComponentController::GetColor() const
|
||||
{
|
||||
return m_configuration.m_color;
|
||||
}
|
||||
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetAttenuationRadius(m_configuration.m_attenuationRadius);
|
||||
}
|
||||
}
|
||||
void AreaLightComponentController::SetColor(const Color& color)
|
||||
{
|
||||
m_configuration.m_color = color;
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnColorChanged, color);
|
||||
ChromaChanged();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::AutoCalculateAttenuationRadius()
|
||||
{
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_configuration.m_attenuationRadius = m_lightShapeDelegate->CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity);
|
||||
}
|
||||
}
|
||||
bool AreaLightComponentController::GetLightEmitsBothDirections() const
|
||||
{
|
||||
return m_configuration.m_lightEmitsBothDirections;
|
||||
}
|
||||
|
||||
const Color& AreaLightComponentController::GetColor() const
|
||||
{
|
||||
return m_configuration.m_color;
|
||||
}
|
||||
void AreaLightComponentController::SetLightEmitsBothDirections(bool value)
|
||||
{
|
||||
m_configuration.m_lightEmitsBothDirections = value;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetColor(const Color& color)
|
||||
{
|
||||
m_configuration.m_color = color;
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnColorChanged, color);
|
||||
ChromaChanged();
|
||||
}
|
||||
bool AreaLightComponentController::GetUseFastApproximation() const
|
||||
{
|
||||
return m_configuration.m_useFastApproximation;
|
||||
}
|
||||
|
||||
bool AreaLightComponentController::GetLightEmitsBothDirections() const
|
||||
{
|
||||
return m_configuration.m_lightEmitsBothDirections;
|
||||
}
|
||||
void AreaLightComponentController::SetUseFastApproximation(bool value)
|
||||
{
|
||||
m_configuration.m_useFastApproximation = value;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetLightEmitsBothDirections(bool value)
|
||||
{
|
||||
m_configuration.m_lightEmitsBothDirections = value;
|
||||
}
|
||||
PhotometricUnit AreaLightComponentController::GetIntensityMode() const
|
||||
{
|
||||
return m_configuration.m_intensityMode;
|
||||
}
|
||||
|
||||
bool AreaLightComponentController::GetUseFastApproximation() const
|
||||
{
|
||||
return m_configuration.m_useFastApproximation;
|
||||
}
|
||||
float AreaLightComponentController::GetIntensity() const
|
||||
{
|
||||
return m_configuration.m_intensity;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetUseFastApproximation(bool value)
|
||||
{
|
||||
m_configuration.m_useFastApproximation = value;
|
||||
}
|
||||
void AreaLightComponentController::SetIntensity(float intensity, PhotometricUnit intensityMode)
|
||||
{
|
||||
m_configuration.m_intensityMode = intensityMode;
|
||||
m_configuration.m_intensity = intensity;
|
||||
|
||||
PhotometricUnit AreaLightComponentController::GetIntensityMode() const
|
||||
{
|
||||
return m_configuration.m_intensityMode;
|
||||
}
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, intensityMode);
|
||||
IntensityChanged();
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetIntensity() const
|
||||
{
|
||||
return m_configuration.m_intensity;
|
||||
}
|
||||
void AreaLightComponentController::SetIntensity(float intensity)
|
||||
{
|
||||
m_configuration.m_intensity = intensity;
|
||||
|
||||
void AreaLightComponentController::SetIntensity(float intensity, PhotometricUnit intensityMode)
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, m_configuration.m_intensityMode);
|
||||
IntensityChanged();
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetAttenuationRadius() const
|
||||
{
|
||||
return m_configuration.m_attenuationRadius;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetAttenuationRadius(float radius)
|
||||
{
|
||||
m_configuration.m_attenuationRadius = radius;
|
||||
m_configuration.m_attenuationRadiusMode = LightAttenuationRadiusMode::Explicit;
|
||||
AttenuationRadiusChanged();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode)
|
||||
{
|
||||
m_configuration.m_attenuationRadiusMode = attenuationRadiusMode;
|
||||
AttenuationRadiusChanged();
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ConvertToIntensityMode(PhotometricUnit intensityMode)
|
||||
{
|
||||
if (m_lightShapeDelegate && m_lightShapeDelegate->GetPhotometricValue().GetType() != intensityMode)
|
||||
{
|
||||
m_configuration.m_intensityMode = intensityMode;
|
||||
m_configuration.m_intensity = intensity;
|
||||
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, intensityMode);
|
||||
IntensityChanged();
|
||||
m_configuration.m_intensity = m_lightShapeDelegate->SetPhotometricUnit(intensityMode);
|
||||
}
|
||||
}
|
||||
|
||||
bool AreaLightComponentController::GetEnableShutters() const
|
||||
{
|
||||
return m_configuration.m_enableShutters;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetIntensity(float intensity)
|
||||
void AreaLightComponentController::SetEnableShutters(bool enabled)
|
||||
{
|
||||
m_configuration.m_enableShutters = enabled && m_configuration.SupportsShutters();
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_configuration.m_intensity = intensity;
|
||||
|
||||
AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, m_configuration.m_intensityMode);
|
||||
IntensityChanged();
|
||||
m_lightShapeDelegate->SetEnableShutters(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetAttenuationRadius() const
|
||||
float AreaLightComponentController::GetInnerShutterAngle() const
|
||||
{
|
||||
return m_configuration.m_innerShutterAngleDegrees;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetInnerShutterAngle(float degrees)
|
||||
{
|
||||
m_configuration.m_innerShutterAngleDegrees = degrees;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
return m_configuration.m_attenuationRadius;
|
||||
m_lightShapeDelegate->SetShutterAngles(m_configuration.m_innerShutterAngleDegrees, m_configuration.m_outerShutterAngleDegrees);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetAttenuationRadius(float radius)
|
||||
float AreaLightComponentController::GetOuterShutterAngle() const
|
||||
{
|
||||
return m_configuration.m_outerShutterAngleDegrees;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetOuterShutterAngle(float degrees)
|
||||
{
|
||||
m_configuration.m_outerShutterAngleDegrees = degrees;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_configuration.m_attenuationRadius = radius;
|
||||
m_configuration.m_attenuationRadiusMode = LightAttenuationRadiusMode::Explicit;
|
||||
AttenuationRadiusChanged();
|
||||
m_lightShapeDelegate->SetShutterAngles(m_configuration.m_innerShutterAngleDegrees, m_configuration.m_outerShutterAngleDegrees);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode)
|
||||
bool AreaLightComponentController::GetEnableShadow() const
|
||||
{
|
||||
return m_configuration.m_enableShadow;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetEnableShadow(bool enabled)
|
||||
{
|
||||
m_configuration.m_enableShadow = enabled && m_configuration.SupportsShadows();
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_configuration.m_attenuationRadiusMode = attenuationRadiusMode;
|
||||
AttenuationRadiusChanged();
|
||||
m_lightShapeDelegate->SetEnableShadow(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ConvertToIntensityMode(PhotometricUnit intensityMode)
|
||||
ShadowmapSize AreaLightComponentController::GetShadowmapMaxSize() const
|
||||
{
|
||||
return m_configuration.m_shadowmapMaxSize;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
m_configuration.m_shadowmapMaxSize = size;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
if (m_lightShapeDelegate && m_lightShapeDelegate->GetPhotometricValue().GetType() != intensityMode)
|
||||
{
|
||||
m_configuration.m_intensityMode = intensityMode;
|
||||
m_configuration.m_intensity = m_lightShapeDelegate->SetPhotometricUnit(intensityMode);
|
||||
}
|
||||
m_lightShapeDelegate->SetShadowmapMaxSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::HandleDisplayEntityViewport(
|
||||
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay,
|
||||
bool isSelected)
|
||||
ShadowFilterMethod AreaLightComponentController::GetShadowFilterMethod() const
|
||||
{
|
||||
return m_configuration.m_shadowFilterMethod;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetShadowFilterMethod(ShadowFilterMethod method)
|
||||
{
|
||||
m_configuration.m_shadowFilterMethod = method;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
Transform transform = Transform::CreateIdentity();
|
||||
TransformBus::EventResult(transform, m_entityId, &TransformBus::Events::GetWorldTM);
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->DrawDebugDisplay(transform, m_configuration.m_color, debugDisplay, isSelected);
|
||||
}
|
||||
m_lightShapeDelegate->SetShadowFilterMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::CreateLightShapeDelegate()
|
||||
float AreaLightComponentController::GetSofteningBoundaryWidthAngle() const
|
||||
{
|
||||
return m_configuration.m_boundaryWidthInDegrees;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetSofteningBoundaryWidthAngle(float width)
|
||||
{
|
||||
m_configuration.m_boundaryWidthInDegrees = width;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetSofteningBoundaryWidthAngle(width);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AreaLightComponentController::GetPredictionSampleCount() const
|
||||
{
|
||||
return m_configuration.m_predictionSampleCount;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetPredictionSampleCount(uint32_t count)
|
||||
{
|
||||
m_configuration.m_predictionSampleCount = count;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetPredictionSampleCount(count);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AreaLightComponentController::GetFilteringSampleCount() const
|
||||
{
|
||||
return m_configuration.m_filteringSampleCount;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
m_configuration.m_filteringSampleCount = count;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetFilteringSampleCount(count);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::HandleDisplayEntityViewport(
|
||||
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay,
|
||||
bool isSelected)
|
||||
{
|
||||
Transform transform = Transform::CreateIdentity();
|
||||
TransformBus::EventResult(transform, m_entityId, &TransformBus::Events::GetWorldTM);
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->DrawDebugDisplay(transform, m_configuration.m_color, debugDisplay, isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
PcfMethod AreaLightComponentController::GetPcfMethod() const
|
||||
{
|
||||
return m_configuration.m_pcfMethod;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetPcfMethod(PcfMethod method)
|
||||
{
|
||||
m_configuration.m_pcfMethod = method;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetPcfMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::CreateLightShapeDelegate()
|
||||
{
|
||||
switch (m_configuration.m_lightType)
|
||||
{
|
||||
|
||||
// Simple types
|
||||
case AreaLightComponentConfig::LightType::SimplePoint:
|
||||
m_lightShapeDelegate = AZStd::make_unique<SimplePointLightDelegate>(m_entityId, m_isVisible);
|
||||
break;
|
||||
case AreaLightComponentConfig::LightType::SimpleSpot:
|
||||
m_lightShapeDelegate = AZStd::make_unique<SimpleSpotLightDelegate>(m_entityId, m_isVisible);
|
||||
break;
|
||||
|
||||
// Area light types
|
||||
case AreaLightComponentConfig::LightType::Sphere:
|
||||
{
|
||||
LmbrCentral::SphereShapeComponentRequests* sphereShapeInterface = LmbrCentral::SphereShapeComponentRequestsBus::FindFirstHandler(m_entityId);
|
||||
if (sphereShapeInterface)
|
||||
{
|
||||
m_lightShapeDelegate = AZStd::make_unique<SphereLightDelegate>(sphereShapeInterface, m_entityId, m_isVisible);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AreaLightComponentConfig::LightType::SpotDisk:
|
||||
{
|
||||
LmbrCentral::DiskShapeComponentRequests* diskShapeInterface = LmbrCentral::DiskShapeComponentRequestBus::FindFirstHandler(m_entityId);
|
||||
if (diskShapeInterface)
|
||||
{
|
||||
m_lightShapeDelegate = AZStd::make_unique<DiskLightDelegate>(diskShapeInterface, m_entityId, m_isVisible);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AreaLightComponentConfig::LightType::Capsule:
|
||||
{
|
||||
LmbrCentral::CapsuleShapeComponentRequests* capsuleShapeInterface = LmbrCentral::CapsuleShapeComponentRequestsBus::FindFirstHandler(m_entityId);
|
||||
if (capsuleShapeInterface)
|
||||
{
|
||||
m_lightShapeDelegate = AZStd::make_unique<CapsuleLightDelegate>(capsuleShapeInterface, m_entityId, m_isVisible);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AreaLightComponentConfig::LightType::Quad:
|
||||
{
|
||||
LmbrCentral::QuadShapeComponentRequests* quadShapeInterface = LmbrCentral::QuadShapeComponentRequestBus::FindFirstHandler(m_entityId);
|
||||
if (quadShapeInterface)
|
||||
{
|
||||
m_lightShapeDelegate = AZStd::make_unique<QuadLightDelegate>(quadShapeInterface, m_entityId, m_isVisible);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AreaLightComponentConfig::LightType::Polygon:
|
||||
{
|
||||
LmbrCentral::PolygonPrismShapeComponentRequests* polyPrismShapeInterface = LmbrCentral::PolygonPrismShapeComponentRequestBus::FindFirstHandler(m_entityId);
|
||||
if (polyPrismShapeInterface)
|
||||
{
|
||||
m_lightShapeDelegate = AZStd::make_unique<PolygonLightDelegate>(polyPrismShapeInterface, m_entityId, m_isVisible);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
} // namespace AZ::Render
|
||||
|
||||
+27
-1
@@ -38,7 +38,7 @@ namespace AZ
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
AreaLightComponentController() = default;
|
||||
AreaLightComponentController(const AreaLightComponentConfig& config);
|
||||
@@ -71,15 +71,41 @@ namespace AZ
|
||||
void SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode) override;
|
||||
void ConvertToIntensityMode(PhotometricUnit intensityMode) override;
|
||||
|
||||
bool GetEnableShutters() const override;
|
||||
void SetEnableShutters(bool enabled) override;
|
||||
float GetInnerShutterAngle() const override;
|
||||
void SetInnerShutterAngle(float degrees) override;
|
||||
float GetOuterShutterAngle() const override;
|
||||
void SetOuterShutterAngle(float degrees) override;
|
||||
|
||||
bool GetEnableShadow() const override;
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
ShadowmapSize GetShadowmapMaxSize() const override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
ShadowFilterMethod GetShadowFilterMethod() const override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
float GetSofteningBoundaryWidthAngle() const override;
|
||||
void SetSofteningBoundaryWidthAngle(float width) override;
|
||||
uint32_t GetPredictionSampleCount() const override;
|
||||
void SetPredictionSampleCount(uint32_t count) override;
|
||||
uint32_t GetFilteringSampleCount() const override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
PcfMethod GetPcfMethod() const override;
|
||||
void SetPcfMethod(PcfMethod method) override;
|
||||
|
||||
void HandleDisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay,
|
||||
bool isSelected);
|
||||
|
||||
void VerifyLightTypeAndShapeComponent();
|
||||
|
||||
void ConfigurationChanged();
|
||||
void IntensityChanged();
|
||||
void ChromaChanged();
|
||||
void AttenuationRadiusChanged();
|
||||
void ShuttersChanged();
|
||||
void ShadowsChanged();
|
||||
|
||||
//! Handles calculating the attenuation radius when LightAttenuationRadiusMode is auto
|
||||
void AutoCalculateAttenuationRadius();
|
||||
|
||||
+13
-2
@@ -24,7 +24,7 @@ namespace AZ
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<DirectionalLightComponentConfig, ComponentConfig>()
|
||||
->Version(6)
|
||||
->Version(7)
|
||||
->Field("Color", &DirectionalLightComponentConfig::m_color)
|
||||
->Field("IntensityMode", &DirectionalLightComponentConfig::m_intensityMode)
|
||||
->Field("Intensity", &DirectionalLightComponentConfig::m_intensity)
|
||||
@@ -43,7 +43,8 @@ namespace AZ
|
||||
->Field("SofteningBoundaryWidth", &DirectionalLightComponentConfig::m_boundaryWidth)
|
||||
->Field("PcfPredictionSampleCount", &DirectionalLightComponentConfig::m_predictionSampleCount)
|
||||
->Field("PcfFilteringSampleCount", &DirectionalLightComponentConfig::m_filteringSampleCount)
|
||||
;
|
||||
->Field("Pcf Method", &DirectionalLightComponentConfig::m_pcfMethod)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,5 +127,15 @@ namespace AZ
|
||||
m_shadowFilterMethod == ShadowFilterMethod::EsmPcf);
|
||||
}
|
||||
|
||||
bool DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled() const
|
||||
{
|
||||
if (IsShadowPcfDisabled())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_pcfMethod != PcfMethod::BoundarySearch;
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+15
-1
@@ -87,6 +87,8 @@ namespace AZ
|
||||
->Event("SetPredictionSampleCount", &DirectionalLightRequestBus::Events::SetPredictionSampleCount)
|
||||
->Event("GetFilteringSampleCount", &DirectionalLightRequestBus::Events::GetFilteringSampleCount)
|
||||
->Event("SetFilteringSampleCount", &DirectionalLightRequestBus::Events::SetFilteringSampleCount)
|
||||
->Event("GetPcfMethod", &DirectionalLightRequestBus::Events::GetPcfMethod)
|
||||
->Event("SetPcfMethod", &DirectionalLightRequestBus::Events::SetPcfMethod)
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
->VirtualProperty("AngularDiameter", "GetAngularDiameter", "SetAngularDiameter")
|
||||
@@ -103,7 +105,8 @@ namespace AZ
|
||||
->VirtualProperty("SofteningBoundaryWidth", "GetSofteningBoundaryWidth", "SetSofteningBoundaryWidth")
|
||||
->VirtualProperty("PredictionSampleCount", "GetPredictionSampleCount", "SetPredictionSampleCount")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
;
|
||||
->VirtualProperty("PcfMethod", "GetPcfMethod", "SetPcfMethod");
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,6 +537,7 @@ namespace AZ
|
||||
SetSofteningBoundaryWidth(m_configuration.m_boundaryWidth);
|
||||
SetPredictionSampleCount(m_configuration.m_predictionSampleCount);
|
||||
SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
SetPcfMethod(m_configuration.m_pcfMethod);
|
||||
|
||||
// [GFX TODO][ATOM-1726] share config for multiple light (e.g., light ID).
|
||||
// [GFX TODO][ATOM-2416] adapt to multiple viewports.
|
||||
@@ -620,6 +624,16 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
PcfMethod DirectionalLightComponentController::GetPcfMethod() const
|
||||
{
|
||||
return m_configuration.m_pcfMethod;
|
||||
}
|
||||
|
||||
void DirectionalLightComponentController::SetPcfMethod(PcfMethod method)
|
||||
{
|
||||
m_configuration.m_pcfMethod = method;
|
||||
m_featureProcessor->SetPcfMethod(m_lightHandle, method);
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+2
@@ -86,6 +86,8 @@ namespace AZ
|
||||
void SetPredictionSampleCount(uint32_t count) override;
|
||||
uint32_t GetFilteringSampleCount() const override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
PcfMethod GetPcfMethod() const override;
|
||||
void SetPcfMethod(PcfMethod method) override;
|
||||
|
||||
private:
|
||||
friend class EditorDirectionalLightComponent;
|
||||
|
||||
+104
-45
@@ -14,62 +14,121 @@
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Render
|
||||
{
|
||||
namespace Render
|
||||
DiskLightDelegate::DiskLightDelegate(LmbrCentral::DiskShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible)
|
||||
: LightDelegateBase<DiskLightFeatureProcessorInterface>(entityId, isVisible)
|
||||
, m_shapeBus(shapeBus)
|
||||
{
|
||||
DiskLightDelegate::DiskLightDelegate(LmbrCentral::DiskShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible)
|
||||
: LightDelegateBase<DiskLightFeatureProcessorInterface>(entityId, isVisible)
|
||||
, m_shapeBus(shapeBus)
|
||||
{
|
||||
InitBase(entityId);
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetLightEmitsBothDirections(bool lightEmitsBothDirections)
|
||||
{
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetLightEmitsBothDirections(GetLightHandle(), lightEmitsBothDirections);
|
||||
}
|
||||
}
|
||||
InitBase(entityId);
|
||||
}
|
||||
|
||||
float DiskLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
|
||||
{
|
||||
// Calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
return sqrt(intensity / lightThreshold);
|
||||
}
|
||||
float DiskLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
|
||||
{
|
||||
// Calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
return sqrt(intensity / lightThreshold);
|
||||
}
|
||||
|
||||
void DiskLightDelegate::HandleShapeChanged()
|
||||
void DiskLightDelegate::HandleShapeChanged()
|
||||
{
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
GetFeatureProcessor()->SetDirection(GetLightHandle(), m_shapeBus->GetNormal());
|
||||
GetFeatureProcessor()->SetDiskRadius(GetLightHandle(), GetRadius());
|
||||
}
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
GetFeatureProcessor()->SetDirection(GetLightHandle(), m_shapeBus->GetNormal());
|
||||
GetFeatureProcessor()->SetDiskRadius(GetLightHandle(), GetRadius());
|
||||
}
|
||||
}
|
||||
|
||||
float DiskLightDelegate::GetSurfaceArea() const
|
||||
float DiskLightDelegate::GetSurfaceArea() const
|
||||
{
|
||||
float radius = GetRadius();
|
||||
return Constants::Pi * radius * radius;
|
||||
}
|
||||
|
||||
float DiskLightDelegate::GetRadius() const
|
||||
{
|
||||
return m_shapeBus->GetRadius() * GetTransform().GetScale().GetMaxElement();
|
||||
}
|
||||
|
||||
void DiskLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
float radius = GetRadius();
|
||||
return Constants::Pi * radius * radius;
|
||||
}
|
||||
debugDisplay.SetColor(color);
|
||||
|
||||
float DiskLightDelegate::GetRadius() const
|
||||
// Draw a disk for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity));
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetEnableShutters(bool enabled)
|
||||
{
|
||||
Base::SetEnableShutters(enabled);
|
||||
GetFeatureProcessor()->SetConstrainToConeLight(GetLightHandle(), true);
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees)
|
||||
{
|
||||
if (GetShuttersEnabled())
|
||||
{
|
||||
return m_shapeBus->GetRadius() * GetTransform().GetScale().GetMaxElement();
|
||||
GetFeatureProcessor()->SetConeAngles(GetLightHandle(), DegToRad(innerAngleDegrees), DegToRad(outerAngleDegrees));
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
void DiskLightDelegate::SetEnableShadow(bool enabled)
|
||||
{
|
||||
Base::SetEnableShadow(enabled);
|
||||
GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled);
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
if (GetShadowsEnabled())
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
debugDisplay.SetColor(color);
|
||||
|
||||
// Draw a disk for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity));
|
||||
}
|
||||
GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size);
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method)
|
||||
{
|
||||
if (GetShadowsEnabled())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
|
||||
{
|
||||
if (GetShadowsEnabled())
|
||||
{
|
||||
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetPredictionSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled())
|
||||
{
|
||||
GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled())
|
||||
{
|
||||
GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetPcfMethod(PcfMethod method)
|
||||
{
|
||||
if (GetShadowsEnabled())
|
||||
{
|
||||
GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace AZ::Render
|
||||
|
||||
@@ -30,16 +30,28 @@ namespace AZ
|
||||
class DiskLightDelegate final
|
||||
: public LightDelegateBase<DiskLightFeatureProcessorInterface>
|
||||
{
|
||||
using Base = LightDelegateBase<DiskLightFeatureProcessorInterface>;
|
||||
|
||||
public:
|
||||
DiskLightDelegate(LmbrCentral::DiskShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible);
|
||||
|
||||
// LightDelegateBase overrides...
|
||||
void SetLightEmitsBothDirections(bool lightEmitsBothDirections) override;
|
||||
float GetSurfaceArea() const override;
|
||||
float GetEffectiveSolidAngle() const override { return PhotometricValue::DirectionalEffectiveSteradians; }
|
||||
float CalculateAttenuationRadius(float lightThreshold) const override;
|
||||
void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const override;
|
||||
|
||||
void SetEnableShutters(bool enabled) override;
|
||||
void SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees) override;
|
||||
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
|
||||
void SetPredictionSampleCount(uint32_t count) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetPcfMethod(PcfMethod method) override;
|
||||
|
||||
private:
|
||||
|
||||
// LightDelegateBase overrides...
|
||||
|
||||
+249
-37
@@ -13,10 +13,17 @@
|
||||
#include <CoreLights/EditorAreaLightComponent.h>
|
||||
|
||||
#include <Atom/RPI.Edit/Common/ColorUtils.h>
|
||||
#include <AzToolsFramework/Component/EditorComponentAPIBus.h>
|
||||
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
|
||||
#include <LmbrCentral/Shape/ShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/EditorShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/SphereShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/DiskShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/CapsuleShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/QuadShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/PolygonPrismShapeComponentBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -27,65 +34,145 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
|
||||
void EditorAreaLightComponent::Reflect(AZ::ReflectContext* context)
|
||||
void EditorAreaLightComponent::Reflect(ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorAreaLightComponent, BaseClass>()
|
||||
->Version(1, ConvertToEditorRenderComponentAdapter<1>);
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
if (EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorAreaLightComponent>(
|
||||
"Area Light", "An Area light emits light emits light from a goemetric shape.")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Atom")
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "editor/icons/components/viewport/component_placeholder.png")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-area-light.html")
|
||||
"Light", "A light which emits from a point or goemetric shape.")
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->Attribute(Edit::Attributes::Category, "Atom")
|
||||
->Attribute(Edit::Attributes::Icon, "Editor/Icons/Components/Component_Placeholder.svg")
|
||||
->Attribute(Edit::Attributes::ViewportIcon, "editor/icons/components/viewport/component_placeholder.png")
|
||||
->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-light.html")
|
||||
;
|
||||
|
||||
editContext->Class<AreaLightComponentController>(
|
||||
"AreaLightComponentController", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AreaLightComponentController::m_configuration, "Configuration", "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentController::m_configuration, "Configuration", "")
|
||||
->Attribute(Edit::Attributes::Visibility, Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
|
||||
editContext->Class<AreaLightComponentConfig>(
|
||||
"AreaLightComponentConfig", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &AreaLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity Mode", "Allows specifying which photometric unit to work in.")
|
||||
->EnumAttribute(PhotometricUnit::Candela, "Candela")
|
||||
->EnumAttribute(PhotometricUnit::Lumen, "Lumen")
|
||||
->EnumAttribute(PhotometricUnit::Nit, "Nit")
|
||||
->EnumAttribute(PhotometricUnit::Ev100Luminance, "Ev100")
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_lightType, "Light Type", "Which type of light this component represents.")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Unknown, "Choose a Light Type")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Sphere, "Point (Sphere)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SimplePoint, "Point (Simple)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SpotDisk, "Spot (Disk)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SimpleSpot, "Spot (Simple)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Capsule, "Capsule")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Quad, "Quad")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Polygon, "Polygon")
|
||||
->DataElement(Edit::UIHandlers::Color, &AreaLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity Mode", "Allows specifying which photometric unit to work in.")
|
||||
->Attribute(AZ::Edit::Attributes::EnumValues, &AreaLightComponentConfig::GetValidPhotometricUnits)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_intensity, "Intensity", "Intensity of the light in the set photometric unit.")
|
||||
->Attribute(Edit::Attributes::Min, &AreaLightComponentConfig::GetIntensityMin)
|
||||
->Attribute(Edit::Attributes::Max, &AreaLightComponentConfig::GetIntensityMax)
|
||||
->Attribute(Edit::Attributes::SoftMin, &AreaLightComponentConfig::GetIntensitySoftMin)
|
||||
->Attribute(Edit::Attributes::SoftMax, &AreaLightComponentConfig::GetIntensitySoftMax)
|
||||
->Attribute(Edit::Attributes::Suffix, &AreaLightComponentConfig::GetIntensitySuffix)
|
||||
->DataElement(AZ::Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_lightEmitsBothDirections, "Both Directions", "Whether light should emit from both sides of the surface or just the front")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &AreaLightComponentConfig::Is2DSurface)
|
||||
->DataElement(AZ::Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_useFastApproximation, "Fast Approximation", "Whether the light should use the default high quality linear transformed cosine technique or a faster approximation.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsFastApproximation)
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Attenuation Radius")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_attenuationRadiusMode, "Mode", "Controls whether the attenation radius is calculated automatically or set explicitly.")
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_lightEmitsBothDirections, "Both Directions", "Whether light should emit from both sides of the surface or just the front")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsBothDirections)
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_useFastApproximation, "Fast Approximation", "Whether the light should use the default high quality linear transformed cosine technique or a faster approximation.")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsFastApproximation)
|
||||
->ClassElement(Edit::ClassElements::Group, "Attenuation Radius")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_attenuationRadiusMode, "Mode", "Controls whether the attenation radius is calculated automatically or set explicitly.")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Automatic, "Automatic")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Explicit, "Explicit")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AreaLightComponentConfig::m_attenuationRadius, "Radius", "The distance at which this light no longer has an affect.")
|
||||
->Attribute(AZ::Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsAttenuationRadiusModeAutomatic)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_attenuationRadius, "Radius", "The distance at which this light no longer has an affect.")
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsAttenuationRadiusModeAutomatic)
|
||||
|
||||
->ClassElement(Edit::ClassElements::Group, "Shutters")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShutters)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_enableShutters, "Enable Shutters", "Restrict the light to a specific beam angle depending on shape.")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::ShuttersMustBeEnabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_innerShutterAngleDegrees, "Inner Angle", "The inner angle of the shutters where the light beam begins to be occluded.")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 180.0f)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShutters)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShuttersDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_outerShutterAngleDegrees, "Outer Angle", "The outer angle of the shutters where the light beam is completely occluded.")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 180.0f)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShutters)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShuttersDisabled)
|
||||
|
||||
->ClassElement(Edit::ClassElements::Group, "Shadows")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_enableShadow, "Enable Shadow", "Enable shadow for the light")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowmapMaxSize, "Shadowmap Size", "Width/Height of shadowmap")
|
||||
->EnumAttribute(ShadowmapSize::Size256, " 256")
|
||||
->EnumAttribute(ShadowmapSize::Size512, " 512")
|
||||
->EnumAttribute(ShadowmapSize::Size1024, "1024")
|
||||
->EnumAttribute(ShadowmapSize::Size2048, "2048")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowFilterMethod, "Shadow Filter Method",
|
||||
"Filtering method of edge-softening of shadows.\n"
|
||||
" None: no filtering\n"
|
||||
" PCF: Percentage-Closer Filtering\n"
|
||||
" ESM: Exponential Shadow Maps\n"
|
||||
" ESM+PCF: ESM with a PCF fallback\n"
|
||||
"For BehaviorContext (or TrackView), None=0, PCF=1, ESM=2, ESM+PCF=3")
|
||||
->EnumAttribute(ShadowFilterMethod::None, "None")
|
||||
->EnumAttribute(ShadowFilterMethod::Pcf, "PCF")
|
||||
->EnumAttribute(ShadowFilterMethod::Esm, "ESM")
|
||||
->EnumAttribute(ShadowFilterMethod::EsmPcf, "ESM+PCF")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_boundaryWidthInDegrees, "Softening Boundary Width",
|
||||
"Width of the boundary between shadowed area and lit one. "
|
||||
"Units are in degrees. "
|
||||
"If this is 0, softening edge is disabled.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 1.f)
|
||||
->Attribute(Edit::Attributes::Suffix, " deg")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_predictionSampleCount, "Prediction Sample Count",
|
||||
"Sample Count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 16)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_filteringSampleCount, "Filtering Sample Count",
|
||||
"It is used only when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 64)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "Pcf Method",
|
||||
"Type of Pcf to use.\n"
|
||||
" Boundary search: do several taps to first determine if we are on a shadow boundary\n"
|
||||
" Bicubic: a smooth, fixed-size kernel \n")
|
||||
->EnumAttribute(PcfMethod::BoundarySearch, "Boundary Search")
|
||||
->EnumAttribute(PcfMethod::Bicubic, "Bicubic")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled);
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -95,8 +182,8 @@ namespace AZ
|
||||
behaviorContext->Class<EditorAreaLightComponent>()->RequestBus("AreaLightRequestBus");
|
||||
|
||||
behaviorContext->ConstantProperty("EditorAreaLightComponentTypeId", BehaviorConstant(Uuid(EditorAreaLightComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation);
|
||||
->Attribute(Script::Attributes::Module, "render")
|
||||
->Attribute(Script::Attributes::Scope, Script::Attributes::ScopeFlags::Automation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,14 +206,139 @@ namespace AZ
|
||||
BaseClass::Deactivate();
|
||||
}
|
||||
|
||||
AZ::u32 EditorAreaLightComponent::OnConfigurationChanged()
|
||||
bool EditorAreaLightComponent::HandleLightTypeChange()
|
||||
{
|
||||
if (m_lightType == AreaLightComponentConfig::LightType::Unknown)
|
||||
{
|
||||
// Light type is unknown, see if it can be determined from a shape component.
|
||||
Crc32 shapeType = Crc32(0);
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(shapeType, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetShapeType);
|
||||
|
||||
constexpr Crc32 SphereShapeTypeId = AZ_CRC_CE("Sphere");
|
||||
constexpr Crc32 DiskShapeTypeId = AZ_CRC_CE("DiskShape");
|
||||
constexpr Crc32 CapsuleShapeTypeId = AZ_CRC_CE("Capsule");
|
||||
constexpr Crc32 QuadShapeTypeId = AZ_CRC_CE("QuadShape");
|
||||
constexpr Crc32 PoylgonShapeTypeId = AZ_CRC_CE("PolygonPrism");
|
||||
|
||||
switch (shapeType)
|
||||
{
|
||||
case SphereShapeTypeId:
|
||||
m_lightType = AreaLightComponentConfig::LightType::Sphere;
|
||||
break;
|
||||
case DiskShapeTypeId:
|
||||
m_lightType = AreaLightComponentConfig::LightType::SpotDisk;
|
||||
break;
|
||||
case CapsuleShapeTypeId:
|
||||
m_lightType = AreaLightComponentConfig::LightType::Capsule;
|
||||
break;
|
||||
case QuadShapeTypeId:
|
||||
m_lightType = AreaLightComponentConfig::LightType::Quad;
|
||||
break;
|
||||
case PoylgonShapeTypeId:
|
||||
m_lightType = AreaLightComponentConfig::LightType::Polygon;
|
||||
break;
|
||||
default:
|
||||
break; // Light type can't be deduced.
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lightType == m_controller.m_configuration.m_lightType)
|
||||
{
|
||||
// No change, nothing to do
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the cached light type.
|
||||
m_lightType = m_controller.m_configuration.m_lightType;
|
||||
|
||||
// componets may be removed or added here, so deactivate now and reactivate the entity when everything is done shifting around.
|
||||
GetEntity()->Deactivate();
|
||||
|
||||
// Check if there is already a shape components and remove it.
|
||||
for (Component* component : GetEntity()->GetComponents())
|
||||
{
|
||||
ComponentDescriptor::DependencyArrayType provided;
|
||||
ComponentDescriptor* componentDescriptor = nullptr;
|
||||
EBUS_EVENT_ID_RESULT(componentDescriptor, component->RTTI_GetType(), ComponentDescriptorBus, GetDescriptor);
|
||||
AZ_Assert(componentDescriptor, "Component class %s descriptor is not created! It must be before you can use it!", component->RTTI_GetTypeName());
|
||||
componentDescriptor->GetProvidedServices(provided, component);
|
||||
auto providedItr = AZStd::find(provided.begin(), provided.end(), AZ_CRC_CE("ShapeService"));
|
||||
if (providedItr != provided.end())
|
||||
{
|
||||
AZStd::vector<Component*> componentsToRemove = { component };
|
||||
AzToolsFramework::EntityCompositionRequests::RemoveComponentsOutcome outcome =
|
||||
AZ::Failure(AZStd::string("Failed to remove old shape component."));
|
||||
AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, &AzToolsFramework::EntityCompositionRequests::RemoveComponents, componentsToRemove);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new shape component for light types that require it.
|
||||
|
||||
auto addComponentOfType = [&](AZ::Uuid type)
|
||||
{
|
||||
AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome outcome =
|
||||
AZ::Failure(AZStd::string("Failed to add shape component for light type"));
|
||||
|
||||
const AZStd::vector<AZ::EntityId> entityList = { GetEntityId() };
|
||||
|
||||
AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities,
|
||||
entityList, ComponentTypeList({ type }));
|
||||
};
|
||||
|
||||
switch (m_lightType)
|
||||
{
|
||||
case AreaLightComponentConfig::LightType::Sphere:
|
||||
addComponentOfType(LmbrCentral::EditorSphereShapeComponentTypeId);
|
||||
break;
|
||||
case AreaLightComponentConfig::LightType::SpotDisk:
|
||||
addComponentOfType(LmbrCentral::EditorDiskShapeComponentTypeId);
|
||||
break;
|
||||
case AreaLightComponentConfig::LightType::Capsule:
|
||||
addComponentOfType(LmbrCentral::EditorCapsuleShapeComponentTypeId);
|
||||
break;
|
||||
case AreaLightComponentConfig::LightType::Quad:
|
||||
addComponentOfType(LmbrCentral::EditorQuadShapeComponentTypeId);
|
||||
break;
|
||||
case AreaLightComponentConfig::LightType::Polygon:
|
||||
addComponentOfType(LmbrCentral::EditorPolygonPrismShapeComponentTypeId);
|
||||
break;
|
||||
default:
|
||||
// Some light types don't require a shape, this is ok.
|
||||
break;
|
||||
}
|
||||
|
||||
GetEntity()->Activate();
|
||||
|
||||
// Set more reasonable default values for certain shapes.
|
||||
switch (m_lightType)
|
||||
{
|
||||
case AreaLightComponentConfig::LightType::Sphere:
|
||||
LmbrCentral::SphereShapeComponentRequestsBus::Event(GetEntityId(), &LmbrCentral::SphereShapeComponentRequests::SetRadius, 0.05f);
|
||||
break;
|
||||
case AreaLightComponentConfig::LightType::SpotDisk:
|
||||
LmbrCentral::DiskShapeComponentRequestBus::Event(GetEntityId(), &LmbrCentral::DiskShapeComponentRequests::SetRadius, 0.05f);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 EditorAreaLightComponent::OnConfigurationChanged()
|
||||
{
|
||||
bool needsFullRefresh = HandleLightTypeChange();
|
||||
|
||||
LmbrCentral::EditorShapeComponentRequestsBus::Event(GetEntityId(), &LmbrCentral::EditorShapeComponentRequests::SetShapeColor, m_controller.m_configuration.m_color);
|
||||
|
||||
// If photometric unit changes, convert the intensities so the actual intensity doesn't change.
|
||||
m_controller.ConvertToIntensityMode(m_controller.m_configuration.m_intensityMode);
|
||||
|
||||
BaseClass::OnConfigurationChanged();
|
||||
|
||||
if (needsFullRefresh)
|
||||
{
|
||||
return Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
return Edit::PropertyRefreshLevels::AttributesAndValues;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -52,7 +52,11 @@ namespace AZ
|
||||
// EditorRenderComponentAdapter overrides...
|
||||
bool ShouldActivateController() const override;
|
||||
|
||||
AZ::u32 OnConfigurationChanged() override;
|
||||
bool HandleLightTypeChange();
|
||||
|
||||
u32 OnConfigurationChanged() override;
|
||||
|
||||
AreaLightComponentConfig::LightType m_lightType; // Used to detect when the configuration's light type changes.
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
|
||||
+13
-3
@@ -145,14 +145,14 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Max, 0.1f)
|
||||
->Attribute(Edit::Attributes::Suffix, " m")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowFilteringDisabled)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_predictionSampleCount, "Prediction Sample Count",
|
||||
"Sample Count for prediction of whether the pixel is on the boundary. "
|
||||
"Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 16)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering Sample Count",
|
||||
"It is used only when the pixel is predicted as on the boundary. "
|
||||
"Specific to PCF and ESM+PCF.")
|
||||
@@ -160,7 +160,17 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Max, 64)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
|
||||
;
|
||||
->DataElement(
|
||||
Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_pcfMethod, "Pcf Method",
|
||||
"Type of Pcf to use.\n"
|
||||
" Boundary search: do several taps to first determine if we are on a shadow boundary\n"
|
||||
" Bicubic: a smooth, fixed-size kernel \n")
|
||||
->EnumAttribute(PcfMethod::BoundarySearch, "Boundary Search")
|
||||
->EnumAttribute(PcfMethod::Bicubic, "Bicubic")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled);
|
||||
;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-206
@@ -1,206 +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 <CoreLights/EditorPointLightComponent.h>
|
||||
|
||||
#include <Atom/RPI.Edit/Common/ColorUtils.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzCore/Math/IntersectSegment.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
EditorPointLightComponent::EditorPointLightComponent(const PointLightComponentConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
|
||||
void EditorPointLightComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorPointLightComponent, BaseClass>()
|
||||
->Version(1, ConvertToEditorRenderComponentAdapter<1>);
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorPointLightComponent>(
|
||||
"Point Light", "A point light emits light in all directions from a single point in space.")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Atom")
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "editor/icons/components/viewport/component_placeholder.png")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-point-light.html")
|
||||
;
|
||||
|
||||
editContext->Class<PointLightComponentController>(
|
||||
"PointLightComponentController", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &PointLightComponentController::m_configuration, "Configuration", "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
|
||||
editContext->Class<PointLightComponentConfig>(
|
||||
"PointLightComponentConfig", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &PointLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &PointLightComponentConfig::m_intensityMode, "Intensity Mode", "Allows specifying light values in candelas or lumens")
|
||||
->EnumAttribute(PhotometricUnit::Candela, "Candela")
|
||||
->EnumAttribute(PhotometricUnit::Lumen, "Lumen")
|
||||
->EnumAttribute(PhotometricUnit::Nit, "Nit")
|
||||
->EnumAttribute(PhotometricUnit::Ev100Luminance, "Ev100")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &PointLightComponentConfig::m_intensity, "Intensity", "Intensity of the light")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, &PointLightComponentConfig::GetIntensitySuffix)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &PointLightComponentConfig::m_bulbRadius, "Bulb Radius", "The size of the bulb in meters")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 100000.0f)
|
||||
->Attribute(AZ::Edit::Attributes::SoftMin, 0.01f)
|
||||
->Attribute(AZ::Edit::Attributes::SoftMax, 1.0f)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " m")
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Attenuation Radius")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &PointLightComponentConfig::m_attenuationRadiusMode, "Mode", "Controls whether the attenation radius is calculated automatically or set explicitly.")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Automatic, "Automatic")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Explicit, "Explicit")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &PointLightComponentConfig::m_attenuationRadius, "Radius", "The distance at which this light no longer has an affect.")
|
||||
->Attribute(AZ::Edit::Attributes::ReadOnly, &PointLightComponentConfig::IsAttenuationRadiusModeAutomatic)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<EditorPointLightComponent>()->RequestBus("PointLightRequestBus");
|
||||
|
||||
behaviorContext->ConstantProperty("EditorPointLightComponentTypeId", BehaviorConstant(Uuid(EditorPointLightComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPointLightComponent::Activate()
|
||||
{
|
||||
BaseClass::Activate();
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId());
|
||||
AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusConnect(GetEntityId());
|
||||
TransformNotificationBus::Handler::BusConnect(GetEntityId());
|
||||
AzFramework::BoundsRequestBus::Handler::BusConnect(GetEntityId());
|
||||
}
|
||||
|
||||
void EditorPointLightComponent::Deactivate()
|
||||
{
|
||||
AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusDisconnect();
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
|
||||
BaseClass::Deactivate();
|
||||
}
|
||||
|
||||
AZStd::tuple<float, Vector3> EditorPointLightComponent::GetRadiusAndPosition() const
|
||||
{
|
||||
Vector3 position = Vector3::CreateZero();
|
||||
AZ::TransformBus::EventResult(position, GetEntityId(), &AZ::TransformBus::Events::GetWorldTranslation);
|
||||
return AZStd::tuple<float, Vector3>(m_controller.GetBulbRadius(), position);
|
||||
}
|
||||
|
||||
AZStd::tuple<float, Vector3> EditorPointLightComponent::GetViewportRadiusAndPosition(const AzFramework::ViewportInfo& viewportInfo) const
|
||||
{
|
||||
const auto [radius, position] = GetRadiusAndPosition();
|
||||
|
||||
constexpr float PixelRadius = 10.0f;
|
||||
const AzFramework::CameraState cameraState = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId);
|
||||
const float distance = cameraState.m_position.GetDistance(position);
|
||||
const float screenScale = (distance * cameraState.m_fovOrZoom) / cameraState.m_viewportSize.GetX();
|
||||
|
||||
return AZStd::tuple<float, Vector3>(AZ::GetMax(radius, screenScale * PixelRadius), position);
|
||||
}
|
||||
|
||||
void EditorPointLightComponent::DisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
debugDisplay.SetColor(m_controller.GetColor());
|
||||
|
||||
// Draw a sphere for the light itself.
|
||||
auto [sphereSize, position] = GetViewportRadiusAndPosition(viewportInfo);
|
||||
debugDisplay.DrawWireSphere(position, sphereSize);
|
||||
|
||||
// Don't draw extra visualization unless selected.
|
||||
if (!IsSelected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw a sphere for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(position, m_controller.GetAttenuationRadius());
|
||||
}
|
||||
|
||||
AZ::Aabb EditorPointLightComponent::GetEditorSelectionBoundsViewport(const AzFramework::ViewportInfo& viewportInfo)
|
||||
{
|
||||
auto [radius, position] = GetViewportRadiusAndPosition(viewportInfo);
|
||||
return Aabb::CreateCenterRadius(position, radius);
|
||||
}
|
||||
|
||||
bool EditorPointLightComponent::EditorSelectionIntersectRayViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, const AZ::Vector3& dir, float& distance)
|
||||
{
|
||||
auto [radius, position] = GetViewportRadiusAndPosition(viewportInfo);
|
||||
return AZ::Intersect::IntersectRaySphere(src, dir, position, radius, distance) > 0;
|
||||
}
|
||||
|
||||
void EditorPointLightComponent::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, [[maybe_unused]] const AZ::Transform& world)
|
||||
{
|
||||
// Transform scale impacts the bulb radius and intensity of the light, so refresh the values.
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay,
|
||||
AzToolsFramework::Refresh_Values);
|
||||
}
|
||||
|
||||
AZ::Aabb EditorPointLightComponent::GetWorldBounds()
|
||||
{
|
||||
auto [radius, position] = GetRadiusAndPosition();
|
||||
return Aabb::CreateCenterRadius(position, radius);
|
||||
}
|
||||
|
||||
AZ::Aabb EditorPointLightComponent::GetLocalBounds()
|
||||
{
|
||||
return Aabb::CreateCenterRadius(AZ::Vector3::CreateZero(), m_controller.GetBulbRadius());
|
||||
}
|
||||
|
||||
u32 EditorPointLightComponent::OnConfigurationChanged()
|
||||
{
|
||||
// Set the intenstiy of the photometric unit in case the controller is disabled. This is needed to correctly convert between photometric units.
|
||||
m_controller.m_photometricValue.SetIntensity(m_controller.m_configuration.m_intensity);
|
||||
|
||||
// If the intensity mode changes in the editor, convert the photometric value and update the intensity
|
||||
if (m_controller.m_configuration.m_intensityMode != m_controller.m_photometricValue.GetType())
|
||||
{
|
||||
m_controller.m_photometricValue.SetArea(m_controller.m_configuration.GetArea());
|
||||
m_controller.m_photometricValue.ConvertToPhotometricUnit(m_controller.m_configuration.m_intensityMode);
|
||||
m_controller.m_configuration.m_intensity = m_controller.m_photometricValue.GetIntensity();
|
||||
}
|
||||
|
||||
BaseClass::OnConfigurationChanged();
|
||||
return Edit::PropertyRefreshLevels::AttributesAndValues;
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-74
@@ -1,74 +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 <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzFramework/Visibility/BoundsBus.h>
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
|
||||
#include <CoreLights/PointLightComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class EditorPointLightComponent final
|
||||
: public EditorRenderComponentAdapter<PointLightComponentController, PointLightComponent, PointLightComponentConfig>
|
||||
, private AzToolsFramework::EditorComponentSelectionRequestsBus::Handler
|
||||
, private AzFramework::EntityDebugDisplayEventBus::Handler
|
||||
, private TransformNotificationBus::Handler
|
||||
, public AzFramework::BoundsRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
using BaseClass = EditorRenderComponentAdapter<PointLightComponentController, PointLightComponent, PointLightComponentConfig>;
|
||||
AZ_EDITOR_COMPONENT(AZ::Render::EditorPointLightComponent, EditorPointLightComponentTypeId, BaseClass);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
EditorPointLightComponent() = default;
|
||||
EditorPointLightComponent(const PointLightComponentConfig& config);
|
||||
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
// EntityDebugDisplayEventBus overrides ...
|
||||
void DisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay) override;
|
||||
|
||||
// EditorComponentSelectionRequestsBus overrides ...
|
||||
bool SupportsEditorRayIntersect() override { return true; }
|
||||
bool EditorSelectionIntersectRayViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, const AZ::Vector3& dir, float& distance) override;
|
||||
AZ::Aabb GetEditorSelectionBoundsViewport(const AzFramework::ViewportInfo& viewportInfo) override;
|
||||
|
||||
// BoundsRequestBus overrides ...
|
||||
AZ::Aabb GetWorldBounds() override;
|
||||
AZ::Aabb GetLocalBounds() override;
|
||||
|
||||
private:
|
||||
AZStd::tuple<float, Vector3> GetRadiusAndPosition() const;
|
||||
|
||||
// TransformNotificationBus::Handler overrides ...
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
//! Returns a radius for the light relative to the viewport, ensuring the the light will always take up at least a certain amount of
|
||||
//! screen space for selection and debug drawing
|
||||
AZStd::tuple<float, Vector3> GetViewportRadiusAndPosition(const AzFramework::ViewportInfo& viewportInfo) const;
|
||||
|
||||
//! EditorRenderComponentAdapter overrides ...
|
||||
u32 OnConfigurationChanged() override;
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-261
@@ -1,261 +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 <CoreLights/EditorSpotLightComponent.h>
|
||||
#include <Atom/RPI.Edit/Common/ColorUtils.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <CoreLights/SpotLightComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
EditorSpotLightComponent::EditorSpotLightComponent(const SpotLightComponentConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
|
||||
void EditorSpotLightComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorSpotLightComponent, BaseClass>()
|
||||
->Version(3, ConvertToEditorRenderComponentAdapter<2>);
|
||||
|
||||
if (AZ::EditContext * editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorSpotLightComponent>(
|
||||
"Spot Light", "A spot light emits light in a cone from a single point in space.")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Atom")
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "editor/icons/components/viewport/component_placeholder.png")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-spot-light.html")
|
||||
;
|
||||
|
||||
editContext->Class<SpotLightComponentController>(
|
||||
"SpotLightComponentController", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SpotLightComponentController::m_configuration, "Configuration", "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
|
||||
editContext->Class<SpotLightComponentConfig>(
|
||||
"SpotLightComponentConfig", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &SpotLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &SpotLightComponentConfig::m_intensityMode, "Intensity Mode",
|
||||
"Allows specifying light values in candelas or lumens")
|
||||
->EnumAttribute(PhotometricUnit::Candela, "Candela")
|
||||
->EnumAttribute(PhotometricUnit::Lumen, "Lumen")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SpotLightComponentConfig::m_intensity, "Intensity", "Intensity of the light")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, &SpotLightComponentConfig::GetIntensitySuffix)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_bulbRadius, "Bulb Radius",
|
||||
"Radius of the disk that represents the spot light bulb.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
||||
->Attribute(AZ::Edit::Attributes::SoftMax, 0.25f)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " m")
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Cone Configuration")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_innerConeDegrees, "Inner Cone Angle",
|
||||
"Angle from the direction axis at which this light starts to fall off.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, &SpotLightComponentConfig::GetConeDegrees)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " degrees")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_outerConeDegrees, "Outer Cone Angle",
|
||||
"Angle from the direction axis at which this light no longer has an effect.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, &SpotLightComponentConfig::GetConeDegrees)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " degrees")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_penumbraBias, "Penumbra Bias",
|
||||
"Controls biasing the fall off curve of the penumbra towards the inner or outer cone angles.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, -1.0f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Attenuation Radius")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &SpotLightComponentConfig::m_attenuationRadiusMode, "Mode",
|
||||
"Controls whether the attenuation radius is calculated automatically or set explicitly.")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Automatic, "Automatic")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Explicit, "Explicit")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SpotLightComponentConfig::m_attenuationRadius, "Radius",
|
||||
"The distance at which this light no longer has an affect.")
|
||||
->Attribute(AZ::Edit::Attributes::ReadOnly, &SpotLightComponentConfig::IsAttenuationRadiusModeAutomatic)
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Shadow")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(Edit::UIHandlers::Default, &SpotLightComponentConfig::m_enabledShadow, "Enable Shadow", "Enable shadow for the light")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &SpotLightComponentConfig::m_shadowmapSize, "Shadowmap Size", "Width/Height of shadowmap")
|
||||
->EnumAttribute(ShadowmapSize::Size256, " 256")
|
||||
->EnumAttribute(ShadowmapSize::Size512, " 512")
|
||||
->EnumAttribute(ShadowmapSize::Size1024, "1024")
|
||||
->EnumAttribute(ShadowmapSize::Size2048, "2048")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &SpotLightComponentConfig::m_shadowFilterMethod, "Shadow Filter Method",
|
||||
"Filtering method of edge-softening of shadows.\n"
|
||||
" None: no filtering\n"
|
||||
" PCF: Percentage-Closer Filtering\n"
|
||||
" ESM: Exponential Shadow Maps\n"
|
||||
" ESM+PCF: ESM with a PCF fallback\n"
|
||||
"For BehaviorContext (or TrackView), None=0, PCF=1, ESM=2, ESM+PCF=3")
|
||||
->EnumAttribute(ShadowFilterMethod::None, "None")
|
||||
->EnumAttribute(ShadowFilterMethod::Pcf, "PCF")
|
||||
->EnumAttribute(ShadowFilterMethod::Esm, "ESM")
|
||||
->EnumAttribute(ShadowFilterMethod::EsmPcf, "ESM+PCF")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_boundaryWidthInDegrees, "Softening Boundary Width",
|
||||
"Width of the boundary between shadowed area and lit one. "
|
||||
"Units are in degrees. "
|
||||
"If this is 0, softening edge is disabled.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 1.f)
|
||||
->Attribute(Edit::Attributes::Suffix, " deg")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &SpotLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_predictionSampleCount, "Prediction Sample Count",
|
||||
"Sample Count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 16)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &SpotLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &SpotLightComponentConfig::m_filteringSampleCount, "Filtering Sample Count",
|
||||
"It is used only when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 64)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &SpotLightComponentConfig::IsShadowPcfDisabled)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::ComboBox, &SpotLightComponentConfig::m_pcfMethod, "Pcf Method",
|
||||
"Type of Pcf to use.\n"
|
||||
" Boundary search: do several taps to first determine if we are on a shadow boundary\n"
|
||||
" Bicubic: a smooth, fixed-size kernel \n")
|
||||
->EnumAttribute(PcfMethod::BoundarySearch, "Boundary Search")
|
||||
->EnumAttribute(PcfMethod::Bicubic, "Bicubic")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &SpotLightComponentConfig::IsShadowPcfDisabled);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<EditorSpotLightComponent>()->RequestBus("SpotLightRequestBus");
|
||||
|
||||
behaviorContext->ConstantProperty("EditorSpotLightComponentTypeId", BehaviorConstant(Uuid(EditorSpotLightComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSpotLightComponent::Activate()
|
||||
{
|
||||
BaseClass::Activate();
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId());
|
||||
}
|
||||
|
||||
void EditorSpotLightComponent::Deactivate()
|
||||
{
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
|
||||
BaseClass::Deactivate();
|
||||
}
|
||||
|
||||
void EditorSpotLightComponent::DisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
AZ::Transform worldTM;
|
||||
AZ::TransformBus::EventResult(worldTM, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
const AZ::Vector3 position = worldTM.GetTranslation();
|
||||
|
||||
debugDisplay.SetColor(m_controller.GetColor());
|
||||
|
||||
// Draw a sphere for the light itself.
|
||||
const float pixelRadius = 10.0f;
|
||||
const AzFramework::CameraState cameraState = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId);
|
||||
const float distance = cameraState.m_position.GetDistance(position);
|
||||
const float screenScale = (distance * cameraState.m_fovOrZoom) / cameraState.m_viewportSize.GetX();
|
||||
debugDisplay.DrawWireSphere(position, screenScale * pixelRadius);
|
||||
|
||||
// Don't draw extra visualization unless selected.
|
||||
if (!IsSelected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw rays to show the affected volume of the spot light.
|
||||
* As well as two circle showing inner and outer cone angles.
|
||||
* Note: the circles will not be drawn if cone are angles go beyond 90 degrees.
|
||||
*/
|
||||
worldTM.ExtractScale();
|
||||
debugDisplay.PushMatrix(worldTM);
|
||||
debugDisplay.SetColor(m_controller.GetColor());
|
||||
|
||||
float outerConeHalfAngle = m_controller.GetOuterConeAngleInDegrees() * 0.5f;
|
||||
float innerConeHalfAngle = m_controller.GetInnerConeAngleInDegrees() * 0.5f;
|
||||
const float debugConeHeight = m_controller.GetAttenuationRadius();
|
||||
|
||||
const float debugOuterConeRadius = tanf(AZ::DegToRad(outerConeHalfAngle)) * debugConeHeight;
|
||||
debugDisplay.DrawArrow(Vector3::CreateZero(), Vector3::CreateAxisY() * debugConeHeight * 0.5f, debugConeHeight * 0.2f);
|
||||
|
||||
constexpr float rightAngleInDegrees = 90.0f;
|
||||
if (outerConeHalfAngle < rightAngleInDegrees)
|
||||
{
|
||||
// outer cone
|
||||
debugDisplay.DrawCircle(Vector3::CreateAxisY() * debugConeHeight, debugOuterConeRadius, 1);
|
||||
}
|
||||
if (innerConeHalfAngle < rightAngleInDegrees)
|
||||
{
|
||||
// inner cone
|
||||
const float debugInnerConeRadius = tanf(AZ::DegToRad(innerConeHalfAngle)) * debugConeHeight;
|
||||
debugDisplay.DrawCircle(Vector3::CreateAxisY() * debugConeHeight, debugInnerConeRadius, 1);
|
||||
}
|
||||
|
||||
constexpr int debugRays = 6;
|
||||
for (int rayIndex = 0; rayIndex < debugRays; ++rayIndex)
|
||||
{
|
||||
const float angle = (AZ::Constants::TwoPi / debugRays) * rayIndex;
|
||||
const Vector3 spotRay = Vector3::CreateAxisY() * debugConeHeight + debugOuterConeRadius * Vector3(sinf(angle), 0.f, cosf(angle));
|
||||
debugDisplay.DrawLine(Vector3::CreateZero(), spotRay * (outerConeHalfAngle > rightAngleInDegrees ? -1.f : 1.f));
|
||||
}
|
||||
|
||||
debugDisplay.PopMatrix();
|
||||
}
|
||||
|
||||
u32 EditorSpotLightComponent::OnConfigurationChanged()
|
||||
{
|
||||
// Set the intenstiy of the photometric unit in case the controller is disabled. This is needed to correctly convert between photometric units.
|
||||
m_controller.m_photometricValue.SetIntensity(m_controller.m_configuration.m_intensity);
|
||||
|
||||
// If the intensity mode changes in the editor, convert the photometric value and update the intensity
|
||||
if (m_controller.m_configuration.m_intensityMode != m_controller.m_photometricValue.GetType())
|
||||
{
|
||||
m_controller.m_photometricValue.ConvertToPhotometricUnit(m_controller.m_configuration.m_intensityMode);
|
||||
m_controller.m_configuration.m_intensity = m_controller.m_photometricValue.GetIntensity();
|
||||
}
|
||||
|
||||
BaseClass::OnConfigurationChanged();
|
||||
return Edit::PropertyRefreshLevels::AttributesAndValues;
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-49
@@ -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 <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
|
||||
#include <CoreLights/SpotLightComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class EditorSpotLightComponent final
|
||||
: public EditorRenderComponentAdapter<SpotLightComponentController, SpotLightComponent, SpotLightComponentConfig>
|
||||
, private AzFramework::EntityDebugDisplayEventBus::Handler
|
||||
{
|
||||
public:
|
||||
|
||||
using BaseClass = EditorRenderComponentAdapter<SpotLightComponentController, SpotLightComponent, SpotLightComponentConfig>;
|
||||
AZ_EDITOR_COMPONENT(AZ::Render::EditorSpotLightComponent, EditorSpotLightComponentTypeId, BaseClass);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
EditorSpotLightComponent() = default;
|
||||
EditorSpotLightComponent(const SpotLightComponentConfig& config);
|
||||
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
// AzFramework::EntityDebugDisplayEventBus::Handler overrides...
|
||||
void DisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay) override;
|
||||
|
||||
// EditorComponentAdapter overrides...
|
||||
AZ::u32 OnConfigurationChanged() override;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -34,20 +34,32 @@ namespace AZ
|
||||
class LightDelegateBase
|
||||
: public LightDelegateInterface
|
||||
, private LmbrCentral::ShapeComponentNotificationsBus::Handler
|
||||
, private TransformNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
LightDelegateBase(EntityId entityId, bool isVisible);
|
||||
virtual ~LightDelegateBase();
|
||||
|
||||
// LightDelegateInterface overrides...
|
||||
virtual void SetChroma(const AZ::Color& chroma) override;
|
||||
virtual void SetIntensity(float intensity) override;
|
||||
virtual float SetPhotometricUnit(PhotometricUnit unit) override;
|
||||
virtual void SetAttenuationRadius(float radius) override;
|
||||
virtual const PhotometricValue& GetPhotometricValue() const override { return m_photometricValue; };
|
||||
virtual void SetLightEmitsBothDirections([[maybe_unused]] bool lightEmitsBothDirections) override {};
|
||||
virtual void SetUseFastApproximation([[maybe_unused]] bool useFastApproximation) override {};
|
||||
virtual void SetVisibility(bool visibility) override;
|
||||
void SetChroma(const AZ::Color& chroma) override;
|
||||
void SetIntensity(float intensity) override;
|
||||
float SetPhotometricUnit(PhotometricUnit unit) override;
|
||||
void SetAttenuationRadius(float radius) override;
|
||||
const PhotometricValue& GetPhotometricValue() const override { return m_photometricValue; };
|
||||
void SetLightEmitsBothDirections([[maybe_unused]] bool lightEmitsBothDirections) override {};
|
||||
void SetUseFastApproximation([[maybe_unused]] bool useFastApproximation) override {};
|
||||
void SetVisibility(bool visibility) override;
|
||||
|
||||
void SetEnableShutters(bool enabled) override { m_shuttersEnabled = enabled; };
|
||||
void SetShutterAngles([[maybe_unused]]float innerAngleDegrees, [[maybe_unused]]float outerAngleDegrees) override {};
|
||||
|
||||
void SetEnableShadow(bool enabled) override { m_shadowsEnabled = enabled; };
|
||||
void SetShadowmapMaxSize([[maybe_unused]] ShadowmapSize size) override {};
|
||||
void SetShadowFilterMethod([[maybe_unused]] ShadowFilterMethod method) override {};
|
||||
void SetSofteningBoundaryWidthAngle([[maybe_unused]] float widthInDegrees) override {};
|
||||
void SetPredictionSampleCount([[maybe_unused]] uint32_t count) override {};
|
||||
void SetFilteringSampleCount([[maybe_unused]] uint32_t count) override {};
|
||||
void SetPcfMethod([[maybe_unused]] PcfMethod method) override {};
|
||||
|
||||
protected:
|
||||
void InitBase(EntityId entityId);
|
||||
@@ -56,11 +68,15 @@ namespace AZ
|
||||
FeatureProcessorType* GetFeatureProcessor() const { return m_featureProcessor; };
|
||||
typename FeatureProcessorType::LightHandle GetLightHandle() const { return m_lightHandle; };
|
||||
const AZ::Transform& GetTransform() const { return m_transform; };
|
||||
|
||||
bool GetShuttersEnabled() { return m_shuttersEnabled; };
|
||||
bool GetShadowsEnabled() { return m_shadowsEnabled; };
|
||||
virtual void HandleShapeChanged() = 0;
|
||||
|
||||
// ShapeComponentNotificationsBus::Handler overrides...
|
||||
void OnShapeChanged(ShapeChangeReasons changeReason) override;
|
||||
|
||||
// TransformNotificationBus::Handler overrides ...
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
private:
|
||||
FeatureProcessorType* m_featureProcessor = nullptr;
|
||||
@@ -69,6 +85,8 @@ namespace AZ
|
||||
LmbrCentral::ShapeComponentRequests* m_shapeBus;
|
||||
AZ::Transform m_transform;
|
||||
PhotometricValue m_photometricValue;
|
||||
bool m_shuttersEnabled = false;
|
||||
bool m_shadowsEnabled = false;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace AZ
|
||||
template <typename FeatureProcessorType>
|
||||
LightDelegateBase<FeatureProcessorType>::~LightDelegateBase()
|
||||
{
|
||||
TransformNotificationBus::Handler::BusDisconnect();
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusDisconnect();
|
||||
if (m_lightHandle.IsValid())
|
||||
{
|
||||
@@ -42,10 +43,21 @@ namespace AZ
|
||||
void LightDelegateBase<FeatureProcessorType>::InitBase(EntityId entityId)
|
||||
{
|
||||
m_photometricValue.SetEffectiveSolidAngle(GetEffectiveSolidAngle());
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusConnect(entityId);
|
||||
m_shapeBus = LmbrCentral::ShapeComponentRequestsBus::FindFirstHandler(entityId);
|
||||
TransformBus::EventResult(m_transform, entityId, &TransformBus::Events::GetWorldTM);
|
||||
OnShapeChanged(ShapeChangeReasons::TransformChanged);
|
||||
|
||||
if (m_shapeBus != nullptr)
|
||||
{
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusConnect(entityId);
|
||||
OnShapeChanged(ShapeChangeReasons::TransformChanged);
|
||||
}
|
||||
else if (m_lightHandle.IsValid())
|
||||
{
|
||||
// Only connect to the transform bus if there's no shape bus, otherwise the shape bus handles transforms.
|
||||
TransformNotificationBus::Handler::BusConnect(entityId);
|
||||
HandleShapeChanged();
|
||||
m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FeatureProcessorType>
|
||||
@@ -95,6 +107,13 @@ namespace AZ
|
||||
}
|
||||
HandleShapeChanged();
|
||||
}
|
||||
|
||||
template <typename FeatureProcessorType>
|
||||
void LightDelegateBase<FeatureProcessorType>::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
|
||||
{
|
||||
m_transform = world;
|
||||
HandleShapeChanged();
|
||||
}
|
||||
|
||||
template <typename FeatureProcessorType>
|
||||
void LightDelegateBase<FeatureProcessorType>::SetVisibility(bool isVisible)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <Atom/Feature/CoreLights/ShadowConstants.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -56,6 +57,31 @@ namespace AZ
|
||||
virtual void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const = 0;
|
||||
//! Turns the visibility of this light on/off.
|
||||
virtual void SetVisibility(bool visibility) = 0;
|
||||
|
||||
// Shutters
|
||||
|
||||
// Sets if the light should be restricted to shutter angles.
|
||||
virtual void SetEnableShutters(bool enabled) = 0;
|
||||
// Sets the inner and outer angles of the shutters in degrees for where the light
|
||||
// beam starts to attenuate (inner) to where it is completely occluded (outer).
|
||||
virtual void SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees) = 0;
|
||||
|
||||
// Shadows
|
||||
|
||||
//! Sets if shadows should be enabled
|
||||
virtual void SetEnableShadow(bool enabled) = 0;
|
||||
//! Sets the maximum resolution of the shadow map
|
||||
virtual void SetShadowmapMaxSize(ShadowmapSize size) = 0;
|
||||
//! Sets the filter method for the shadow
|
||||
virtual void SetShadowFilterMethod(ShadowFilterMethod method) = 0;
|
||||
//! Sets the width of boundary between shadowed area and lit area in degrees.
|
||||
virtual void SetSofteningBoundaryWidthAngle(float widthInDegrees) = 0;
|
||||
//! Sets the sample count to predict the boundary of the shadow. Max 16, should be less than filtering sample count.
|
||||
virtual void SetPredictionSampleCount(uint32_t count) = 0;
|
||||
//! Sets the sample count for filtering of the shadow boundary, max 64.
|
||||
virtual void SetFilteringSampleCount(uint32_t count) = 0;
|
||||
//! Sets the Pcf (Percentage closer filtering) method to use.
|
||||
virtual void SetPcfMethod(PcfMethod method) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <CoreLights/PointLightComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
|
||||
PointLightComponent::PointLightComponent(const PointLightComponentConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
|
||||
void PointLightComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<PointLightComponent, BaseClass>();
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<PointLightComponent>()->RequestBus("PointLightRequestBus");
|
||||
|
||||
behaviorContext->ConstantProperty("PointLightComponentTypeId", BehaviorConstant(Uuid(PointLightComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common);
|
||||
}
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -1,38 +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 <AzFramework/Components/ComponentAdapter.h>
|
||||
#include <CoreLights/PointLightComponentController.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/CoreLightsConstants.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class PointLightComponent final
|
||||
: public AzFramework::Components::ComponentAdapter<PointLightComponentController, PointLightComponentConfig>
|
||||
{
|
||||
public:
|
||||
|
||||
using BaseClass = AzFramework::Components::ComponentAdapter<PointLightComponentController, PointLightComponentConfig>;
|
||||
AZ_COMPONENT(AZ::Render::PointLightComponent, PointLightComponentTypeId, BaseClass);
|
||||
|
||||
PointLightComponent() = default;
|
||||
PointLightComponent(const PointLightComponentConfig& config);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-286
@@ -1,286 +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 <CoreLights/PointLightComponentController.h>
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
void PointLightComponentConfig::Reflect(ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<PointLightComponentConfig, ComponentConfig>()
|
||||
->Version(2)
|
||||
->Field("Color", &PointLightComponentConfig::m_color)
|
||||
->Field("ColorIntensityMode", &PointLightComponentConfig::m_intensityMode)
|
||||
->Field("Intensity", &PointLightComponentConfig::m_intensity)
|
||||
->Field("AttenuationRadiusMode", &PointLightComponentConfig::m_attenuationRadiusMode)
|
||||
->Field("AttenuationRadius", &PointLightComponentConfig::m_attenuationRadius)
|
||||
->Field("BulbRadius", &PointLightComponentConfig::m_bulbRadius)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightComponentController::Reflect(ReflectContext* context)
|
||||
{
|
||||
PointLightComponentConfig::Reflect(context);
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<PointLightComponentController>()
|
||||
->Version(1)
|
||||
->Field("Configuration", &PointLightComponentController::m_configuration);
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<PointLightRequestBus>("PointLightRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Event("GetAttenuationRadius", &PointLightRequestBus::Events::GetAttenuationRadius)
|
||||
->Event("SetAttenuationRadius", &PointLightRequestBus::Events::SetAttenuationRadius)
|
||||
->Event("GetAttenuationRadiusIsAutomatic", &PointLightRequestBus::Events::GetAttenuationRadiusIsAutomatic)
|
||||
->Event("SetAttenuationRadiusIsAutomatic", &PointLightRequestBus::Events::SetAttenuationRadiusIsAutomatic)
|
||||
->Event("GetBulbRadius", &PointLightRequestBus::Events::GetBulbRadius)
|
||||
->Event("SetBulbRadius", &PointLightRequestBus::Events::SetBulbRadius)
|
||||
->Event("GetColor", &PointLightRequestBus::Events::GetColor)
|
||||
->Event("SetColor", &PointLightRequestBus::Events::SetColor)
|
||||
->Event("GetIntensity", &PointLightRequestBus::Events::GetIntensity)
|
||||
->Event("SetIntensity", static_cast<void(PointLightRequestBus::Events::*)(float)>(&PointLightRequestBus::Events::SetIntensity))
|
||||
->Event("GetIntensityMode", &PointLightRequestBus::Events::GetIntensityMode)
|
||||
->Event("ConvertToIntensityMode", &PointLightRequestBus::Events::ConvertToIntensityMode)
|
||||
->VirtualProperty("AttenuationRadius", "GetAttenuationRadius", "SetAttenuationRadius")
|
||||
->VirtualProperty("AttenuationRadiusIsAutomatic", "GetAttenuationRadiusIsAutomatic", "SetAttenuationRadiusIsAutomatic")
|
||||
->VirtualProperty("BulbRadius", "GetBulbRadius", "SetBulbRadius")
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("PointLightService", 0x951d2403));
|
||||
}
|
||||
|
||||
void PointLightComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("PointLightService", 0x951d2403));
|
||||
}
|
||||
|
||||
PointLightComponentController::PointLightComponentController(const PointLightComponentConfig& config)
|
||||
: m_configuration(config)
|
||||
{
|
||||
}
|
||||
|
||||
void PointLightComponentController::Activate(EntityId entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
m_featureProcessor = RPI::Scene::GetFeatureProcessorForEntity<PointLightFeatureProcessorInterface>(entityId);
|
||||
AZ_Error("PointLightComponentController", m_featureProcessor, "Could not find a PointLightFeatureProcessorInterface on the scene.");
|
||||
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_lightHandle = m_featureProcessor->AcquireLight();
|
||||
|
||||
AZ::Vector3 position = Vector3::CreateZero();
|
||||
AZ::TransformBus::EventResult(position, entityId, &AZ::TransformBus::Events::GetWorldTranslation);
|
||||
m_featureProcessor->SetPosition(m_lightHandle, position);
|
||||
|
||||
AZ::Vector3 scale = AZ::Vector3::CreateOne();
|
||||
AZ::TransformBus::EventResult(scale, entityId, &AZ::TransformBus::Events::GetWorldScale);
|
||||
m_configuration.m_scale = scale.GetMaxElement();
|
||||
|
||||
TransformNotificationBus::Handler::BusConnect(m_entityId);
|
||||
PointLightRequestBus::Handler::BusConnect(m_entityId);
|
||||
ConfigurationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightComponentController::Deactivate()
|
||||
{
|
||||
PointLightRequestBus::Handler::BusDisconnect(m_entityId);
|
||||
TransformNotificationBus::Handler::BusDisconnect(m_entityId);
|
||||
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->ReleaseLight(m_lightHandle);
|
||||
}
|
||||
m_entityId.SetInvalid();
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetConfiguration(const PointLightComponentConfig& config)
|
||||
{
|
||||
m_configuration = config;
|
||||
ConfigurationChanged();
|
||||
}
|
||||
|
||||
const PointLightComponentConfig& PointLightComponentController::GetConfiguration() const
|
||||
{
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void PointLightComponentController::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
|
||||
{
|
||||
m_featureProcessor->SetPosition(m_lightHandle, world.GetTranslation());
|
||||
if (m_configuration.m_scale != world.GetScale().GetMaxElement())
|
||||
{
|
||||
m_configuration.UpdateScale(world.GetScale().GetMaxElement());
|
||||
BulbRadiusChanged();
|
||||
ColorIntensityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightComponentController::ConfigurationChanged()
|
||||
{
|
||||
m_configuration.UpdateUnscaledIntensity();
|
||||
m_configuration.UpdateUnscaledBulbRadius();
|
||||
|
||||
m_photometricValue = PhotometricValue(m_configuration.m_intensity, m_configuration.m_color, m_configuration.m_intensityMode);
|
||||
m_photometricValue.SetArea(m_configuration.GetArea());
|
||||
|
||||
ColorIntensityChanged();
|
||||
AttenuationRadiusChanged();
|
||||
BulbRadiusChanged();
|
||||
}
|
||||
|
||||
void PointLightComponentController::ColorIntensityChanged()
|
||||
{
|
||||
PointLightNotificationBus::Event(m_entityId, &PointLightNotifications::OnColorOrIntensityChanged, m_configuration.m_color, m_configuration.m_intensity);
|
||||
|
||||
m_photometricValue.SetChroma(m_configuration.m_color);
|
||||
m_photometricValue.SetIntensity(m_configuration.m_intensity);
|
||||
m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<PhotometricUnit::Candela>());
|
||||
}
|
||||
|
||||
void PointLightComponentController::AttenuationRadiusChanged()
|
||||
{
|
||||
if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AutoCalculateAttenuationRadius();
|
||||
}
|
||||
PointLightNotificationBus::Event(m_entityId, &PointLightNotifications::OnAttenutationRadiusChanged, m_configuration.m_attenuationRadius);
|
||||
m_featureProcessor->SetAttenuationRadius(m_lightHandle, m_configuration.m_attenuationRadius);
|
||||
}
|
||||
|
||||
void PointLightComponentController::BulbRadiusChanged()
|
||||
{
|
||||
m_photometricValue.SetArea(m_configuration.GetArea());
|
||||
PointLightNotificationBus::Event(m_entityId, &PointLightNotifications::OnBulbRadiusChanged, m_configuration.m_bulbRadius);
|
||||
m_featureProcessor->SetBulbRadius(m_lightHandle, m_configuration.m_bulbRadius);
|
||||
}
|
||||
|
||||
void PointLightComponentController::AutoCalculateAttenuationRadius()
|
||||
{
|
||||
// Get combined intensity luma from m_photometricValue, then calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
static const float CutoffIntensity = 0.1f; // Make this configurable later.
|
||||
|
||||
float intensity = m_photometricValue.GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
m_configuration.m_attenuationRadius = sqrt(intensity / CutoffIntensity);
|
||||
}
|
||||
|
||||
const Color& PointLightComponentController::GetColor() const
|
||||
{
|
||||
return m_configuration.m_color;
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetColor(const Color& color)
|
||||
{
|
||||
m_configuration.m_color = color;
|
||||
|
||||
PointLightNotificationBus::Event(m_entityId, &PointLightNotifications::OnColorChanged, color);
|
||||
ColorIntensityChanged();
|
||||
}
|
||||
|
||||
float PointLightComponentController::GetIntensity() const
|
||||
{
|
||||
return m_configuration.m_intensity;
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetIntensity(float intensity)
|
||||
{
|
||||
m_configuration.m_intensity = intensity;
|
||||
m_configuration.UpdateUnscaledIntensity();
|
||||
|
||||
PointLightNotificationBus::Event(m_entityId, &PointLightNotifications::OnIntensityChanged, intensity);
|
||||
ColorIntensityChanged();
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetIntensity(float intensity, PhotometricUnit intensityMode)
|
||||
{
|
||||
m_configuration.m_intensityMode = intensityMode;
|
||||
SetIntensity(intensity);
|
||||
}
|
||||
|
||||
PhotometricUnit PointLightComponentController::GetIntensityMode() const
|
||||
{
|
||||
return m_configuration.m_intensityMode;
|
||||
}
|
||||
|
||||
void PointLightComponentController::ConvertToIntensityMode(PhotometricUnit intensityMode)
|
||||
{
|
||||
if (m_configuration.m_intensityMode != intensityMode)
|
||||
{
|
||||
m_configuration.m_intensityMode = intensityMode;
|
||||
m_photometricValue.ConvertToPhotometricUnit(intensityMode);
|
||||
m_configuration.m_intensity = m_photometricValue.GetIntensity();
|
||||
m_configuration.UpdateUnscaledIntensity();
|
||||
}
|
||||
}
|
||||
|
||||
float PointLightComponentController::GetAttenuationRadius() const
|
||||
{
|
||||
return m_configuration.m_attenuationRadius;
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetAttenuationRadius(float radius)
|
||||
{
|
||||
m_configuration.m_attenuationRadius = radius;
|
||||
AttenuationRadiusChanged();
|
||||
}
|
||||
|
||||
float PointLightComponentController::GetBulbRadius() const
|
||||
{
|
||||
return m_configuration.m_bulbRadius;
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetBulbRadius(float bulbRadius)
|
||||
{
|
||||
m_configuration.m_bulbRadius = bulbRadius;
|
||||
m_configuration.UpdateUnscaledBulbRadius();
|
||||
BulbRadiusChanged();
|
||||
}
|
||||
|
||||
bool PointLightComponentController::GetAttenuationRadiusIsAutomatic() const
|
||||
{
|
||||
return (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic);
|
||||
}
|
||||
|
||||
void PointLightComponentController::SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode)
|
||||
{
|
||||
m_configuration.m_attenuationRadiusMode = attenuationRadiusMode;
|
||||
if (attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AutoCalculateAttenuationRadius();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-87
@@ -1,87 +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/Component/Component.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h>
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/PointLightBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/PointLightComponentConfig.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class PointLightComponentController final
|
||||
: private TransformNotificationBus::Handler
|
||||
, public PointLightRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
friend class EditorPointLightComponent;
|
||||
|
||||
AZ_TYPE_INFO(AZ::Render::PointLightComponentController, "{23F82E30-2E1F-45FE-A9A7-B15632ED9EBD}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
|
||||
PointLightComponentController() = default;
|
||||
PointLightComponentController(const PointLightComponentConfig& config);
|
||||
|
||||
void Activate(EntityId entityId);
|
||||
void Deactivate();
|
||||
void SetConfiguration(const PointLightComponentConfig& config);
|
||||
const PointLightComponentConfig& GetConfiguration() const;
|
||||
|
||||
private:
|
||||
|
||||
AZ_DISABLE_COPY(PointLightComponentController);
|
||||
|
||||
// TransformNotificationBus::Handler overrides ...
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
// PointLightRequestBus::Handler overrides ...
|
||||
const Color& GetColor() const override;
|
||||
void SetColor(const Color& color) override;
|
||||
float GetIntensity() const override;
|
||||
PhotometricUnit GetIntensityMode() const override;
|
||||
void SetIntensity(float intensity) override;
|
||||
void SetIntensity(float intensity, PhotometricUnit intensityMode) override;
|
||||
|
||||
float GetAttenuationRadius() const override;
|
||||
void SetAttenuationRadius(float radius) override;
|
||||
bool GetAttenuationRadiusIsAutomatic() const override;
|
||||
void SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode) override;
|
||||
float GetBulbRadius() const override;
|
||||
void SetBulbRadius(float bulbRadius) override;
|
||||
void ConvertToIntensityMode(PhotometricUnit intensityMode) override;
|
||||
|
||||
void ConfigurationChanged();
|
||||
void ColorIntensityChanged();
|
||||
void AttenuationRadiusChanged();
|
||||
void BulbRadiusChanged();
|
||||
|
||||
void AutoCalculateAttenuationRadius();
|
||||
|
||||
PointLightComponentConfig m_configuration;
|
||||
PhotometricValue m_photometricValue;
|
||||
PointLightFeatureProcessorInterface* m_featureProcessor = nullptr;
|
||||
PointLightFeatureProcessorInterface::LightHandle m_lightHandle;
|
||||
EntityId m_entityId;
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // AZ namespace
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 <CoreLights/SimplePointLightDelegate.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/Feature/CoreLights/SimplePointLightFeatureProcessorInterface.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
SimplePointLightDelegate::SimplePointLightDelegate(EntityId entityId, bool isVisible)
|
||||
: LightDelegateBase<SimplePointLightFeatureProcessorInterface>(entityId, isVisible)
|
||||
{
|
||||
InitBase(entityId);
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
}
|
||||
float SimplePointLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
|
||||
{
|
||||
// Calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
return sqrt(intensity / lightThreshold);
|
||||
}
|
||||
|
||||
float SimplePointLightDelegate::GetSurfaceArea() const
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void SimplePointLightDelegate::HandleShapeChanged()
|
||||
{
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
}
|
||||
|
||||
void SimplePointLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
debugDisplay.SetColor(color);
|
||||
|
||||
// Draw a sphere for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity));
|
||||
}
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 <CoreLights/LightDelegateBase.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Atom/Feature/CoreLights/SimplePointLightFeatureProcessorInterface.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class SimplePointLightDelegate final
|
||||
: public LightDelegateBase<SimplePointLightFeatureProcessorInterface>
|
||||
{
|
||||
public:
|
||||
SimplePointLightDelegate(EntityId entityId, bool isVisible);
|
||||
|
||||
// LightDelegateBase overrides...
|
||||
float CalculateAttenuationRadius(float lightThreshold) const override;
|
||||
void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const override;
|
||||
float GetSurfaceArea() const override;
|
||||
float GetEffectiveSolidAngle() const override { return PhotometricValue::OmnidirectionalSteradians; }
|
||||
|
||||
private:
|
||||
virtual void HandleShapeChanged();
|
||||
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 <CoreLights/SimpleSpotLightDelegate.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
|
||||
|
||||
namespace AZ::Render
|
||||
{
|
||||
SimpleSpotLightDelegate::SimpleSpotLightDelegate(EntityId entityId, bool isVisible)
|
||||
: LightDelegateBase<SimpleSpotLightFeatureProcessorInterface>(entityId, isVisible)
|
||||
{
|
||||
InitBase(entityId);
|
||||
}
|
||||
|
||||
void SimpleSpotLightDelegate::HandleShapeChanged()
|
||||
{
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
GetFeatureProcessor()->SetDirection(GetLightHandle(), GetTransform().GetBasisZ());
|
||||
}
|
||||
|
||||
float SimpleSpotLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
|
||||
{
|
||||
// Calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
return sqrt(intensity / lightThreshold);
|
||||
}
|
||||
|
||||
float SimpleSpotLightDelegate::GetSurfaceArea() const
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void SimpleSpotLightDelegate::SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees)
|
||||
{
|
||||
GetFeatureProcessor()->SetConeAngles(GetLightHandle(), DegToRad(innerAngleDegrees), DegToRad(outerAngleDegrees));
|
||||
}
|
||||
|
||||
void SimpleSpotLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
debugDisplay.SetColor(color);
|
||||
|
||||
// Draw a cone for the cone angle and attenuation radius
|
||||
debugDisplay.DrawCone(transform.GetTranslation(), transform.GetBasisX(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity), false);
|
||||
}
|
||||
}
|
||||
} // namespace AZ::Render
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 <CoreLights/LightDelegateBase.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Atom/Feature/CoreLights/SimpleSpotLightFeatureProcessorInterface.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class SimpleSpotLightDelegate final
|
||||
: public LightDelegateBase<SimpleSpotLightFeatureProcessorInterface>
|
||||
{
|
||||
public:
|
||||
SimpleSpotLightDelegate(EntityId entityId, bool isVisible);
|
||||
|
||||
// LightDelegateBase overrides...
|
||||
float CalculateAttenuationRadius(float lightThreshold) const override;
|
||||
void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const override;
|
||||
float GetSurfaceArea() const override;
|
||||
float GetEffectiveSolidAngle() const override { return PhotometricValue::DirectionalEffectiveSteradians; }
|
||||
void SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees) override;
|
||||
private:
|
||||
virtual void HandleShapeChanged();
|
||||
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <CoreLights/SpotLightComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
|
||||
SpotLightComponent::SpotLightComponent(const SpotLightComponentConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
|
||||
void SpotLightComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SpotLightComponent, BaseClass>();
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SpotLightComponent>()->RequestBus("SpotLightRequestBus");
|
||||
|
||||
behaviorContext->ConstantProperty("SpotLightComponentTypeId", BehaviorConstant(Uuid(SpotLightComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common);
|
||||
}
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -1,37 +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 <AzFramework/Components/ComponentAdapter.h>
|
||||
#include <CoreLights/SpotLightComponentController.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class SpotLightComponent final
|
||||
: public AzFramework::Components::ComponentAdapter<SpotLightComponentController, SpotLightComponentConfig>
|
||||
{
|
||||
public:
|
||||
|
||||
using BaseClass = AzFramework::Components::ComponentAdapter<SpotLightComponentController, SpotLightComponentConfig>;
|
||||
AZ_COMPONENT(AZ::Render::SpotLightComponent, SpotLightComponentTypeId, BaseClass);
|
||||
|
||||
SpotLightComponent() = default;
|
||||
SpotLightComponent(const SpotLightComponentConfig& config);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/SpotLightComponentConfig.h>
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
void SpotLightComponentConfig::Reflect(ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SpotLightComponentConfig, ComponentConfig>()
|
||||
->Version(4)
|
||||
->Field("Color", &SpotLightComponentConfig::m_color)
|
||||
->Field("Intensity", &SpotLightComponentConfig::m_intensity)
|
||||
->Field("IntensityMode", &SpotLightComponentConfig::m_intensityMode)
|
||||
->Field("Bulb Radius", &SpotLightComponentConfig::m_bulbRadius)
|
||||
->Field("Inner Cone Angle", &SpotLightComponentConfig::m_innerConeDegrees)
|
||||
->Field("Outer Cone Angle", &SpotLightComponentConfig::m_outerConeDegrees)
|
||||
->Field("Attenuation Radius", &SpotLightComponentConfig::m_attenuationRadius)
|
||||
->Field("Attenuation Radius Mode", &SpotLightComponentConfig::m_attenuationRadiusMode)
|
||||
->Field("Penumbra Bias", &SpotLightComponentConfig::m_penumbraBias)
|
||||
->Field("Enabled Shadow", &SpotLightComponentConfig::m_enabledShadow)
|
||||
->Field("Shadowmap Size", &SpotLightComponentConfig::m_shadowmapSize)
|
||||
->Field("Shadow Filter Method", &SpotLightComponentConfig::m_shadowFilterMethod)
|
||||
->Field("Softening Boundary Width", &SpotLightComponentConfig::m_boundaryWidthInDegrees)
|
||||
->Field("Prediction Sample Count", &SpotLightComponentConfig::m_predictionSampleCount)
|
||||
->Field("Filtering Sample Count", &SpotLightComponentConfig::m_filteringSampleCount)
|
||||
->Field("Pcf Method", &SpotLightComponentConfig::m_pcfMethod);
|
||||
}
|
||||
}
|
||||
|
||||
bool SpotLightComponentConfig::IsAttenuationRadiusModeAutomatic() const
|
||||
{
|
||||
return m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic;
|
||||
}
|
||||
|
||||
const char* SpotLightComponentConfig::GetIntensitySuffix() const
|
||||
{
|
||||
return PhotometricValue::GetTypeSuffix(m_intensityMode);
|
||||
}
|
||||
|
||||
float SpotLightComponentConfig::GetConeDegrees() const
|
||||
{
|
||||
return (m_enabledShadow && m_shadowmapSize != ShadowmapSize::None) ? MaxSpotLightConeAngleDegreeWithShadow : MaxSpotLightConeAngleDegree;
|
||||
}
|
||||
|
||||
bool SpotLightComponentConfig::IsShadowFilteringDisabled() const
|
||||
{
|
||||
return (m_shadowFilterMethod == ShadowFilterMethod::None);
|
||||
}
|
||||
|
||||
bool SpotLightComponentConfig::IsShadowPcfDisabled() const
|
||||
{
|
||||
return !(m_shadowFilterMethod == ShadowFilterMethod::Pcf ||
|
||||
m_shadowFilterMethod == ShadowFilterMethod::EsmPcf);
|
||||
}
|
||||
|
||||
bool SpotLightComponentConfig::IsPcfBoundarySearchDisabled() const
|
||||
{
|
||||
if (IsShadowPcfDisabled())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_pcfMethod != PcfMethod::BoundarySearch;
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-434
@@ -1,434 +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 <CoreLights/SpotLightComponentController.h>
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
void SpotLightComponentController::Reflect(ReflectContext* context)
|
||||
{
|
||||
SpotLightComponentConfig::Reflect(context);
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SpotLightComponentController>()
|
||||
->Version(3)
|
||||
->Field("Configuration", &SpotLightComponentController::m_configuration);
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext
|
||||
->Enum<static_cast<uint32_t>(ShadowFilterMethod::None)>("ShadowFilterMethod_None")
|
||||
->Enum<static_cast<uint32_t>(ShadowFilterMethod::Pcf)>("ShadowFilterMethod_PCF")
|
||||
->Enum<static_cast<uint32_t>(ShadowFilterMethod::Esm)>("ShadowFilterMethod_ESM")
|
||||
->Enum<static_cast<uint32_t>(ShadowFilterMethod::EsmPcf)>("ShadowFilterMethod_ESM_PCF")
|
||||
->Enum<static_cast<uint32_t>(ShadowmapSize::None)>("ShadowmapSize_None")
|
||||
->Enum<static_cast<uint32_t>(ShadowmapSize::Size256)>("ShadowmapSize_256")
|
||||
->Enum<static_cast<uint32_t>(ShadowmapSize::Size512)>("ShadowmapSize_512")
|
||||
->Enum<static_cast<uint32_t>(ShadowmapSize::Size1024)>("ShadowmapSize_1024")
|
||||
->Enum<static_cast<uint32_t>(ShadowmapSize::Size2048)>("ShadowmapSize_2045")
|
||||
;
|
||||
|
||||
behaviorContext->EBus<SpotLightRequestBus>("SpotLightRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Event("GetAttenuationRadius", &SpotLightRequestBus::Events::GetAttenuationRadius)
|
||||
->Event("SetAttenuationRadius", &SpotLightRequestBus::Events::SetAttenuationRadius)
|
||||
->Event("GetAttenuationRadiusIsAutomatic", &SpotLightRequestBus::Events::GetAttenuationRadiusIsAutomatic)
|
||||
->Event("SetAttenuationRadiusIsAutomatic", &SpotLightRequestBus::Events::SetAttenuationRadiusIsAutomatic)
|
||||
->Event("GetColor", &SpotLightRequestBus::Events::GetColor)
|
||||
->Event("SetColor", &SpotLightRequestBus::Events::SetColor)
|
||||
->Event("GetIntensity", &SpotLightRequestBus::Events::GetIntensity)
|
||||
->Event("SetIntensity", &SpotLightRequestBus::Events::SetIntensity)
|
||||
->Event("GetBulbRadius", &SpotLightRequestBus::Events::GetBulbRadius)
|
||||
->Event("SetBulbRadius", &SpotLightRequestBus::Events::SetBulbRadius)
|
||||
->Event("GetInnerConeAngleInDegrees", &SpotLightRequestBus::Events::GetInnerConeAngleInDegrees)
|
||||
->Event("SetInnerConeAngleInDegrees", &SpotLightRequestBus::Events::SetInnerConeAngleInDegrees)
|
||||
->Event("GetOuterConeAngleInDegrees", &SpotLightRequestBus::Events::GetOuterConeAngleInDegrees)
|
||||
->Event("SetOuterConeAngleInDegrees", &SpotLightRequestBus::Events::SetOuterConeAngleInDegrees)
|
||||
->Event("GetPenumbraBias", &SpotLightRequestBus::Events::GetPenumbraBias)
|
||||
->Event("SetPenumbraBias", &SpotLightRequestBus::Events::SetPenumbraBias)
|
||||
->Event("GetEnableShadow", &SpotLightRequestBus::Events::GetEnableShadow)
|
||||
->Event("SetEnableShadow", &SpotLightRequestBus::Events::SetEnableShadow)
|
||||
->Event("GetShadowmapSize", &SpotLightRequestBus::Events::GetShadowmapSize)
|
||||
->Event("SetShadowmapSize", &SpotLightRequestBus::Events::SetShadowmapSize)
|
||||
->Event("GetShadowFilterMethod", &SpotLightRequestBus::Events::GetShadowFilterMethod)
|
||||
->Event("SetShadowFilterMethod", &SpotLightRequestBus::Events::SetShadowFilterMethod)
|
||||
->Event("GetSofteningBoundaryWidthAngle", &SpotLightRequestBus::Events::GetSofteningBoundaryWidthAngle)
|
||||
->Event("SetSofteningBoundaryWidthAngle", &SpotLightRequestBus::Events::SetSofteningBoundaryWidthAngle)
|
||||
->Event("GetPredictionSampleCount", &SpotLightRequestBus::Events::GetPredictionSampleCount)
|
||||
->Event("SetPredictionSampleCount", &SpotLightRequestBus::Events::SetPredictionSampleCount)
|
||||
->Event("GetFilteringSampleCount", &SpotLightRequestBus::Events::GetFilteringSampleCount)
|
||||
->Event("SetFilteringSampleCount", &SpotLightRequestBus::Events::SetFilteringSampleCount)
|
||||
->Event("GetPcfMethod", &SpotLightRequestBus::Events::GetPcfMethod)
|
||||
->Event("SetPcfMethod", &SpotLightRequestBus::Events::SetPcfMethod)
|
||||
->VirtualProperty("AttenuationRadius", "GetAttenuationRadius", "SetAttenuationRadius")
|
||||
->VirtualProperty("AttenuationRadiusIsAutomatic", "GetAttenuationRadiusIsAutomatic", "SetAttenuationRadiusIsAutomatic")
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
->VirtualProperty("InnerConeAngleInDegrees", "GetInnerConeAngleInDegrees", "SetInnerConeAngleInDegrees")
|
||||
->VirtualProperty("OuterConeAngleInDegrees", "GetOuterConeAngleInDegrees", "SetOuterConeAngleInDegrees")
|
||||
->VirtualProperty("PenumbraBias", "GetPenumbraBias", "SetPenumbraBias")
|
||||
->VirtualProperty("EnableShadow", "GetEnableShadow", "SetEnableShadow")
|
||||
->VirtualProperty("ShadowmapSize", "GetShadowmapSize", "SetShadowmapSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("SofteningBoundaryWidthAngle", "GetSofteningBoundaryWidthAngle", "SetSofteningBoundaryWidthAngle")
|
||||
->VirtualProperty("PredictionSampleCount", "GetPredictionSampleCount", "SetPredictionSampleCount")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
->VirtualProperty("PcfMethod", "GetPcfMethod", "SetPcfMethod");
|
||||
}
|
||||
}
|
||||
|
||||
void SpotLightComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("SpotLightService", 0x3ae7d498));
|
||||
}
|
||||
|
||||
void SpotLightComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("SpotLightService", 0x3ae7d498));
|
||||
}
|
||||
|
||||
SpotLightComponentController::SpotLightComponentController(const SpotLightComponentConfig& config)
|
||||
: m_configuration(config)
|
||||
{
|
||||
}
|
||||
|
||||
void SpotLightComponentController::Activate(EntityId entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
m_featureProcessor = RPI::Scene::GetFeatureProcessorForEntity<SpotLightFeatureProcessorInterface>(entityId);
|
||||
AZ_Error("SpotLightComponentController", m_featureProcessor, "Could not find a SpotLightFeatureProcessorInterface on the scene.");
|
||||
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_lightHandle = m_featureProcessor->AcquireLight();
|
||||
|
||||
TransformNotificationBus::Handler::BusConnect(m_entityId);
|
||||
SpotLightRequestBus::Handler::BusConnect(m_entityId);
|
||||
ConfigurationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SpotLightComponentController::Deactivate()
|
||||
{
|
||||
SpotLightRequestBus::Handler::BusDisconnect(m_entityId);
|
||||
TransformNotificationBus::Handler::BusDisconnect(m_entityId);
|
||||
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->ReleaseLight(m_lightHandle);
|
||||
}
|
||||
m_entityId.SetInvalid();
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetConfiguration(const SpotLightComponentConfig& config)
|
||||
{
|
||||
m_configuration = config;
|
||||
ConfigurationChanged();
|
||||
}
|
||||
|
||||
const SpotLightComponentConfig& SpotLightComponentController::GetConfiguration() const
|
||||
{
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
|
||||
{
|
||||
m_featureProcessor->SetPosition(m_lightHandle, world.GetTranslation());
|
||||
|
||||
const Vector3 forward = Vector3::CreateAxisY();
|
||||
const Vector3 lightDirection = world.TransformVector(forward);
|
||||
m_featureProcessor->SetDirection(m_lightHandle, lightDirection);
|
||||
}
|
||||
|
||||
void SpotLightComponentController::ConfigurationChanged()
|
||||
{
|
||||
m_photometricValue = PhotometricValue(m_configuration.m_intensity, m_configuration.m_color, m_configuration.m_intensityMode);
|
||||
m_photometricValue.SetEffectiveSolidAngle(PhotometricValue::DirectionalEffectiveSteradians);
|
||||
|
||||
AZ::Transform worldTM;
|
||||
AZ::TransformBus::EventResult(worldTM, m_entityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
OnTransformChanged({}, worldTM);
|
||||
|
||||
ColorIntensityChanged();
|
||||
AttenuationRadiusChanged();
|
||||
ConeAnglesChanged();
|
||||
PenumbraBiasChanged();
|
||||
SetBulbRadius(m_configuration.m_bulbRadius);
|
||||
SetEnableShadow(m_configuration.m_enabledShadow);
|
||||
SetShadowmapSize(m_configuration.m_shadowmapSize);
|
||||
SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
|
||||
SetSofteningBoundaryWidthAngle(m_configuration.m_boundaryWidthInDegrees);
|
||||
SetPredictionSampleCount(m_configuration.m_predictionSampleCount);
|
||||
SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
SetPcfMethod(m_configuration.m_pcfMethod);
|
||||
}
|
||||
|
||||
void SpotLightComponentController::ColorIntensityChanged()
|
||||
{
|
||||
SpotLightNotificationBus::Event(m_entityId, &SpotLightNotifications::OnIntensityChanged, m_configuration.m_intensity);
|
||||
SpotLightNotificationBus::Event(m_entityId, &SpotLightNotifications::OnColorChanged, m_configuration.m_color);
|
||||
|
||||
m_photometricValue.SetChroma(m_configuration.m_color);
|
||||
m_photometricValue.SetIntensity(m_configuration.m_intensity);
|
||||
m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<PhotometricUnit::Candela>());
|
||||
}
|
||||
|
||||
void SpotLightComponentController::ConeAnglesChanged()
|
||||
{
|
||||
if (m_configuration.m_innerConeDegrees > m_configuration.m_outerConeDegrees)
|
||||
{
|
||||
m_configuration.m_innerConeDegrees = m_configuration.m_outerConeDegrees;
|
||||
}
|
||||
|
||||
SpotLightNotificationBus::Event(m_entityId, &SpotLightNotifications::OnConeAnglesChanged, m_configuration.m_innerConeDegrees, m_configuration.m_outerConeDegrees);
|
||||
m_featureProcessor->SetConeAngles(m_lightHandle, m_configuration.m_innerConeDegrees, m_configuration.m_outerConeDegrees);
|
||||
}
|
||||
|
||||
void SpotLightComponentController::AttenuationRadiusChanged()
|
||||
{
|
||||
if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AutoCalculateAttenuationRadius();
|
||||
}
|
||||
|
||||
SpotLightNotificationBus::Event(m_entityId, &SpotLightNotifications::OnAttenuationRadiusChanged, m_configuration.m_attenuationRadius);
|
||||
m_featureProcessor->SetAttenuationRadius(m_lightHandle, m_configuration.m_attenuationRadius);
|
||||
}
|
||||
|
||||
void SpotLightComponentController::PenumbraBiasChanged()
|
||||
{
|
||||
SpotLightNotificationBus::Event(m_entityId, &SpotLightNotifications::OnPenumbraBiasChanged, m_configuration.m_penumbraBias);
|
||||
m_featureProcessor->SetPenumbraBias(m_lightHandle, m_configuration.m_penumbraBias);
|
||||
}
|
||||
|
||||
void SpotLightComponentController::AutoCalculateAttenuationRadius()
|
||||
{
|
||||
// Get combined intensity luma from m_photometricValue, then calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
static const float CutoffIntensity = 0.1f; // Make this configurable later.
|
||||
|
||||
float intensity = m_photometricValue.GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
m_configuration.m_attenuationRadius = sqrt(intensity / CutoffIntensity);
|
||||
}
|
||||
|
||||
const Color& SpotLightComponentController::GetColor() const
|
||||
{
|
||||
return m_configuration.m_color;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetColor(const Color& color)
|
||||
{
|
||||
m_configuration.m_color = color;
|
||||
ColorIntensityChanged();
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetIntensity() const
|
||||
{
|
||||
return m_configuration.m_intensity;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetIntensity(float intensity)
|
||||
{
|
||||
m_configuration.m_intensity = intensity;
|
||||
ColorIntensityChanged();
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetBulbRadius() const
|
||||
{
|
||||
return m_configuration.m_bulbRadius;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetBulbRadius(float bulbRadius)
|
||||
{
|
||||
m_configuration.m_bulbRadius = bulbRadius;
|
||||
m_featureProcessor->SetBulbRadius(m_lightHandle, bulbRadius);
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetInnerConeAngleInDegrees() const
|
||||
{
|
||||
return m_configuration.m_innerConeDegrees;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetInnerConeAngleInDegrees(float degrees)
|
||||
{
|
||||
m_configuration.m_innerConeDegrees = degrees;
|
||||
ConeAnglesChanged();
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetOuterConeAngleInDegrees() const
|
||||
{
|
||||
return m_configuration.m_outerConeDegrees;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetOuterConeAngleInDegrees(float degrees)
|
||||
{
|
||||
m_configuration.m_outerConeDegrees = degrees;
|
||||
ConeAnglesChanged();
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetPenumbraBias() const
|
||||
{
|
||||
return m_configuration.m_penumbraBias;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetPenumbraBias(float penumbraBias)
|
||||
{
|
||||
m_configuration.m_penumbraBias = penumbraBias;
|
||||
PenumbraBiasChanged();
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetAttenuationRadius() const
|
||||
{
|
||||
return m_configuration.m_attenuationRadius;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetAttenuationRadius(float radius)
|
||||
{
|
||||
m_configuration.m_attenuationRadius = radius;
|
||||
AttenuationRadiusChanged();
|
||||
}
|
||||
|
||||
LightAttenuationRadiusMode SpotLightComponentController::GetAttenuationRadiusMode() const
|
||||
{
|
||||
return m_configuration.m_attenuationRadiusMode;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode)
|
||||
{
|
||||
m_configuration.m_attenuationRadiusMode = attenuationRadiusMode;
|
||||
if (attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AutoCalculateAttenuationRadius();
|
||||
}
|
||||
}
|
||||
|
||||
bool SpotLightComponentController::GetEnableShadow() const
|
||||
{
|
||||
return m_configuration.m_enabledShadow;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetEnableShadow(bool enabled)
|
||||
{
|
||||
m_configuration.m_enabledShadow = enabled;
|
||||
|
||||
m_featureProcessor->SetShadowmapSize(
|
||||
m_lightHandle,
|
||||
m_configuration.m_enabledShadow ?
|
||||
m_configuration.m_shadowmapSize :
|
||||
ShadowmapSize::None);
|
||||
}
|
||||
|
||||
ShadowmapSize SpotLightComponentController::GetShadowmapSize() const
|
||||
{
|
||||
return m_configuration.m_shadowmapSize;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetShadowmapSize(ShadowmapSize size)
|
||||
{
|
||||
// The minimum valid ShadowmapSize is 256 and maximum one is 2048.
|
||||
const uint32_t sizeInt = aznumeric_cast<uint32_t>(size);
|
||||
if (sizeInt < aznumeric_cast<uint32_t>(ShadowmapSize::Size512))
|
||||
{
|
||||
size = ShadowmapSize::Size256;
|
||||
}
|
||||
else if (sizeInt < aznumeric_cast<uint32_t>(ShadowmapSize::Size1024))
|
||||
{
|
||||
size = ShadowmapSize::Size512;
|
||||
}
|
||||
else if (sizeInt < aznumeric_cast<uint32_t>(ShadowmapSize::Size2048))
|
||||
{
|
||||
size = ShadowmapSize::Size1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = ShadowmapSize::Size2048;
|
||||
}
|
||||
|
||||
m_configuration.m_shadowmapSize = size;
|
||||
m_featureProcessor->SetShadowmapSize(
|
||||
m_lightHandle,
|
||||
m_configuration.m_enabledShadow ?
|
||||
m_configuration.m_shadowmapSize :
|
||||
ShadowmapSize::None);
|
||||
}
|
||||
|
||||
ShadowFilterMethod SpotLightComponentController::GetShadowFilterMethod() const
|
||||
{
|
||||
return m_configuration.m_shadowFilterMethod;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetShadowFilterMethod(ShadowFilterMethod method)
|
||||
{
|
||||
m_configuration.m_shadowFilterMethod = method;
|
||||
|
||||
m_featureProcessor->SetShadowFilterMethod(m_lightHandle, method);
|
||||
}
|
||||
|
||||
float SpotLightComponentController::GetSofteningBoundaryWidthAngle() const
|
||||
{
|
||||
return m_configuration.m_boundaryWidthInDegrees;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetSofteningBoundaryWidthAngle(float width)
|
||||
{
|
||||
m_configuration.m_boundaryWidthInDegrees = width;
|
||||
|
||||
m_featureProcessor->SetShadowBoundaryWidthAngle(m_lightHandle, width);
|
||||
}
|
||||
|
||||
uint32_t SpotLightComponentController::GetPredictionSampleCount() const
|
||||
{
|
||||
return m_configuration.m_predictionSampleCount;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetPredictionSampleCount(uint32_t count)
|
||||
{
|
||||
m_configuration.m_predictionSampleCount = count;
|
||||
|
||||
m_featureProcessor->SetPredictionSampleCount(m_lightHandle, count);
|
||||
}
|
||||
|
||||
uint32_t SpotLightComponentController::GetFilteringSampleCount() const
|
||||
{
|
||||
return m_configuration.m_filteringSampleCount;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
m_configuration.m_filteringSampleCount = count;
|
||||
|
||||
m_featureProcessor->SetFilteringSampleCount(m_lightHandle, count);
|
||||
}
|
||||
|
||||
PcfMethod SpotLightComponentController::GetPcfMethod() const
|
||||
{
|
||||
return m_configuration.m_pcfMethod;
|
||||
}
|
||||
|
||||
void SpotLightComponentController::SetPcfMethod(PcfMethod method)
|
||||
{
|
||||
m_configuration.m_pcfMethod = method;
|
||||
m_featureProcessor->SetPcfMethod(m_lightHandle, method);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/SpotLightBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/SpotLightComponentConfig.h>
|
||||
#include <Atom/Feature/CoreLights/SpotLightFeatureProcessorInterface.h>
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class SpotLightComponentController final
|
||||
: public TransformNotificationBus::Handler
|
||||
, public SpotLightRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
friend class EditorSpotLightComponent;
|
||||
|
||||
AZ_TYPE_INFO(AZ::Render::SpotLightComponentController, "{2B37DC8C-BE9E-481C-A53B-FCBFFAB425E0}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
|
||||
SpotLightComponentController() = default;
|
||||
SpotLightComponentController(const SpotLightComponentConfig& config);
|
||||
|
||||
void Activate(EntityId entityId);
|
||||
void Deactivate();
|
||||
void SetConfiguration(const SpotLightComponentConfig& config);
|
||||
const SpotLightComponentConfig& GetConfiguration() const;
|
||||
|
||||
private:
|
||||
|
||||
AZ_DISABLE_COPY(SpotLightComponentController);
|
||||
|
||||
// TransformNotificationBus::Handler overrides ...
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
// SpotLightRequestBus::Handler overrides ...
|
||||
const Color& GetColor() const override;
|
||||
void SetColor(const Color& color) override;
|
||||
float GetIntensity() const override;
|
||||
void SetIntensity(float intensity) override;
|
||||
float GetBulbRadius() const override;
|
||||
void SetBulbRadius(float bulbRadius) override;
|
||||
float GetInnerConeAngleInDegrees() const override;
|
||||
void SetInnerConeAngleInDegrees(float degrees) override;
|
||||
float GetOuterConeAngleInDegrees() const override;
|
||||
void SetOuterConeAngleInDegrees(float degrees) override;
|
||||
float GetPenumbraBias() const override;
|
||||
void SetPenumbraBias(float penumbraBias) override;
|
||||
float GetAttenuationRadius() const override;
|
||||
void SetAttenuationRadius(float radius) override;
|
||||
LightAttenuationRadiusMode GetAttenuationRadiusMode() const override;
|
||||
void SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode) override;
|
||||
bool GetEnableShadow() const override;
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
ShadowmapSize GetShadowmapSize() const override;
|
||||
void SetShadowmapSize(ShadowmapSize size) override;
|
||||
ShadowFilterMethod GetShadowFilterMethod() const override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
float GetSofteningBoundaryWidthAngle() const override;
|
||||
void SetSofteningBoundaryWidthAngle(float width) override;
|
||||
uint32_t GetPredictionSampleCount() const override;
|
||||
void SetPredictionSampleCount(uint32_t count) override;
|
||||
uint32_t GetFilteringSampleCount() const override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
PcfMethod GetPcfMethod() const override;
|
||||
void SetPcfMethod(PcfMethod method) override;
|
||||
|
||||
void ConfigurationChanged();
|
||||
void ColorIntensityChanged();
|
||||
void ConeAnglesChanged();
|
||||
void AttenuationRadiusChanged();
|
||||
void PenumbraBiasChanged();
|
||||
|
||||
void AutoCalculateAttenuationRadius();
|
||||
|
||||
SpotLightComponentConfig m_configuration;
|
||||
PhotometricValue m_photometricValue;
|
||||
SpotLightFeatureProcessorInterface* m_featureProcessor = nullptr;
|
||||
SpotLightFeatureProcessorInterface::LightHandle m_lightHandle;
|
||||
EntityId m_entityId;
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // AZ namespace
|
||||
+4
-4
@@ -175,19 +175,19 @@ namespace AZ
|
||||
tableWidget->setCellWidget(row, OverwriteFileColumn, overwriteCheckBoxContainer);
|
||||
|
||||
// Whenever the selection is updated, automatically apply the change to the export item
|
||||
QObject::connect(materialSlotCheckBox, &QCheckBox::stateChanged, materialSlotCheckBox, [&]([[maybe_unused]] int state) {
|
||||
QObject::connect(materialSlotCheckBox, &QCheckBox::stateChanged, materialSlotCheckBox, [&exportItem, materialFileWidget, materialSlotCheckBox, overwriteCheckBox]([[maybe_unused]] int state) {
|
||||
exportItem.m_enabled = materialSlotCheckBox->isChecked();
|
||||
materialFileWidget->setEnabled(exportItem.m_enabled);
|
||||
overwriteCheckBox->setEnabled(exportItem.m_enabled && exportItem.m_exists);
|
||||
});
|
||||
|
||||
// Whenever the overwrite check box is updated, automatically apply the change to the export item
|
||||
QObject::connect(overwriteCheckBox, &QCheckBox::stateChanged, overwriteCheckBox, [&]([[maybe_unused]] int state) {
|
||||
QObject::connect(overwriteCheckBox, &QCheckBox::stateChanged, overwriteCheckBox, [&exportItem, overwriteCheckBox]([[maybe_unused]] int state) {
|
||||
exportItem.m_overwrite = overwriteCheckBox->isChecked();
|
||||
});
|
||||
|
||||
// Whenever the browse button is clicked, open a save file dialog in the same location as the current export file setting
|
||||
QObject::connect(materialFileWidget, &AzQtComponents::BrowseEdit::attachedButtonTriggered, materialFileWidget, [&]() {
|
||||
QObject::connect(materialFileWidget, &AzQtComponents::BrowseEdit::attachedButtonTriggered, materialFileWidget, [&dialog, &exportItem, materialFileWidget, overwriteCheckBox]() {
|
||||
QFileInfo fileInfo = QFileDialog::getSaveFileName(&dialog,
|
||||
QString("Select Material Filename"),
|
||||
exportItem.m_exportPath.c_str(),
|
||||
@@ -201,7 +201,7 @@ namespace AZ
|
||||
exportItem.m_exportPath = fileInfo.absoluteFilePath().toUtf8().constData();
|
||||
exportItem.m_exists = fileInfo.exists();
|
||||
exportItem.m_overwrite = fileInfo.exists();
|
||||
\
|
||||
|
||||
// Update the controls to display the new state
|
||||
materialFileWidget->setText(fileInfo.fileName());
|
||||
overwriteCheckBox->setChecked(exportItem.m_overwrite);
|
||||
|
||||
+1
-5
@@ -98,10 +98,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::DefaultAsset, &EditorMaterialComponentSlot::GetDefaultAssetId)
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &EditorMaterialComponentSlot::GetLabel)
|
||||
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true)
|
||||
->Attribute("ShowThumbnail", true)
|
||||
->Attribute("EditButton", ":/Cards/img/UI20/Cards/menu_ico.svg")
|
||||
->Attribute("EditDescription", "")
|
||||
->Attribute("EditCallback", &EditorMaterialComponentSlot::OpenPopupMenu)
|
||||
->Attribute("ThumbnailWithDropDown", &EditorMaterialComponentSlot::OpenPopupMenu)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -109,7 +106,6 @@ namespace AZ
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<EditorMaterialComponentSlot>("EditorMaterialComponentSlot")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Editor")
|
||||
->Attribute(AZ::Script::Attributes::Module, "editor")
|
||||
|
||||
@@ -75,7 +75,6 @@ namespace AZ
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<MaterialComponentConfig>("MaterialComponentConfig")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "render")
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
|
||||
-1
@@ -33,7 +33,6 @@ namespace AZ
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<MaterialComponentRequestBus>("MaterialComponentRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "render")
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
|
||||
@@ -140,7 +140,9 @@ namespace AZ
|
||||
AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne();
|
||||
AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, GetEntityId(), &AZ::NonUniformScaleRequests::GetScale);
|
||||
|
||||
return m_controller.GetModel()->RayIntersection(transform, nonUniformScale, src, dir, distance);
|
||||
AZ::Vector3 ignoreNormal;
|
||||
|
||||
return m_controller.GetModel()->RayIntersection(transform, nonUniformScale, src, dir, distance, ignoreNormal);
|
||||
}
|
||||
|
||||
bool EditorMeshComponent::SupportsEditorRayIntersect()
|
||||
@@ -200,7 +202,6 @@ namespace AZ
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay,
|
||||
AzToolsFramework::Refresh_EntireTree);
|
||||
}
|
||||
|
||||
AZ::u32 EditorMeshComponent::OnConfigurationChanged()
|
||||
{
|
||||
// temp variable is needed to hold reference to m_modelAsset while it's being loaded.
|
||||
|
||||
@@ -87,6 +87,12 @@ namespace AZ
|
||||
return values;
|
||||
}
|
||||
|
||||
MeshComponentController::~MeshComponentController()
|
||||
{
|
||||
// Release memory, disconnect from buses in the right order and broadcast events so that other components are aware.
|
||||
Deactivate();
|
||||
}
|
||||
|
||||
void MeshComponentController::Reflect(ReflectContext* context)
|
||||
{
|
||||
MeshComponentConfig::Reflect(context);
|
||||
@@ -130,11 +136,13 @@ namespace AZ
|
||||
void MeshComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("MaterialReceiverService", 0x0d1a6a74));
|
||||
provided.push_back(AZ_CRC("MeshService", 0x71d8a455));
|
||||
}
|
||||
|
||||
void MeshComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("MaterialReceiverService", 0x0d1a6a74));
|
||||
incompatible.push_back(AZ_CRC("MeshService", 0x71d8a455));
|
||||
}
|
||||
|
||||
// [GFX TODO] [ATOM-13339] Remove the ModelAsset id fix up function in MeshComponentController
|
||||
@@ -157,7 +165,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "Failed to find asset id for [%s] ", modelAsset.GetHint().c_str());
|
||||
AZ_Error("MeshComponentController", false, "Failed to find asset id for [%s] ", modelAsset.GetHint().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,14 +205,15 @@ namespace AZ
|
||||
|
||||
void MeshComponentController::Deactivate()
|
||||
{
|
||||
// Buses must be disconnected after unregistering the model, otherwise they can't deliver the events during the process.
|
||||
UnregisterModel();
|
||||
|
||||
AzFramework::BoundsRequestBus::Handler::BusDisconnect();
|
||||
MeshComponentRequestBus::Handler::BusDisconnect();
|
||||
TransformNotificationBus::Handler::BusDisconnect();
|
||||
MaterialReceiverRequestBus::Handler::BusDisconnect();
|
||||
MaterialComponentNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
UnregisterModel();
|
||||
|
||||
m_meshFeatureProcessor = nullptr;
|
||||
m_transformInterface = nullptr;
|
||||
m_entityId = AZ::EntityId(AZ::EntityId::InvalidEntityId);
|
||||
@@ -299,8 +308,9 @@ namespace AZ
|
||||
|
||||
void MeshComponentController::UnregisterModel()
|
||||
{
|
||||
if (m_meshFeatureProcessor)
|
||||
if (m_meshFeatureProcessor && m_meshHandle.IsValid())
|
||||
{
|
||||
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelPreDestroy);
|
||||
m_meshFeatureProcessor->ReleaseMesh(m_meshHandle);
|
||||
}
|
||||
}
|
||||
@@ -338,7 +348,7 @@ namespace AZ
|
||||
|
||||
const Data::Asset<RPI::ModelAsset>& MeshComponentController::GetModelAsset() const
|
||||
{
|
||||
return m_configuration.m_modelAsset;
|
||||
return GetModel() ? GetModel()->GetModelAsset() : m_configuration.m_modelAsset;
|
||||
}
|
||||
|
||||
Data::AssetId MeshComponentController::GetModelAssetId() const
|
||||
|
||||
@@ -67,6 +67,8 @@ namespace AZ
|
||||
AZ_CLASS_ALLOCATOR(MeshComponentController, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(AZ::Render::MeshComponentController, "{D0F35FAC-4194-4C89-9487-D000DDB8B272}");
|
||||
|
||||
~MeshComponentController();
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#include <CommonFeaturesSystemComponent.h>
|
||||
#include <CoreLights/AreaLightComponent.h>
|
||||
#include <CoreLights/DirectionalLightComponent.h>
|
||||
#include <CoreLights/PointLightComponent.h>
|
||||
#include <CoreLights/SpotLightComponent.h>
|
||||
#include <Decals/DecalComponent.h>
|
||||
#include <DiffuseProbeGrid/DiffuseProbeGridComponent.h>
|
||||
#include <Grid/GridComponent.h>
|
||||
@@ -40,14 +38,13 @@
|
||||
#include <SkyBox/HDRiSkyboxComponent.h>
|
||||
#include <SkyBox/PhysicalSkyComponent.h>
|
||||
#include <Scripting/EntityReferenceComponent.h>
|
||||
#include <SurfaceData/SurfaceDataMeshComponent.h>
|
||||
|
||||
#ifdef ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR
|
||||
#include <EditorCommonFeaturesSystemComponent.h>
|
||||
#include <PostProcess/EditorPostFxSystemComponent.h>
|
||||
#include <CoreLights/EditorAreaLightComponent.h>
|
||||
#include <CoreLights/EditorDirectionalLightComponent.h>
|
||||
#include <CoreLights/EditorPointLightComponent.h>
|
||||
#include <CoreLights/EditorSpotLightComponent.h>
|
||||
#include <Decals/EditorDecalComponent.h>
|
||||
#include <DiffuseProbeGrid/EditorDiffuseProbeGridComponent.h>
|
||||
#include <Grid/EditorGridComponent.h>
|
||||
@@ -71,6 +68,7 @@
|
||||
#include <SkyBox/EditorHDRiSkyboxComponent.h>
|
||||
#include <SkyBox/EditorPhysicalSkyComponent.h>
|
||||
#include <Scripting/EditorEntityReferenceComponent.h>
|
||||
#include <SurfaceData/EditorSurfaceDataMeshComponent.h>
|
||||
#endif
|
||||
|
||||
namespace AZ
|
||||
@@ -104,16 +102,15 @@ namespace AZ
|
||||
MaterialComponent::CreateDescriptor(),
|
||||
MeshComponent::CreateDescriptor(),
|
||||
PhysicalSkyComponent::CreateDescriptor(),
|
||||
PointLightComponent::CreateDescriptor(),
|
||||
PostFxLayerComponent::CreateDescriptor(),
|
||||
ReflectionProbeComponent::CreateDescriptor(),
|
||||
SpotLightComponent::CreateDescriptor(),
|
||||
RadiusWeightModifierComponent::CreateDescriptor(),
|
||||
ShapeWeightModifierComponent::CreateDescriptor(),
|
||||
EntityReferenceComponent::CreateDescriptor(),
|
||||
GradientWeightModifierComponent::CreateDescriptor(),
|
||||
DiffuseProbeGridComponent::CreateDescriptor(),
|
||||
DeferredFogComponent::CreateDescriptor(),
|
||||
SurfaceData::SurfaceDataMeshComponent::CreateDescriptor(),
|
||||
|
||||
#ifdef ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR
|
||||
EditorAreaLightComponent::CreateDescriptor(),
|
||||
@@ -135,16 +132,15 @@ namespace AZ
|
||||
EditorMeshSystemComponent::CreateDescriptor(),
|
||||
EditorMeshComponent::CreateDescriptor(),
|
||||
EditorPhysicalSkyComponent::CreateDescriptor(),
|
||||
EditorPointLightComponent::CreateDescriptor(),
|
||||
EditorPostFxLayerComponent::CreateDescriptor(),
|
||||
EditorReflectionProbeComponent::CreateDescriptor(),
|
||||
EditorSpotLightComponent::CreateDescriptor(),
|
||||
EditorRadiusWeightModifierComponent::CreateDescriptor(),
|
||||
EditorShapeWeightModifierComponent::CreateDescriptor(),
|
||||
EditorEntityReferenceComponent::CreateDescriptor(),
|
||||
EditorGradientWeightModifierComponent::CreateDescriptor(),
|
||||
EditorDiffuseProbeGridComponent::CreateDescriptor(),
|
||||
EditorDeferredFogComponent::CreateDescriptor(),
|
||||
SurfaceData::EditorSurfaceDataMeshComponent::CreateDescriptor(),
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
#include <AzFramework/Components/ComponentAdapter.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/PostProcess/GradientWeightModifier/GradientWeightModifierComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/PostProcess/GradientWeightModifier/GradientWeightModifierComponentConfig.h>
|
||||
#include <PostProcess/GradientWeightModifier/GradientWeightModifierComponentController.h>
|
||||
#include <PostProcess/GradientWeightModifier/GradientWeightModifierController.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <PostProcess/GradientWeightModifier/GradientWeightModifierComponentController.h>
|
||||
#include <PostProcess/GradientWeightModifier/GradientWeightModifierController.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 "EditorSurfaceDataMeshComponent.h"
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <LmbrCentral/Dependency/DependencyNotificationBus.h>
|
||||
|
||||
namespace SurfaceData
|
||||
{
|
||||
void EditorSurfaceDataMeshComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClassType::ReflectSubClass<EditorSurfaceDataMeshComponent, BaseClassType>(context, 2, &LmbrCentral::EditorWrappedComponentBaseVersionConverter<typename BaseClassType::WrappedComponentType, typename BaseClassType::WrappedConfigType,2>);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
|
||||
#include <SurfaceData/SurfaceDataMeshComponent.h>
|
||||
#include <LmbrCentral/Component/EditorWrappedComponentBase.h>
|
||||
|
||||
namespace SurfaceData
|
||||
{
|
||||
class EditorSurfaceDataMeshComponent
|
||||
: public LmbrCentral::EditorWrappedComponentBase<SurfaceDataMeshComponent, SurfaceDataMeshConfig>
|
||||
{
|
||||
public:
|
||||
using BaseClassType = LmbrCentral::EditorWrappedComponentBase<SurfaceDataMeshComponent, SurfaceDataMeshConfig>;
|
||||
AZ_EDITOR_COMPONENT(EditorSurfaceDataMeshComponent, "{4D73E979-5463-4B75-AE46-70B1E52CBF43}", BaseClassType);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static constexpr const char* const s_categoryName = "Surface Data";
|
||||
static constexpr const char* const s_componentName = "Mesh Surface Tag Emitter";
|
||||
static constexpr const char* const s_componentDescription = "Enables a static mesh to emit surface tags";
|
||||
static constexpr const char* const s_icon = "Editor/Icons/Components/SurfaceData.svg";
|
||||
static constexpr const char* const s_viewportIcon = "Editor/Icons/Components/Viewport/SurfaceData.png";
|
||||
static constexpr const char* const s_helpUrl = "https://docs.aws.amazon.com/console/lumberyard/surfacedata/mesh-surface-tag-emitter";
|
||||
};
|
||||
}
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensor's.
|
||||
*
|
||||
* 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 "SurfaceDataMeshComponent.h"
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <LmbrCentral/Rendering/MeshAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAssetCreator.h>
|
||||
|
||||
#include <SurfaceData/SurfaceDataSystemRequestBus.h>
|
||||
#include <SurfaceData/Utility/SurfaceDataUtility.h>
|
||||
|
||||
#include <MathConversion.h>
|
||||
|
||||
namespace SurfaceData
|
||||
{
|
||||
void SurfaceDataMeshConfig::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<SurfaceDataMeshConfig, AZ::ComponentConfig>()
|
||||
->Version(0)
|
||||
->Field("SurfaceTags", &SurfaceDataMeshConfig::m_tags)
|
||||
;
|
||||
|
||||
AZ::EditContext* edit = serialize->GetEditContext();
|
||||
if (edit)
|
||||
{
|
||||
edit->Class<SurfaceDataMeshConfig>(
|
||||
"Mesh Surface Tag Emitter", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(0, &SurfaceDataMeshConfig::m_tags, "Generated Tags", "")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
services.push_back(AZ_CRC("SurfaceDataProviderService", 0xfe9fb95e));
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
services.push_back(AZ_CRC("SurfaceDataProviderService", 0xfe9fb95e));
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
services.push_back(AZ_CRC("MeshService", 0x71d8a455));
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
SurfaceDataMeshConfig::Reflect(context);
|
||||
|
||||
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<SurfaceDataMeshComponent, AZ::Component>()
|
||||
->Version(0)
|
||||
->Field("Configuration", &SurfaceDataMeshComponent::m_configuration)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceDataMeshComponent::SurfaceDataMeshComponent(const SurfaceDataMeshConfig& configuration)
|
||||
: m_configuration(configuration)
|
||||
{
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::Activate()
|
||||
{
|
||||
AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId());
|
||||
AZ::Render::MeshComponentNotificationBus::Handler::BusConnect(GetEntityId());
|
||||
|
||||
m_providerHandle = InvalidSurfaceDataRegistryHandle;
|
||||
m_refresh = false;
|
||||
|
||||
// Update the cached mesh data and bounds, then register the surface data provider
|
||||
UpdateMeshData();
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::Deactivate()
|
||||
{
|
||||
if (m_providerHandle != InvalidSurfaceDataRegistryHandle)
|
||||
{
|
||||
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle);
|
||||
m_providerHandle = InvalidSurfaceDataRegistryHandle;
|
||||
}
|
||||
|
||||
SurfaceDataProviderRequestBus::Handler::BusDisconnect();
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AZ::TransformNotificationBus::Handler::BusDisconnect();
|
||||
AZ::Render::MeshComponentNotificationBus::Handler::BusDisconnect();
|
||||
m_refresh = false;
|
||||
|
||||
// Clear the cached mesh data
|
||||
{
|
||||
AZStd::lock_guard<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
m_meshAssetData = {};
|
||||
m_meshBounds = AZ::Aabb::CreateNull();
|
||||
m_meshWorldTM = AZ::Transform::CreateIdentity();
|
||||
m_meshWorldTMInverse = AZ::Transform::CreateIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
bool SurfaceDataMeshComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
|
||||
{
|
||||
if (auto config = azrtti_cast<const SurfaceDataMeshConfig*>(baseConfig))
|
||||
{
|
||||
m_configuration = *config;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SurfaceDataMeshComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
|
||||
{
|
||||
if (auto config = azrtti_cast<SurfaceDataMeshConfig*>(outBaseConfig))
|
||||
{
|
||||
*config = m_configuration;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SurfaceDataMeshComponent::DoRayTrace(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, AZ::Vector3& outNormal) const
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
|
||||
|
||||
AZStd::lock_guard<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
// test AABB as first pass to claim the point
|
||||
const AZ::Vector3 testPosition = AZ::Vector3(
|
||||
inPosition.GetX(),
|
||||
inPosition.GetY(),
|
||||
(m_meshBounds.GetMax().GetZ() + m_meshBounds.GetMin().GetZ()) * 0.5f);
|
||||
|
||||
if (!m_meshBounds.Contains(testPosition))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::RPI::ModelAsset* mesh = m_meshAssetData.GetAs<AZ::RPI::ModelAsset>();
|
||||
if (!mesh)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const AZ::Vector3 rayOrigin = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_meshBounds.GetMax().GetZ() + s_rayAABBHeightPadding);
|
||||
const AZ::Vector3 rayDirection = -AZ::Vector3::CreateAxisZ();
|
||||
return GetMeshRayIntersection(*mesh, m_meshWorldTM, m_meshWorldTMInverse, rayOrigin, rayDirection, outPosition, outNormal);
|
||||
}
|
||||
|
||||
|
||||
void SurfaceDataMeshComponent::GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZ::Vector3 hitPosition;
|
||||
AZ::Vector3 hitNormal;
|
||||
if (DoRayTrace(inPosition, hitPosition, hitNormal))
|
||||
{
|
||||
SurfacePoint point;
|
||||
point.m_entityId = GetEntityId();
|
||||
point.m_position = hitPosition;
|
||||
point.m_normal = hitNormal;
|
||||
AddMaxValueForMasks(point.m_masks, m_configuration.m_tags, 1.0f);
|
||||
surfacePointList.push_back(point);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Aabb SurfaceDataMeshComponent::GetSurfaceAabb() const
|
||||
{
|
||||
return m_meshBounds;
|
||||
}
|
||||
|
||||
SurfaceTagVector SurfaceDataMeshComponent::GetSurfaceTags() const
|
||||
{
|
||||
return m_configuration.m_tags;
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::OnCompositionChanged()
|
||||
{
|
||||
if (!m_refresh)
|
||||
{
|
||||
m_refresh = true;
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::OnModelReady([[maybe_unused]] const AZ::Data::Asset<AZ::RPI::ModelAsset>& modelAsset, [[maybe_unused]] const AZ::Data::Instance<AZ::RPI::Model>& model)
|
||||
{
|
||||
OnCompositionChanged();
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::OnTransformChanged(const AZ::Transform & local, const AZ::Transform & world)
|
||||
{
|
||||
(void)local;
|
||||
(void)world;
|
||||
OnCompositionChanged();
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/)
|
||||
{
|
||||
if (m_refresh)
|
||||
{
|
||||
UpdateMeshData();
|
||||
m_refresh = false;
|
||||
}
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::UpdateMeshData()
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
|
||||
|
||||
bool meshValidBeforeUpdate = false;
|
||||
bool meshValidAfterUpdate = false;
|
||||
|
||||
{
|
||||
AZStd::lock_guard<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
meshValidBeforeUpdate = (m_meshAssetData.GetAs<AZ::RPI::ModelAsset>() != nullptr) && (m_meshBounds.IsValid());
|
||||
|
||||
m_meshAssetData = {};
|
||||
AZ::Render::MeshComponentRequestBus::EventResult(m_meshAssetData, GetEntityId(), &AZ::Render::MeshComponentRequestBus::Events::GetModelAsset);
|
||||
|
||||
m_meshBounds = AZ::Aabb::CreateNull();
|
||||
AZ::Render::MeshComponentRequestBus::EventResult(m_meshBounds, GetEntityId(), &AZ::Render::MeshComponentRequestBus::Events::GetWorldBounds);
|
||||
|
||||
m_meshWorldTM = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(m_meshWorldTM, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
m_meshWorldTMInverse = m_meshWorldTM.GetInverse();
|
||||
|
||||
meshValidAfterUpdate = (m_meshAssetData.GetAs<AZ::RPI::ModelAsset>() != nullptr) && (m_meshBounds.IsValid());
|
||||
}
|
||||
|
||||
SurfaceDataRegistryEntry registryEntry;
|
||||
registryEntry.m_entityId = GetEntityId();
|
||||
registryEntry.m_bounds = GetSurfaceAabb();
|
||||
registryEntry.m_tags = GetSurfaceTags();
|
||||
|
||||
if (!meshValidBeforeUpdate && !meshValidAfterUpdate)
|
||||
{
|
||||
// We didn't have a valid mesh asset before or after running this, so do nothing.
|
||||
}
|
||||
else if (!meshValidBeforeUpdate && meshValidAfterUpdate)
|
||||
{
|
||||
// Our mesh has become valid, so register as a provider and save off the provider handle
|
||||
AZ_Assert((m_providerHandle == InvalidSurfaceDataRegistryHandle), "Surface data handle is initialized before our mesh became active");
|
||||
AZ_Assert(m_meshBounds.IsValid(), "Mesh Geometry isn't correctly initialized.");
|
||||
SurfaceDataSystemRequestBus::BroadcastResult(m_providerHandle, &SurfaceDataSystemRequestBus::Events::RegisterSurfaceDataProvider, registryEntry);
|
||||
|
||||
// Start listening for surface data events
|
||||
AZ_Assert((m_providerHandle != InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
|
||||
SurfaceDataProviderRequestBus::Handler::BusConnect(m_providerHandle);
|
||||
}
|
||||
else if (meshValidBeforeUpdate && !meshValidAfterUpdate)
|
||||
{
|
||||
// Our mesh has stopped being valid, so unregister and stop listening for surface data events
|
||||
AZ_Assert((m_providerHandle != InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
|
||||
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle);
|
||||
m_providerHandle = InvalidSurfaceDataRegistryHandle;
|
||||
|
||||
SurfaceDataProviderRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
else if (meshValidBeforeUpdate && meshValidAfterUpdate)
|
||||
{
|
||||
// Our mesh was valid before and after, it just changed in some way, so update our registry entry.
|
||||
AZ_Assert((m_providerHandle != InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
|
||||
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::UpdateSurfaceDataProvider, m_providerHandle, registryEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
|
||||
#include <SurfaceData/SurfaceDataProviderRequestBus.h>
|
||||
#include <SurfaceData/SurfaceDataTypes.h>
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
template<typename, typename>
|
||||
class EditorWrappedComponentBase;
|
||||
}
|
||||
|
||||
namespace SurfaceData
|
||||
{
|
||||
constexpr float s_rayAABBHeightPadding = 0.1f;
|
||||
|
||||
class SurfaceDataMeshConfig
|
||||
: public AZ::ComponentConfig
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(SurfaceDataMeshConfig, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(SurfaceDataMeshConfig, "{764C602E-7CA8-4BCC-AB2D-3E46623B3A20}", AZ::ComponentConfig);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
SurfaceTagVector m_tags;
|
||||
};
|
||||
|
||||
class SurfaceDataMeshComponent
|
||||
: public AZ::Component
|
||||
, public AZ::TickBus::Handler
|
||||
, public AZ::TransformNotificationBus::Handler
|
||||
, public AZ::Render::MeshComponentNotificationBus::Handler
|
||||
, public SurfaceDataProviderRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
template<typename, typename> friend class LmbrCentral::EditorWrappedComponentBase;
|
||||
AZ_COMPONENT(SurfaceDataMeshComponent, "{F8915F34-BE8B-40B4-B7E8-01EBF3DA1C95}");
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
SurfaceDataMeshComponent(const SurfaceDataMeshConfig& configuration);
|
||||
SurfaceDataMeshComponent() = default;
|
||||
~SurfaceDataMeshComponent() = default;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Component interface implementation
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
|
||||
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MeshComponentNotificationBus
|
||||
void OnModelReady(const AZ::Data::Asset<AZ::RPI::ModelAsset>& modelAsset, const AZ::Data::Instance<AZ::RPI::Model>& model) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TransformNotificationBus
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AZ::TickBus
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataProviderRequestBus
|
||||
void GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const override;
|
||||
|
||||
private:
|
||||
bool DoRayTrace(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, AZ::Vector3& outNormal) const;
|
||||
void UpdateMeshData();
|
||||
void OnCompositionChanged();
|
||||
|
||||
AZ::Aabb GetSurfaceAabb() const;
|
||||
SurfaceTagVector GetSurfaceTags() const;
|
||||
|
||||
SurfaceDataMeshConfig m_configuration;
|
||||
|
||||
SurfaceDataRegistryHandle m_providerHandle = InvalidSurfaceDataRegistryHandle;
|
||||
|
||||
// cached data
|
||||
AZStd::atomic_bool m_refresh{ false };
|
||||
mutable AZStd::recursive_mutex m_cacheMutex;
|
||||
AZ::Data::Asset<AZ::Data::AssetData> m_meshAssetData;
|
||||
AZ::Transform m_meshWorldTM = AZ::Transform::CreateIdentity();
|
||||
AZ::Transform m_meshWorldTMInverse = AZ::Transform::CreateIdentity();
|
||||
AZ::Aabb m_meshBounds = AZ::Aabb::CreateNull();
|
||||
};
|
||||
}
|
||||
+1
-1
@@ -35,7 +35,7 @@ namespace AZ
|
||||
//! ThumbnailRendererData encapsulates all data used by thumbnail renderer and caches assets
|
||||
struct ThumbnailRendererData final
|
||||
{
|
||||
static constexpr const char* LightingPresetPath = "lightingpresets/default.lightingpreset.azasset";
|
||||
static constexpr const char* LightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
static constexpr const char* DefaultModelPath = "materialeditor/viewportmodels/quadsphere.azmodel";
|
||||
static constexpr const char* DefaultMaterialPath = "materials/basic_grey.azmaterial";
|
||||
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ namespace AZ
|
||||
data->m_renderPipeline->SetDefaultView(data->m_view);
|
||||
|
||||
// Create lighting preset
|
||||
data->m_lightingPresetAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::AnyAsset>(LightingPresetPath);
|
||||
data->m_lightingPresetAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::AnyAsset>(ThumbnailRendererData::LightingPresetPath);
|
||||
if (data->m_lightingPresetAsset.IsReady())
|
||||
{
|
||||
auto preset = data->m_lightingPresetAsset->GetDataAs<Render::LightingPreset>();
|
||||
|
||||
-1
@@ -31,7 +31,6 @@ namespace AZ
|
||||
void Start() override;
|
||||
|
||||
private:
|
||||
static constexpr const char* LightingPresetPath = "lightingpresets/default.lightingpreset.azasset";
|
||||
static constexpr float AspectRatio = 1.0f;
|
||||
static constexpr float NearDist = 0.1f;
|
||||
static constexpr float FarDist = 100.0f;
|
||||
|
||||
+2
-4
@@ -19,10 +19,6 @@ set(FILES
|
||||
Source/CoreLights/EditorAreaLightComponent.cpp
|
||||
Source/CoreLights/EditorDirectionalLightComponent.h
|
||||
Source/CoreLights/EditorDirectionalLightComponent.cpp
|
||||
Source/CoreLights/EditorPointLightComponent.h
|
||||
Source/CoreLights/EditorPointLightComponent.cpp
|
||||
Source/CoreLights/EditorSpotLightComponent.h
|
||||
Source/CoreLights/EditorSpotLightComponent.cpp
|
||||
Source/Decals/EditorDecalComponent.h
|
||||
Source/Decals/EditorDecalComponent.cpp
|
||||
Source/DiffuseProbeGrid/EditorDiffuseProbeGridComponent.h
|
||||
@@ -111,5 +107,7 @@ set(FILES
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.h
|
||||
Source/Scripting/EditorEntityReferenceComponent.cpp
|
||||
Source/Scripting/EditorEntityReferenceComponent.h
|
||||
Source/SurfaceData/EditorSurfaceDataMeshComponent.cpp
|
||||
Source/SurfaceData/EditorSurfaceDataMeshComponent.h
|
||||
Resources/AtomLyIntegrationResources.qrc
|
||||
)
|
||||
+8
-11
@@ -27,21 +27,16 @@ set(FILES
|
||||
Source/CoreLights/LightDelegateBase.h
|
||||
Source/CoreLights/LightDelegateBase.inl
|
||||
Source/CoreLights/LightDelegateInterface.h
|
||||
Source/CoreLights/PointLightComponent.h
|
||||
Source/CoreLights/PointLightComponent.cpp
|
||||
Source/CoreLights/PointLightComponentController.h
|
||||
Source/CoreLights/PointLightComponentController.cpp
|
||||
Source/CoreLights/PolygonLightDelegate.h
|
||||
Source/CoreLights/PolygonLightDelegate.cpp
|
||||
Source/CoreLights/QuadLightDelegate.h
|
||||
Source/CoreLights/QuadLightDelegate.cpp
|
||||
Source/CoreLights/SimplePointLightDelegate.h
|
||||
Source/CoreLights/SimplePointLightDelegate.cpp
|
||||
Source/CoreLights/SimpleSpotLightDelegate.h
|
||||
Source/CoreLights/SimpleSpotLightDelegate.cpp
|
||||
Source/CoreLights/SphereLightDelegate.h
|
||||
Source/CoreLights/SphereLightDelegate.cpp
|
||||
Source/CoreLights/SpotLightComponent.h
|
||||
Source/CoreLights/SpotLightComponent.cpp
|
||||
Source/CoreLights/SpotLightComponentConfig.cpp
|
||||
Source/CoreLights/SpotLightComponentController.h
|
||||
Source/CoreLights/SpotLightComponentController.cpp
|
||||
Source/Decals/DecalComponent.h
|
||||
Source/Decals/DecalComponent.cpp
|
||||
Source/Decals/DecalComponentController.h
|
||||
@@ -117,8 +112,8 @@ set(FILES
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierComponent.h
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierComponent.cpp
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierComponentConfig.cpp
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierComponentController.h
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierComponentController.cpp
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierController.h
|
||||
Source/PostProcess/GradientWeightModifier/GradientWeightModifierController.cpp
|
||||
Source/ScreenSpace/DeferredFogComponentController.h
|
||||
Source/ScreenSpace/DeferredFogComponentController.cpp
|
||||
Source/ScreenSpace/DeferredFogComponent.h
|
||||
@@ -145,4 +140,6 @@ set(FILES
|
||||
Source/Scripting/EntityReferenceComponentConfig.cpp
|
||||
Source/Scripting/EntityReferenceComponentController.cpp
|
||||
Source/Scripting/EntityReferenceComponentController.h
|
||||
Source/SurfaceData/SurfaceDataMeshComponent.cpp
|
||||
Source/SurfaceData/SurfaceDataMeshComponent.h
|
||||
)
|
||||
|
||||
-4
@@ -15,10 +15,6 @@ set(FILES
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/CoreLightsConstants.h
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/DirectionalLightBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/DirectionalLightComponentConfig.h
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/PointLightBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/PointLightComponentConfig.h
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/SpotLightBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/CoreLights/SpotLightComponentConfig.h
|
||||
Include/AtomLyIntegration/CommonFeatures/Decals/DecalBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/Decals/DecalComponentConfig.h
|
||||
Include/AtomLyIntegration/CommonFeatures/Decals/DecalConstants.h
|
||||
|
||||
Reference in New Issue
Block a user