Add an Orthogonal Projection option to the Camera Gem (#2414)
* Add an Orthogonal Projection option to the Camera Gem This adds a check-box to opt into an ortho projection along with a half-width parameter to adjust the size of the visible area. Includes some light tweaks to ensure debug rendering looks OK and that we generate a correct camera state for these non-perspective views. Known issue: while in "Be this camera" mode in the Editor using an ortho projection manipulators aren't working correctly. This appears to be a downstream issue with CameraState consumers not actually checking the ortho flag. Signed-off-by: nvsickle <nvsickle@amazon.com> * Fix some typos Signed-off-by: nvsickle <nvsickle@amazon.com> * Account for reversed depth buffer Signed-off-by: nvsickle <nvsickle@amazon.com> * Clarify depth reversal for MakeOrthographicMatrixRH Signed-off-by: nvsickle <nvsickle@amazon.com>
This commit is contained in:
committed by
GitHub
parent
e81f59d1e1
commit
7f84a4318c
@@ -24,7 +24,9 @@ namespace Camera
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<CameraComponentConfig, AZ::ComponentConfig>()
|
||||
->Version(2)
|
||||
->Version(3)
|
||||
->Field("Orthographic", &CameraComponentConfig::m_orthographic)
|
||||
->Field("Orthographic Half Width", &CameraComponentConfig::m_orthographicHalfWidth)
|
||||
->Field("Field of View", &CameraComponentConfig::m_fov)
|
||||
->Field("Near Clip Plane Distance", &CameraComponentConfig::m_nearClipDistance)
|
||||
->Field("Far Clip Plane Distance", &CameraComponentConfig::m_farClipDistance)
|
||||
@@ -42,25 +44,33 @@ namespace Camera
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_makeActiveViewOnActivation,
|
||||
"Make active camera on activation?", "If true, this camera will become the active render camera when it activates")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_orthographic, "Orthographic",
|
||||
"If set, this camera will use an orthographic projection instead of a perspective one. Objects will appear as the same size, regardless of distance from the camera.")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_orthographicHalfWidth, "Orthographic Half-width", "The half-width used to calculate the orthographic projection. The height will be determined by the aspect ratio.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &CameraComponentConfig::GetOrthographicParameterVisibility)
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.001f)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_fov, "Field of view", "Vertical field of view in degrees")
|
||||
->Attribute(AZ::Edit::Attributes::Min, MIN_FOV)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " degrees")
|
||||
->Attribute(AZ::Edit::Attributes::Step, 1.f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, AZ::RadToDeg(AZ::Constants::Pi) - 0.0001f) //We assert at fovs >= Pi so set the max for this field to be just under that
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshValues", 0x28e720d4))
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &CameraComponentConfig::GetPerspectiveParameterVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_nearClipDistance, "Near clip distance",
|
||||
"Distance to the near clip plane of the view Frustum")
|
||||
->Attribute(AZ::Edit::Attributes::Min, CAMERA_MIN_NEAR)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " m")
|
||||
->Attribute(AZ::Edit::Attributes::Step, 0.1f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, &CameraComponentConfig::GetFarClipDistance)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues", 0xcbc2147c))
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_farClipDistance, "Far clip distance",
|
||||
"Distance to the far clip plane of the view Frustum")
|
||||
->Attribute(AZ::Edit::Attributes::Min, &CameraComponentConfig::GetNearClipDistance)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " m")
|
||||
->Attribute(AZ::Edit::Attributes::Step, 10.f)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues", 0xcbc2147c))
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -81,6 +91,16 @@ namespace Camera
|
||||
return AZ::EntityId(m_editorEntityId);
|
||||
}
|
||||
|
||||
AZ::u32 CameraComponentConfig::GetPerspectiveParameterVisibility() const
|
||||
{
|
||||
return m_orthographic ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
|
||||
}
|
||||
|
||||
AZ::u32 CameraComponentConfig::GetOrthographicParameterVisibility() const
|
||||
{
|
||||
return m_orthographic ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
|
||||
}
|
||||
|
||||
CameraComponentController::CameraComponentController(const CameraComponentConfig& config)
|
||||
{
|
||||
SetConfiguration(config);
|
||||
@@ -289,6 +309,16 @@ namespace Camera
|
||||
return m_config;
|
||||
}
|
||||
|
||||
AZ::RPI::ViewportContextPtr CameraComponentController::GetViewportContext()
|
||||
{
|
||||
auto atomViewportRequests = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
|
||||
if (m_atomCamera && atomViewportRequests)
|
||||
{
|
||||
return atomViewportRequests->GetDefaultViewportContext();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AZ::EntityId CameraComponentController::GetCameras()
|
||||
{
|
||||
return m_entityId;
|
||||
@@ -324,6 +354,16 @@ namespace Camera
|
||||
return m_config.m_frustumHeight;
|
||||
}
|
||||
|
||||
bool CameraComponentController::IsOrthographic()
|
||||
{
|
||||
return m_config.m_orthographic;
|
||||
}
|
||||
|
||||
float CameraComponentController::GetOrthographicHalfWidth()
|
||||
{
|
||||
return m_config.m_orthographicHalfWidth;
|
||||
}
|
||||
|
||||
void CameraComponentController::SetFovDegrees(float fov)
|
||||
{
|
||||
m_config.m_fov = AZ::GetClamp(fov, MinFoV, MaxFoV);
|
||||
@@ -359,6 +399,18 @@ namespace Camera
|
||||
UpdateCamera();
|
||||
}
|
||||
|
||||
void CameraComponentController::SetOrthographic(bool orthographic)
|
||||
{
|
||||
m_config.m_orthographic = orthographic;
|
||||
UpdateCamera();
|
||||
}
|
||||
|
||||
void CameraComponentController::SetOrthographicHalfWidth(float halfWidth)
|
||||
{
|
||||
m_config.m_orthographicHalfWidth = halfWidth;
|
||||
UpdateCamera();
|
||||
}
|
||||
|
||||
void CameraComponentController::MakeActiveView()
|
||||
{
|
||||
// Set Legacy Cry view, if it exists
|
||||
@@ -423,30 +475,38 @@ namespace Camera
|
||||
m_view->SetCurrentParams(viewParams);
|
||||
}
|
||||
|
||||
auto atomViewportRequests = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
|
||||
if (m_atomCamera && atomViewportRequests)
|
||||
if (auto viewportContext = GetViewportContext())
|
||||
{
|
||||
AZ::Matrix4x4 viewToClipMatrix;
|
||||
float aspectRatio = m_view ? m_view->GetCamera().GetPixelAspectRatio() : 1.f;
|
||||
auto viewportContext = atomViewportRequests->GetViewportContextByName(
|
||||
atomViewportRequests->GetDefaultViewportContextName());
|
||||
if (viewportContext)
|
||||
if (!m_atomAuxGeom)
|
||||
{
|
||||
if (!m_atomAuxGeom)
|
||||
{
|
||||
SetupAtomAuxGeom(viewportContext);
|
||||
}
|
||||
auto windowSize = viewportContext->GetViewportSize();
|
||||
aspectRatio = aznumeric_cast<float>(windowSize.m_width) / aznumeric_cast<float>(windowSize.m_height);
|
||||
SetupAtomAuxGeom(viewportContext);
|
||||
}
|
||||
auto windowSize = viewportContext->GetViewportSize();
|
||||
aspectRatio = aznumeric_cast<float>(windowSize.m_width) / aznumeric_cast<float>(windowSize.m_height);
|
||||
|
||||
// This assumes a reversed depth buffer, in line with other LY Atom integration
|
||||
AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix,
|
||||
AZ::DegToRad(m_config.m_fov),
|
||||
aspectRatio,
|
||||
m_config.m_nearClipDistance,
|
||||
m_config.m_farClipDistance,
|
||||
true);
|
||||
if (m_config.m_orthographic)
|
||||
{
|
||||
AZ::MakeOrthographicMatrixRH(viewToClipMatrix,
|
||||
-m_config.m_orthographicHalfWidth,
|
||||
m_config.m_orthographicHalfWidth,
|
||||
-m_config.m_orthographicHalfWidth / aspectRatio,
|
||||
m_config.m_orthographicHalfWidth / aspectRatio,
|
||||
m_config.m_nearClipDistance,
|
||||
m_config.m_farClipDistance,
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix,
|
||||
AZ::DegToRad(m_config.m_fov),
|
||||
aspectRatio,
|
||||
m_config.m_nearClipDistance,
|
||||
m_config.m_farClipDistance,
|
||||
true);
|
||||
}
|
||||
m_updatingTransformFromEntity = true;
|
||||
m_atomCamera->SetViewToClipMatrix(viewToClipMatrix);
|
||||
m_updatingTransformFromEntity = false;
|
||||
|
||||
Reference in New Issue
Block a user