Merge branch 'development' into Atom/guthadam/atomtools_updating_cmake_config
This commit is contained in:
@@ -7,8 +7,10 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
Tests that require a GPU in order to run.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -40,6 +42,33 @@ def golden_images_directory():
|
||||
return golden_images_dir
|
||||
|
||||
|
||||
def create_screenshots_archive(screenshot_path):
|
||||
"""
|
||||
Creates a new zip file archive at archive_path containing all files listed within archive_path.
|
||||
:param screenshot_path: location containing the files to archive, the zip archive file will also be saved here.
|
||||
:return: None, but creates a new zip file archive inside path containing all of the files inside archive_path.
|
||||
"""
|
||||
files_to_archive = []
|
||||
|
||||
# Search for .png and .ppm files to add to the zip archive file.
|
||||
for (folder_name, sub_folders, file_names) in os.walk(screenshot_path):
|
||||
for file_name in file_names:
|
||||
if file_name.endswith(".png") or file_name.endswith(".ppm"):
|
||||
file_path = os.path.join(folder_name, file_name)
|
||||
files_to_archive.append(file_path)
|
||||
|
||||
# Setup variables for naming the zip archive file.
|
||||
timestamp = datetime.datetime.now().timestamp()
|
||||
formatted_timestamp = datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d_%H-%M-%S")
|
||||
screenshots_file = os.path.join(screenshot_path, f'zip_archive_{formatted_timestamp}.zip')
|
||||
|
||||
# Write all of the valid .png and .ppm files to the archive file.
|
||||
with zipfile.ZipFile(screenshots_file, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) as zip_archive:
|
||||
for file_path in files_to_archive:
|
||||
file_name = os.path.basename(file_path)
|
||||
zip_archive.write(file_path, file_name)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
|
||||
@pytest.mark.parametrize("level", ["auto_test"])
|
||||
@@ -53,8 +82,8 @@ class TestAllComponentsIndepthTests(object):
|
||||
Tests that a basic rendering level setup can be created (lighting, meshes, materials, etc.).
|
||||
"""
|
||||
# Clear existing test screenshots before starting test.
|
||||
test_screenshots = [os.path.join(
|
||||
workspace.paths.project(), DEFAULT_SUBFOLDER_PATH, screenshot_name)]
|
||||
screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
|
||||
test_screenshots = [os.path.join(screenshot_directory, screenshot_name)]
|
||||
file_system.delete(test_screenshots, True, True)
|
||||
|
||||
golden_images = [os.path.join(golden_images_directory(), screenshot_name)]
|
||||
@@ -86,6 +115,8 @@ class TestAllComponentsIndepthTests(object):
|
||||
for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
|
||||
compare_screenshots(test_screenshot, golden_screenshot)
|
||||
|
||||
create_screenshots_archive(screenshot_directory)
|
||||
|
||||
def test_LightComponent_ScreenshotMatchesGoldenImage(
|
||||
self, request, editor, workspace, project, launcher_platform, level):
|
||||
"""
|
||||
@@ -105,9 +136,10 @@ class TestAllComponentsIndepthTests(object):
|
||||
"SpotLight_5.ppm",
|
||||
"SpotLight_6.ppm",
|
||||
]
|
||||
screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
|
||||
test_screenshots = []
|
||||
for screenshot in screenshot_names:
|
||||
screenshot_path = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH, screenshot)
|
||||
screenshot_path = os.path.join(screenshot_directory, screenshot)
|
||||
test_screenshots.append(screenshot_path)
|
||||
file_system.delete(test_screenshots, True, True)
|
||||
|
||||
@@ -139,6 +171,8 @@ class TestAllComponentsIndepthTests(object):
|
||||
for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
|
||||
compare_screenshots(test_screenshot, golden_screenshot)
|
||||
|
||||
create_screenshots_archive(screenshot_directory)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('rhi', ['dx12', 'vulkan'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
|
||||
@@ -1087,6 +1087,7 @@ void EditorViewportWidget::ConnectViewportInteractionRequestBus()
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
m_viewportUi.ConnectViewportUiBus(GetViewportId());
|
||||
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusConnect();
|
||||
@@ -1097,6 +1098,7 @@ void EditorViewportWidget::DisconnectViewportInteractionRequestBus()
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusDisconnect();
|
||||
|
||||
m_viewportUi.DisconnectViewportUiBus();
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ class SANDBOX_API EditorViewportWidget final
|
||||
, private AzFramework::InputSystemCursorConstraintRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
|
||||
, private AzFramework::AssetCatalogEventBus::Handler
|
||||
, private AZ::RPI::SceneNotificationBus::Handler
|
||||
{
|
||||
@@ -128,10 +129,12 @@ private:
|
||||
CameraComponent,
|
||||
ViewSourceTypesCount,
|
||||
};
|
||||
|
||||
enum class PlayInEditorState
|
||||
{
|
||||
Editor, Starting, Started
|
||||
};
|
||||
|
||||
enum class KeyPressedState
|
||||
{
|
||||
AllUp,
|
||||
@@ -142,7 +145,7 @@ private:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Method overrides ...
|
||||
|
||||
// QWidget
|
||||
// QWidget overrides ...
|
||||
void focusOutEvent(QFocusEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
bool event(QEvent* event) override;
|
||||
@@ -150,7 +153,7 @@ private:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
|
||||
// QtViewport/IDisplayViewport/CViewport
|
||||
// QtViewport/IDisplayViewport/CViewport overrides ...
|
||||
EViewportType GetType() const override { return ET_ViewportCamera; }
|
||||
void SetType([[maybe_unused]] EViewportType type) override { assert(type == ET_ViewportCamera); };
|
||||
AzToolsFramework::ViewportInteraction::MouseInteraction BuildMouseInteraction(
|
||||
@@ -176,16 +179,17 @@ private:
|
||||
void Update() override;
|
||||
void UpdateContent(int flags) override;
|
||||
|
||||
// SceneNotificationBus
|
||||
// SceneNotificationBus overrides ...
|
||||
void OnBeginPrepareRender() override;
|
||||
|
||||
// Camera::CameraNotificationBus
|
||||
// Camera::CameraNotificationBus overrides ...
|
||||
void OnActiveViewChanged(const AZ::EntityId&) override;
|
||||
|
||||
// IEditorEventListener
|
||||
// IEditorEventListener overrides ...
|
||||
void OnEditorNotifyEvent(EEditorNotifyEvent event) override;
|
||||
|
||||
// AzToolsFramework::EditorEntityContextNotificationBus (handler moved to cpp to resolve link issues in unity builds)
|
||||
// AzToolsFramework::EditorEntityContextNotificationBus overrides ...
|
||||
// note: handler moved to cpp to resolve link issues in unity builds
|
||||
void OnStartPlayInEditor();
|
||||
void OnStopPlayInEditor();
|
||||
void OnStartPlayInEditorBegin();
|
||||
@@ -194,10 +198,10 @@ private:
|
||||
void BeginUndoTransaction() override;
|
||||
void EndUndoTransaction() override;
|
||||
|
||||
// AzFramework::InputSystemCursorConstraintRequestBus
|
||||
// AzFramework::InputSystemCursorConstraintRequestBus overrides ...
|
||||
void* GetSystemCursorConstraintWindow() const override;
|
||||
|
||||
// AzToolsFramework::ViewportFreezeRequestBus
|
||||
// AzToolsFramework::ViewportFreezeRequestBus overrides ...
|
||||
bool IsViewportInputFrozen() override;
|
||||
void FreezeViewportInput(bool freeze) override;
|
||||
|
||||
@@ -205,13 +209,15 @@ private:
|
||||
AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) override;
|
||||
AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override;
|
||||
float TerrainHeight(const AZ::Vector2& position) override;
|
||||
void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntitiesOut) override;
|
||||
bool ShowingWorldSpace() override;
|
||||
QWidget* GetWidgetForViewportContextMenu() override;
|
||||
void BeginWidgetContext() override;
|
||||
void EndWidgetContext() override;
|
||||
|
||||
// Camera::EditorCameraRequestBus
|
||||
// EditorEntityViewportInteractionRequestBus overrides ...
|
||||
void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) override;
|
||||
|
||||
// Camera::EditorCameraRequestBus overrides ...
|
||||
void SetViewFromEntityPerspective(const AZ::EntityId& entityId) override;
|
||||
void SetViewAndMovementLockFromEntityPerspective(const AZ::EntityId& entityId, bool lockCameraMovement) override;
|
||||
AZ::EntityId GetCurrentViewEntityId() override;
|
||||
@@ -327,7 +333,7 @@ private:
|
||||
// Determines also if the current camera for this viewport is default editor camera
|
||||
ViewSourceType m_viewSourceType = ViewSourceType::None;
|
||||
|
||||
// During play game in editor, holds the editor entity ID of the last
|
||||
// During play game in editor, holds the editor entity ID of the last
|
||||
AZ::EntityId m_viewEntityIdCachedForEditMode;
|
||||
|
||||
// The editor camera TM before switching to game mode
|
||||
|
||||
@@ -1092,9 +1092,8 @@ bool QtViewport::HitTest(const QPoint& point, HitContext& hitInfo)
|
||||
const int viewportId = GetViewportId();
|
||||
|
||||
AzToolsFramework::EntityIdList visibleEntityIds;
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Event(
|
||||
viewportId,
|
||||
&AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequests::FindVisibleEntities,
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Event(
|
||||
viewportId, &AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Events::FindVisibleEntities,
|
||||
visibleEntityIds);
|
||||
|
||||
// Look through all visible entities to find the closest one to the specified mouse point
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
#include <AzCore/Math/Matrix3x4.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/Component/ComponentBus.h>
|
||||
@@ -100,6 +101,8 @@ namespace AzFramework
|
||||
virtual AZ::u32 SetState(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual void PushMatrix(const AZ::Transform& tm) { (void)tm; }
|
||||
virtual void PopMatrix() {}
|
||||
virtual void PushPremultipliedMatrix(const AZ::Matrix3x4& matrix) { (void)matrix; }
|
||||
virtual AZ::Matrix3x4 PopPremultipliedMatrix() { return AZ::Matrix3x4::CreateIdentity(); }
|
||||
|
||||
protected:
|
||||
~DebugDisplayRequests() = default;
|
||||
|
||||
@@ -588,6 +588,12 @@ namespace AzFramework
|
||||
// pass through the camera's position and look vector for use in the lookAt function
|
||||
if (const auto lookAt = lookAtFn(targetCamera.Translation(), targetCamera.Rotation().GetBasisY()))
|
||||
{
|
||||
// default to internal look at behavior if the look at point matches the camera translation
|
||||
if (targetCamera.m_lookAt.IsClose(*lookAt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt);
|
||||
nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt);
|
||||
UpdateCameraFromTransform(nextCamera, transform);
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace AzFramework
|
||||
protected:
|
||||
~BoundsRequests() = default;
|
||||
};
|
||||
|
||||
using BoundsRequestBus = AZ::EBus<BoundsRequests>;
|
||||
|
||||
//! Returns a union of all local Aabbs provided by components implementing the BoundsRequestBus.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
@@ -47,18 +48,17 @@ namespace UnitTest
|
||||
m_firstPersonTranslateCamera =
|
||||
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::LookTranslation, m_translateCameraInputChannelIds);
|
||||
|
||||
auto orbitCamera =
|
||||
AZStd::make_shared<AzFramework::OrbitCameraInput>(AzFramework::InputChannelId("keyboard_key_modifier_alt_l"));
|
||||
m_orbitCamera = AZStd::make_shared<AzFramework::OrbitCameraInput>(m_orbitChannelId);
|
||||
auto orbitRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(AzFramework::InputDeviceMouse::Button::Left);
|
||||
auto orbitTranslateCamera =
|
||||
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::OrbitTranslation, m_translateCameraInputChannelIds);
|
||||
|
||||
orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera);
|
||||
orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera);
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera);
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera);
|
||||
|
||||
m_cameraSystem->m_cameras.AddCamera(m_firstPersonRotateCamera);
|
||||
m_cameraSystem->m_cameras.AddCamera(m_firstPersonTranslateCamera);
|
||||
m_cameraSystem->m_cameras.AddCamera(orbitCamera);
|
||||
m_cameraSystem->m_cameras.AddCamera(m_orbitCamera);
|
||||
|
||||
// these tests rely on using motion delta, not cursor positions (default is true)
|
||||
AzFramework::ed_cameraSystemUseCursor = false;
|
||||
@@ -68,6 +68,7 @@ namespace UnitTest
|
||||
{
|
||||
AzFramework::ed_cameraSystemUseCursor = true;
|
||||
|
||||
m_orbitCamera.reset();
|
||||
m_firstPersonRotateCamera.reset();
|
||||
m_firstPersonTranslateCamera.reset();
|
||||
|
||||
@@ -77,12 +78,14 @@ namespace UnitTest
|
||||
AllocatorsTestFixture::TearDown();
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId m_orbitChannelId = AzFramework::InputChannelId("keyboard_key_modifier_alt_l");
|
||||
AzFramework::TranslateCameraInputChannelIds m_translateCameraInputChannelIds;
|
||||
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_firstPersonRotateCamera;
|
||||
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_firstPersonTranslateCamera;
|
||||
AZStd::shared_ptr<AzFramework::OrbitCameraInput> m_orbitCamera;
|
||||
};
|
||||
|
||||
TEST_F(CameraInputFixture, Begin_and_end_OrbitCameraInput_consumes_correct_events)
|
||||
TEST_F(CameraInputFixture, BeginAndEndOrbitCameraInputConsumesCorrectEvents)
|
||||
{
|
||||
// begin orbit camera
|
||||
const bool consumed1 = HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::ModifierAltL,
|
||||
@@ -102,7 +105,7 @@ namespace UnitTest
|
||||
EXPECT_THAT(allConsumed, ElementsAre(true, false, true, false));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, Begin_CameraInput_notifies_ActivationBeganFn_for_TranslateCameraInput)
|
||||
TEST_F(CameraInputFixture, BeginCameraInputNotifiesActivationBeganFnForTranslateCameraInput)
|
||||
{
|
||||
bool activationBegan = false;
|
||||
m_firstPersonTranslateCamera->SetActivationBeganFn(
|
||||
@@ -111,13 +114,13 @@ namespace UnitTest
|
||||
activationBegan = true;
|
||||
});
|
||||
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
EXPECT_TRUE(activationBegan);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, Begin_CameraInput_notifies_ActivationBeganFn_after_delta_for_RotateCameraInput)
|
||||
TEST_F(CameraInputFixture, BeginCameraInputNotifiesActivationBeganFnAfterDeltaForRotateCameraInput)
|
||||
{
|
||||
bool activationBegan = false;
|
||||
m_firstPersonRotateCamera->SetActivationBeganFn(
|
||||
@@ -133,7 +136,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(activationBegan);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, Begin_CameraInput_does_not_notify_ActivationBeganFn_with_no_delta_for_RotateCameraInput)
|
||||
TEST_F(CameraInputFixture, BeginCameraInputDoesNotNotifyActivationBeganFnWithNoDeltaForRotateCameraInput)
|
||||
{
|
||||
bool activationBegan = false;
|
||||
m_firstPersonRotateCamera->SetActivationBeganFn(
|
||||
@@ -148,7 +151,7 @@ namespace UnitTest
|
||||
EXPECT_FALSE(activationBegan);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, End_CameraInput_notifies_ActivationEndFn_after_delta_for_RotateCameraInput)
|
||||
TEST_F(CameraInputFixture, EndCameraInputNotifiesActivationEndFnAfterDeltaForRotateCameraInput)
|
||||
{
|
||||
bool activationEnded = false;
|
||||
m_firstPersonRotateCamera->SetActivationEndedFn(
|
||||
@@ -166,7 +169,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(activationEnded);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, End_CameraInput_does_not_notify_ActivationBeganFn_or_ActivationBeganFn_with_no_delta_for_RotateCameraInput)
|
||||
TEST_F(CameraInputFixture, EndCameraInputDoesNotNotifyActivationBeganFnOrActivationBeganFnWithNoDeltaForRotateCameraInput)
|
||||
{
|
||||
bool activationBegan = false;
|
||||
m_firstPersonRotateCamera->SetActivationBeganFn(
|
||||
@@ -191,7 +194,7 @@ namespace UnitTest
|
||||
EXPECT_FALSE(activationEnded);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, End_CameraInput_notifies_ActivationBeganFn_or_ActivationEndFn_with_TranslateCamera)
|
||||
TEST_F(CameraInputFixture, End_CameraInputNotifiesActivationBeganFnOrActivationEndFnWithTranslateCamera)
|
||||
{
|
||||
bool activationBegan = false;
|
||||
m_firstPersonTranslateCamera->SetActivationBeganFn(
|
||||
@@ -207,16 +210,16 @@ namespace UnitTest
|
||||
activationEnded = true;
|
||||
});
|
||||
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId, AzFramework::InputChannel::State::Ended });
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Ended });
|
||||
|
||||
EXPECT_TRUE(activationBegan);
|
||||
EXPECT_TRUE(activationEnded);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, End_activation_called_for_CameraInput_if_active_when_cameras_are_cleared)
|
||||
TEST_F(CameraInputFixture, EndActivationCalledForCameraInputIfActiveWhenCamerasAreCleared)
|
||||
{
|
||||
bool activationEnded = false;
|
||||
m_firstPersonTranslateCamera->SetActivationEndedFn(
|
||||
@@ -225,11 +228,37 @@ namespace UnitTest
|
||||
activationEnded = true;
|
||||
});
|
||||
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
m_cameraSystem->m_cameras.Clear();
|
||||
|
||||
EXPECT_TRUE(activationEnded);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, OrbitCameraInputHandlesLookAtPointAndSelfAtSamePositionWhenOrbiting)
|
||||
{
|
||||
// create pathological lookAtFn that just returns the same position as the camera
|
||||
m_orbitCamera->SetLookAtFn(
|
||||
[](const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
|
||||
{
|
||||
return position;
|
||||
});
|
||||
|
||||
AzFramework::UpdateCameraFromTransform(
|
||||
m_targetCamera,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(0.0f, 0.0f, 90.0f)), AZ::Vector3(10.0f, 10.0f, 10.0f)));
|
||||
|
||||
m_camera = m_targetCamera;
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
|
||||
// verify the camera yaw has not changed and the look at point
|
||||
// does not match that of the camera translation
|
||||
using ::testing::Eq;
|
||||
using ::testing::Not;
|
||||
EXPECT_THAT(m_camera.m_yaw, Eq(AZ::DegToRad(90.0f)));
|
||||
EXPECT_THAT(m_camera.m_lookAt, Not(IsClose(m_camera.Translation())));
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
+3
@@ -45,6 +45,9 @@ namespace AzManipulatorTestFramework
|
||||
virtual void SetAngularStep(float step) = 0;
|
||||
//! Get the viewport id.
|
||||
virtual int GetViewportId() const = 0;
|
||||
//! Updates the visibility state.
|
||||
//! Updates which entities are currently visible given the current camera state.
|
||||
virtual void UpdateVisibility() = 0;
|
||||
};
|
||||
|
||||
//! This interface is used to simulate the manipulator manager while the manipulators are under test.
|
||||
|
||||
+6
-8
@@ -12,8 +12,8 @@
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace UnitTest
|
||||
@@ -21,20 +21,18 @@ namespace UnitTest
|
||||
//! Fixture to provide the indirect call viewport interaction that is dependent on AzToolsFramework::ToolsApplication.
|
||||
//! \tparam ToolsApplicationFixtureT The fixture that provides the AzToolsFramework::ToolsApplication functionality.
|
||||
template<typename ToolsApplicationFixtureT>
|
||||
class IndirectCallManipulatorViewportInteractionFixtureMixin
|
||||
: public ToolsApplicationFixtureT
|
||||
class IndirectCallManipulatorViewportInteractionFixtureMixin : public ToolsApplicationFixtureT
|
||||
{
|
||||
using IndirectCallManipulatorViewportInteraction =
|
||||
AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction;
|
||||
using IndirectCallManipulatorViewportInteraction = AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction;
|
||||
using ImmediateModeActionDispatcher = AzManipulatorTestFramework::ImmediateModeActionDispatcher;
|
||||
|
||||
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
ToolsApplicationFixtureT::SetUpEditorFixtureImpl();
|
||||
m_viewportManipulatorInteraction = AZStd::make_unique<IndirectCallManipulatorViewportInteraction>();
|
||||
m_actionDispatcher = AZStd::make_unique<ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction);
|
||||
m_cameraState = AzFramework::CreateIdentityDefaultCamera(
|
||||
AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
|
||||
m_cameraState =
|
||||
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
|
||||
}
|
||||
|
||||
void TearDownEditorFixtureImpl() override
|
||||
|
||||
+3
-4
@@ -9,8 +9,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
@@ -18,13 +18,12 @@ namespace AzManipulatorTestFramework
|
||||
class IndirectCallManipulatorManager;
|
||||
|
||||
//! Implementation of manipulator viewport interaction that manipulates the manager indirectly via bus calls.
|
||||
class IndirectCallManipulatorViewportInteraction
|
||||
: public ManipulatorViewportInteraction
|
||||
class IndirectCallManipulatorViewportInteraction : public ManipulatorViewportInteraction
|
||||
{
|
||||
public:
|
||||
IndirectCallManipulatorViewportInteraction();
|
||||
~IndirectCallManipulatorViewportInteraction();
|
||||
|
||||
|
||||
// ManipulatorViewportInteractionInterface ...
|
||||
const ViewportInteractionInterface& GetViewportInteraction() const override;
|
||||
const ManipulatorManagerInterface& GetManipulatorManager() const override;
|
||||
|
||||
+7
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Visibility/EntityVisibilityQuery.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
@@ -19,6 +20,7 @@ namespace AzManipulatorTestFramework
|
||||
: public ViewportInteractionInterface
|
||||
, public AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler
|
||||
, public AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
ViewportInteraction();
|
||||
@@ -34,6 +36,7 @@ namespace AzManipulatorTestFramework
|
||||
void SetGridSize(float size) override;
|
||||
void SetAngularStep(float step) override;
|
||||
int GetViewportId() const override;
|
||||
void UpdateVisibility() override;
|
||||
|
||||
// ViewportInteractionRequestBus overrides ...
|
||||
AzFramework::CameraState GetCameraState() override;
|
||||
@@ -52,7 +55,11 @@ namespace AzManipulatorTestFramework
|
||||
float ManipulatorLineBoundWidth() const override;
|
||||
float ManipulatorCircleBoundWidth() const override;
|
||||
|
||||
// EditorEntityViewportInteractionRequestBus overrides ...
|
||||
void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) override;
|
||||
|
||||
private:
|
||||
AzFramework::EntityVisibilityQuery m_entityVisibilityQuery;
|
||||
AZStd::unique_ptr<NullDebugDisplayRequests> m_nullDebugDisplayRequests;
|
||||
const int m_viewportId = 1234; // Arbitrary viewport id for manipulator tests
|
||||
AzFramework::CameraState m_cameraState;
|
||||
|
||||
+3
-3
@@ -91,12 +91,12 @@ namespace AzManipulatorTestFramework
|
||||
AzToolsFramework::ViewportInteraction::MousePick BuildMousePick(
|
||||
const AzFramework::ScreenPoint& screenPoint, const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
const auto screenToWorld = AzFramework::ScreenToWorld(screenPoint, cameraState);
|
||||
const auto nearPlaneWorldPosition = AzFramework::ScreenToWorld(screenPoint, cameraState);
|
||||
|
||||
AzToolsFramework::ViewportInteraction::MousePick mousePick;
|
||||
mousePick.m_screenCoordinates = screenPoint;
|
||||
mousePick.m_rayOrigin = screenToWorld;
|
||||
mousePick.m_rayDirection = (screenToWorld - cameraState.m_position).GetNormalized();
|
||||
mousePick.m_rayOrigin = cameraState.m_position;
|
||||
mousePick.m_rayDirection = (nearPlaneWorldPosition - cameraState.m_position).GetNormalized();
|
||||
|
||||
return mousePick;
|
||||
}
|
||||
|
||||
+4
-4
@@ -16,8 +16,7 @@ namespace AzManipulatorTestFramework
|
||||
using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
|
||||
|
||||
//! Implementation of the manipulator interface using bus calls to access to the manipulator manager.
|
||||
class IndirectCallManipulatorManager
|
||||
: public ManipulatorManagerInterface
|
||||
class IndirectCallManipulatorManager : public ManipulatorManagerInterface
|
||||
{
|
||||
public:
|
||||
IndirectCallManipulatorManager(ViewportInteractionInterface& viewportInteraction);
|
||||
@@ -39,11 +38,12 @@ namespace AzManipulatorTestFramework
|
||||
|
||||
void IndirectCallManipulatorManager::ConsumeMouseInteractionEvent(const MouseInteractionEvent& event)
|
||||
{
|
||||
m_viewportInteraction.UpdateVisibility();
|
||||
|
||||
DrawManipulators();
|
||||
AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(),
|
||||
&AzToolsFramework::ViewportInteraction::InternalMouseViewportRequests::InternalHandleAllMouseInteractions,
|
||||
event);
|
||||
&AzToolsFramework::ViewportInteraction::InternalMouseViewportRequests::InternalHandleAllMouseInteractions, event);
|
||||
DrawManipulators();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,12 @@ namespace AzManipulatorTestFramework
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler::BusConnect(m_viewportId);
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusConnect(m_viewportId);
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusConnect(m_viewportId);
|
||||
}
|
||||
|
||||
ViewportInteraction::~ViewportInteraction()
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
@@ -74,6 +76,16 @@ namespace AzManipulatorTestFramework
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
void ViewportInteraction::FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntitiesOut)
|
||||
{
|
||||
visibleEntitiesOut.assign(m_entityVisibilityQuery.Begin(), m_entityVisibilityQuery.End());
|
||||
}
|
||||
|
||||
void ViewportInteraction::UpdateVisibility()
|
||||
{
|
||||
m_entityVisibilityQuery.UpdateVisibility(m_cameraState);
|
||||
}
|
||||
|
||||
AzFramework::ScreenPoint ViewportInteraction::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
|
||||
{
|
||||
return AzFramework::WorldToScreen(worldPosition, m_cameraState);
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZ::EBusReduceResult<AZ::Aabb, AzFramework::AabbUnionAggregator> aabbResult(AZ::Aabb::CreateNull());
|
||||
EditorComponentSelectionRequestsBus::EventResult(
|
||||
aabbResult, entityId, &EditorComponentSelectionRequests::GetEditorSelectionBoundsViewport, viewportInfo);
|
||||
aabbResult, entityId, &EditorComponentSelectionRequestsBus::Events::GetEditorSelectionBoundsViewport, viewportInfo);
|
||||
|
||||
return aabbResult.value;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,25 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction(
|
||||
const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
||||
{
|
||||
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left())
|
||||
{
|
||||
if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down)
|
||||
{
|
||||
return AzFramework::ClickDetector::ClickEvent::Down;
|
||||
}
|
||||
|
||||
if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Up)
|
||||
{
|
||||
return AzFramework::ClickDetector::ClickEvent::Up;
|
||||
}
|
||||
}
|
||||
|
||||
return AzFramework::ClickDetector::ClickEvent::Nil;
|
||||
}
|
||||
|
||||
float ManipulatorLineBoundWidth(const AzFramework::ViewportId viewportId /*= AzFramework::InvalidViewportId*/)
|
||||
{
|
||||
float lineBoundWidth = 0.0f;
|
||||
|
||||
@@ -250,8 +250,6 @@ namespace AzToolsFramework
|
||||
virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0;
|
||||
//! Return the terrain height given a world position in 2d (xy plane).
|
||||
virtual float TerrainHeight(const AZ::Vector2& position) = 0;
|
||||
//! Given the current view frustum (viewport) return all visible entities.
|
||||
virtual void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) = 0;
|
||||
//! Is the user holding a modifier key to move the manipulator space from local to world.
|
||||
virtual bool ShowingWorldSpace() = 0;
|
||||
//! Return the widget to use as the parent for the viewport context menu.
|
||||
@@ -269,7 +267,20 @@ namespace AzToolsFramework
|
||||
//! Type to inherit to implement MainEditorViewportInteractionRequests.
|
||||
using MainEditorViewportInteractionRequestBus = AZ::EBus<MainEditorViewportInteractionRequests, ViewportEBusTraits>;
|
||||
|
||||
//! Viewport requests for managing the viewport's cursor state.
|
||||
//! Editor entity requests to be made about the viewport.
|
||||
class EditorEntityViewportInteractionRequests
|
||||
{
|
||||
public:
|
||||
//! Given the current view frustum (viewport) return all visible entities.
|
||||
virtual void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) = 0;
|
||||
|
||||
protected:
|
||||
~EditorEntityViewportInteractionRequests() = default;
|
||||
};
|
||||
|
||||
using EditorEntityViewportInteractionRequestBus = AZ::EBus<EditorEntityViewportInteractionRequests, ViewportEBusTraits>;
|
||||
|
||||
//! Viewport requests for managing the viewport cursor state.
|
||||
class ViewportMouseCursorRequests
|
||||
{
|
||||
public:
|
||||
@@ -321,23 +332,8 @@ namespace AzToolsFramework
|
||||
|
||||
//! Maps a mouse interaction event to a ClickDetector event.
|
||||
//! @note Function only cares about up or down events, all other events are mapped to Nil (ignored).
|
||||
inline AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction(
|
||||
const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
||||
{
|
||||
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left())
|
||||
{
|
||||
if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down)
|
||||
{
|
||||
return AzFramework::ClickDetector::ClickEvent::Down;
|
||||
}
|
||||
|
||||
if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Up)
|
||||
{
|
||||
return AzFramework::ClickDetector::ClickEvent::Up;
|
||||
}
|
||||
}
|
||||
return AzFramework::ClickDetector::ClickEvent::Nil;
|
||||
}
|
||||
AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction(
|
||||
const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
|
||||
|
||||
//! Wrap EBus call to retrieve manipulator line bound width.
|
||||
//! @note It is possible to pass AzFramework::InvalidViewportId (the default) to perform a Broadcast as opposed to a targeted Event.
|
||||
|
||||
+18
-8
@@ -19,7 +19,7 @@
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
// default ray length for picking in the viewport
|
||||
static const float s_pickRayLength = 1000.0f;
|
||||
static const float EditorPickRayLength = 1000.0f;
|
||||
|
||||
AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot)
|
||||
{
|
||||
@@ -60,16 +60,27 @@ namespace AzToolsFramework
|
||||
return screenPosition;
|
||||
}
|
||||
|
||||
bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb)
|
||||
bool AabbIntersectRay(const AZ::Vector3& origin, const AZ::Vector3& direction, const AZ::Aabb& aabb, float& distance)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
|
||||
const AZ::Vector3 rayScaledDir = mouseInteraction.m_mousePick.m_rayDirection * s_pickRayLength;
|
||||
const AZ::Vector3 rayScaledDir = direction * EditorPickRayLength;
|
||||
|
||||
AZ::Vector3 startNormal;
|
||||
float t, end;
|
||||
return AZ::Intersect::IntersectRayAABB(
|
||||
mouseInteraction.m_mousePick.m_rayOrigin, rayScaledDir, rayScaledDir.GetReciprocal(), aabb, t, end, startNormal) > 0;
|
||||
AZ::Vector3 startNormal;
|
||||
if (AZ::Intersect::IntersectRayAABB(origin, rayScaledDir, rayScaledDir.GetReciprocal(), aabb, t, end, startNormal) > 0)
|
||||
{
|
||||
distance = t * EditorPickRayLength;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb)
|
||||
{
|
||||
float unused;
|
||||
return AabbIntersectRay(mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, aabb, unused);
|
||||
}
|
||||
|
||||
bool PickEntity(
|
||||
@@ -117,8 +128,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
float scaling = 1.0f;
|
||||
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
|
||||
scaling, viewportId,
|
||||
&ViewportInteraction::ViewportInteractionRequestBus::Events::DeviceScalingFactor);
|
||||
scaling, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::DeviceScalingFactor);
|
||||
|
||||
return scaling;
|
||||
}
|
||||
|
||||
+4
@@ -46,6 +46,10 @@ namespace AzToolsFramework
|
||||
//! in screen space intersected an aabb in world space.
|
||||
bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb);
|
||||
|
||||
//! Wrapper to perform an intersection between a ray and an aabb.
|
||||
//! Note: direction should be normalized (it is scaled internally by the editor pick distance).
|
||||
bool AabbIntersectRay(const AZ::Vector3& origin, const AZ::Vector3& direction, const AZ::Aabb& aabb, float& distance);
|
||||
|
||||
//! Return if a mouse interaction (pick ray) did intersect the tested EntityId.
|
||||
bool PickEntity(
|
||||
AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction, float& closestDistance, int viewportId);
|
||||
|
||||
+2
-2
@@ -161,8 +161,8 @@ namespace AzToolsFramework
|
||||
|
||||
// request list of visible entities from authoritative system
|
||||
EntityIdList nextVisibleEntityIds;
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::Event(
|
||||
viewportInfo.m_viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::FindVisibleEntities,
|
||||
ViewportInteraction::EditorEntityViewportInteractionRequestBus::Event(
|
||||
viewportInfo.m_viewportId, &ViewportInteraction::EditorEntityViewportInteractionRequestBus::Events::FindVisibleEntities,
|
||||
nextVisibleEntityIds);
|
||||
|
||||
// only bother resorting if we know the lists have changed
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ComponentModeTestDoubles.h"
|
||||
#include "ComponentModeTestFixture.h"
|
||||
#include "ComponentModeTestDoubles.h"
|
||||
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
|
||||
@@ -15,17 +15,15 @@ namespace UnitTest
|
||||
{
|
||||
void ComponentModeTestFixture::SetUpEditorFixtureImpl()
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
using namespace AzToolsFramework::ComponentModeFramework;
|
||||
namespace AztfCmf = AzToolsFramework::ComponentModeFramework;
|
||||
|
||||
auto* app = GetApplication();
|
||||
ASSERT_TRUE(app);
|
||||
|
||||
app->RegisterComponentDescriptor(PlaceholderEditorComponent::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(AnotherPlaceholderEditorComponent::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(DependentPlaceholderEditorComponent::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(AztfCmf::PlaceholderEditorComponent::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(AztfCmf::AnotherPlaceholderEditorComponent::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(AztfCmf::DependentPlaceholderEditorComponent::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(
|
||||
TestComponentModeComponent<OverrideMouseInteractionComponentMode>::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(IncompatiblePlaceholderEditorComponent::CreateDescriptor());
|
||||
AztfCmf::TestComponentModeComponent<AztfCmf::OverrideMouseInteractionComponentMode>::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(AztfCmf::IncompatiblePlaceholderEditorComponent::CreateDescriptor());
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -178,7 +178,7 @@ void CSystem::LogVersion()
|
||||
strftime(s, 128, "%d %b %y (%H %M %S)", today);
|
||||
#endif
|
||||
|
||||
const SFileVersion& ver = GetFileVersion();
|
||||
[[maybe_unused]] const SFileVersion& ver = GetFileVersion();
|
||||
|
||||
CryLogAlways("BackupNameAttachment=\" Build(%d) %s\" -- used by backup system\n", ver.v[0], s); // read by CreateBackupFile()
|
||||
|
||||
@@ -249,7 +249,7 @@ void CSystem::LogVersion()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSystem::LogBuildInfo()
|
||||
{
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
[[maybe_unused]] auto projectName = AZ::Utils::GetProjectName();
|
||||
CryLogAlways("GameName: %s", projectName.c_str());
|
||||
CryLogAlways("BuildTime: " __DATE__ " " __TIME__);
|
||||
}
|
||||
|
||||
@@ -115,10 +115,13 @@ namespace AZ
|
||||
AZ_Assert(m_shaderResourceGroup, "RayTracingPass [%s]: Failed to create RayTracingGlobalSrg", GetPathName().GetCStr());
|
||||
RPI::PassUtils::BindDataMappingsToSrg(m_passDescriptor, m_shaderResourceGroup.get());
|
||||
|
||||
// check to see if the shader requires the View and RayTracingMaterial Srgs
|
||||
// check to see if the shader requires the View, Scene, or RayTracingMaterial Srgs
|
||||
const auto& viewSrgLayout = m_rayGenerationShader->FindShaderResourceGroupLayout(RPI::SrgBindingSlot::View);
|
||||
m_requiresViewSrg = (viewSrgLayout != nullptr);
|
||||
|
||||
const auto& sceneSrgLayout = m_rayGenerationShader->FindShaderResourceGroupLayout(RPI::SrgBindingSlot::Scene);
|
||||
m_requiresSceneSrg = (sceneSrgLayout != nullptr);
|
||||
|
||||
const auto& rayTracingMaterialSrgLayout = m_rayGenerationShader->FindShaderResourceGroupLayout(RayTracingMaterialSrgBindingSlot);
|
||||
m_requiresRayTracingMaterialSrg = (rayTracingMaterialSrgLayout != nullptr);
|
||||
|
||||
@@ -324,6 +327,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
if (m_requiresSceneSrg)
|
||||
{
|
||||
shaderResourceGroups.push_back(scene->GetShaderResourceGroup()->GetRHIShaderResourceGroup());
|
||||
}
|
||||
|
||||
if (m_requiresRayTracingMaterialSrg)
|
||||
{
|
||||
shaderResourceGroups.push_back(rayTracingFeatureProcessor->GetRayTracingMaterialSrg()->GetRHIShaderResourceGroup());
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace AZ
|
||||
RHI::ConstPtr<RHI::PipelineState> m_globalPipelineState;
|
||||
RHI::Ptr<RHI::RayTracingShaderTable> m_rayTracingShaderTable;
|
||||
bool m_requiresViewSrg = false;
|
||||
bool m_requiresSceneSrg = false;
|
||||
bool m_requiresRayTracingMaterialSrg = false;
|
||||
};
|
||||
} // namespace RPI
|
||||
|
||||
+2
@@ -73,6 +73,7 @@ namespace AtomToolsFramework
|
||||
|
||||
return AZ::Transform::CreateIdentity();
|
||||
}
|
||||
|
||||
void ModularCameraViewportContextImpl::SetCameraTransform(const AZ::Transform& transform)
|
||||
{
|
||||
if (auto viewportContext = RetrieveViewportContext(m_viewportId))
|
||||
@@ -80,6 +81,7 @@ namespace AtomToolsFramework
|
||||
viewportContext->SetCameraTransform(transform);
|
||||
}
|
||||
}
|
||||
|
||||
void ModularCameraViewportContextImpl::ConnectViewMatrixChangedHandler(AZ::RPI::ViewportContext::MatrixChangedEvent::Handler& handler)
|
||||
{
|
||||
if (auto viewportContext = RetrieveViewportContext(m_viewportId))
|
||||
|
||||
@@ -1552,6 +1552,26 @@ namespace AZ::AtomBridge
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::PushPremultipliedMatrix(const AZ::Matrix3x4& matrix)
|
||||
{
|
||||
AZ_Assert(m_rendState.m_currentTransform < RenderState::TransformStackSize, "Exceeded AtomDebugDisplayViewportInterface matrix stack size");
|
||||
if (m_rendState.m_currentTransform < RenderState::TransformStackSize)
|
||||
{
|
||||
m_rendState.m_currentTransform++;
|
||||
m_rendState.m_transformStack[m_rendState.m_currentTransform] = matrix;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Matrix3x4 AtomDebugDisplayViewportInterface::PopPremultipliedMatrix()
|
||||
{
|
||||
AZ_Assert(m_rendState.m_currentTransform > 0, "Underflowed AtomDebugDisplayViewportInterface matrix stack");
|
||||
if (m_rendState.m_currentTransform > 0)
|
||||
{
|
||||
m_rendState.m_currentTransform--;
|
||||
}
|
||||
return m_rendState.m_transformStack[m_rendState.m_currentTransform + 1];
|
||||
}
|
||||
|
||||
const AZ::Matrix3x4& AtomDebugDisplayViewportInterface::GetCurrentTransform() const
|
||||
{
|
||||
return m_rendState.m_transformStack[m_rendState.m_currentTransform];
|
||||
|
||||
@@ -193,6 +193,8 @@ namespace AZ::AtomBridge
|
||||
AZ::u32 SetState(AZ::u32 state) override;
|
||||
void PushMatrix(const AZ::Transform& tm) override;
|
||||
void PopMatrix() override;
|
||||
void PushPremultipliedMatrix(const AZ::Matrix3x4& matrix) override;
|
||||
AZ::Matrix3x4 PopPremultipliedMatrix() override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/FileFunc/FileFunc.h>
|
||||
|
||||
// For AZ_Printf statements...
|
||||
#define WWISE_CONFIG_WINDOW "WwiseConfig"
|
||||
@@ -56,7 +56,7 @@ namespace Audio::Wwise
|
||||
bool ConfigurationSettings::Load(const AZStd::string& filePath)
|
||||
{
|
||||
AZ::IO::Path fileIoPath(filePath);
|
||||
auto outcome = AzFramework::FileFunc::ReadJsonFile(fileIoPath);
|
||||
auto outcome = AZ::JsonSerializationUtils::ReadJsonFile(fileIoPath.Native());
|
||||
if (!outcome)
|
||||
{
|
||||
AZ_Printf(WWISE_CONFIG_WINDOW, "ERROR: %s\n", outcome.GetError().c_str());
|
||||
@@ -92,7 +92,7 @@ namespace Audio::Wwise
|
||||
return false;
|
||||
}
|
||||
|
||||
auto outcome = AzFramework::FileFunc::WriteJsonFile(jsonDoc, filePath);
|
||||
auto outcome = AZ::JsonSerializationUtils::WriteJsonFile(jsonDoc, filePath);
|
||||
if (!outcome)
|
||||
{
|
||||
AZ_Printf(WWISE_CONFIG_WINDOW, "ERROR: %s\n", outcome.GetError().c_str());
|
||||
|
||||
@@ -19,9 +19,7 @@
|
||||
#include <AudioEngineWwise_Traits_Platform.h>
|
||||
#include <cinttypes>
|
||||
|
||||
#define MAX_NUMBER_STRING_SIZE (10) // 4G
|
||||
#define ID_TO_STRING_FORMAT_BANK AKTEXT("%u.bnk")
|
||||
#define ID_TO_STRING_FORMAT_WEM AKTEXT("%u.wem")
|
||||
#define MAX_NUMBER_STRING_SIZE (10) // max digits in u32 base-10 number
|
||||
#define MAX_EXTENSION_SIZE (4) // .xxx
|
||||
#define MAX_FILETITLE_SIZE (MAX_NUMBER_STRING_SIZE + MAX_EXTENSION_SIZE + 1) // null-terminated
|
||||
|
||||
@@ -442,11 +440,16 @@ namespace Audio
|
||||
}
|
||||
}
|
||||
|
||||
AkOSChar fileName[MAX_FILETITLE_SIZE] = { '\0' };
|
||||
AkOSChar fileName[MAX_FILETITLE_SIZE] = { 0 };
|
||||
|
||||
const AkOSChar* const filenameFormat = (flags->uCodecID == AKCODECID_BANK ? ID_TO_STRING_FORMAT_BANK : ID_TO_STRING_FORMAT_WEM);
|
||||
|
||||
AK_OSPRINTF(fileName, MAX_FILETITLE_SIZE, filenameFormat, static_cast<int unsigned>(fileID));
|
||||
if (flags->uCodecID == AKCODECID_BANK)
|
||||
{
|
||||
AK_OSPRINTF(fileName, MAX_FILETITLE_SIZE, AKTEXT("%u.bnk"), static_cast<unsigned int>(fileID));
|
||||
}
|
||||
else
|
||||
{
|
||||
AK_OSPRINTF(fileName, MAX_FILETITLE_SIZE, AKTEXT("%u.wem"), static_cast<unsigned int>(fileID));
|
||||
}
|
||||
|
||||
AKPLATFORM::SafeStrCat(finalFilePath, fileName, AK_MAX_PATH);
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
// Shape components
|
||||
#include "Shape/SphereShapeComponent.h"
|
||||
#include "Shape/DiskShapeComponent.h"
|
||||
#include "Shape/AxisAlignedBoxShapeComponent.h"
|
||||
#include "Shape/BoxShapeComponent.h"
|
||||
#include "Shape/QuadShapeComponent.h"
|
||||
#include "Shape/CylinderShapeComponent.h"
|
||||
@@ -202,6 +203,7 @@ namespace LmbrCentral
|
||||
SphereShapeComponent::CreateDescriptor(),
|
||||
DiskShapeComponent::CreateDescriptor(),
|
||||
BoxShapeComponent::CreateDescriptor(),
|
||||
AxisAlignedBoxShapeComponent::CreateDescriptor(),
|
||||
QuadShapeComponent::CreateDescriptor(),
|
||||
CylinderShapeComponent::CreateDescriptor(),
|
||||
CapsuleShapeComponent::CreateDescriptor(),
|
||||
@@ -215,6 +217,7 @@ namespace LmbrCentral
|
||||
SphereShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
DiskShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
BoxShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
AxisAlignedBoxShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
QuadShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
CapsuleShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
CylinderShapeDebugDisplayComponent::CreateDescriptor(),
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Scripting/EditorSpawnerComponent.h"
|
||||
#include "Scripting/EditorTagComponent.h"
|
||||
|
||||
#include "Shape/EditorAxisAlignedBoxShapeComponent.h"
|
||||
#include "Shape/EditorBoxShapeComponent.h"
|
||||
#include "Shape/EditorQuadShapeComponent.h"
|
||||
#include "Shape/EditorSphereShapeComponent.h"
|
||||
@@ -67,6 +68,7 @@ namespace LmbrCentral
|
||||
EditorDiskShapeComponent::CreateDescriptor(),
|
||||
EditorTubeShapeComponent::CreateDescriptor(),
|
||||
EditorBoxShapeComponent::CreateDescriptor(),
|
||||
EditorAxisAlignedBoxShapeComponent::CreateDescriptor(),
|
||||
EditorQuadShapeComponent::CreateDescriptor(),
|
||||
EditorLookAtComponent::CreateDescriptor(),
|
||||
EditorCylinderShapeComponent::CreateDescriptor(),
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AxisAlignedBoxShape.h"
|
||||
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Math/IntersectSegment.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/Math/Matrix3x3.h>
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/Math/Sfmt.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Shape/ShapeDisplay.h>
|
||||
#include <random>
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
AxisAlignedBoxShape::AxisAlignedBoxShape()
|
||||
: BoxShape()
|
||||
{
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShape::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AxisAlignedBoxShape, BoxShape>()
|
||||
->Version(1)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<AxisAlignedBoxShape>("Axis Aligned Box Shape", "Axis Aligned Box shape configuration parameters")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShape::Activate(AZ::EntityId entityId)
|
||||
{
|
||||
BoxShape::Activate(entityId);
|
||||
m_currentTransform.SetRotation(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShape::OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world)
|
||||
{
|
||||
AZ::Transform worldNoRotation(world.GetTranslation(), AZ::Quaternion::CreateIdentity(), world.GetUniformScale());
|
||||
BoxShape::OnTransformChanged(local, worldNoRotation);
|
||||
}
|
||||
} // namespace LmbrCentral
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <AzCore/Math/Obb.h>
|
||||
#include <AzCore/Component/NonUniformScaleBus.h>
|
||||
#include <LmbrCentral/Shape/ShapeComponentBus.h>
|
||||
#include <LmbrCentral/Shape/BoxShapeComponentBus.h>
|
||||
#include "BoxShape.h"
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class DebugDisplayRequests;
|
||||
}
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
struct ShapeDrawParams;
|
||||
|
||||
class AxisAlignedBoxShape
|
||||
: public BoxShape
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AxisAlignedBoxShape, AZ::SystemAllocator, 0)
|
||||
AZ_RTTI(AxisAlignedBoxShape, "{CFDC96C5-287A-4033-8D7D-BA9331C13F25}", BoxShape)
|
||||
|
||||
AxisAlignedBoxShape();
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
void Activate(AZ::EntityId entityId) override;
|
||||
|
||||
// AZ::TransformNotificationBus::Handler
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
};
|
||||
} // namespace LmbrCentral
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "AxisAlignedBoxShapeComponent.h"
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Shape/ShapeComponentConverters.h>
|
||||
#include <Shape/ShapeDisplay.h>
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
void AxisAlignedBoxShapeComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC_CE("ShapeService"));
|
||||
provided.push_back(AZ_CRC_CE("BoxShapeService"));
|
||||
provided.push_back(AZ_CRC_CE("AxisAlignedBoxShapeService"));
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("ShapeService"));
|
||||
incompatible.push_back(AZ_CRC_CE("AxisAlignedBoxShapeService"));
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC_CE("TransformService"));
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
dependent.push_back(AZ_CRC_CE("NonUniformScaleService"));
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeDebugDisplayComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AxisAlignedBoxShapeDebugDisplayComponent, EntityDebugDisplayComponent>()
|
||||
->Version(1)->Field(
|
||||
"Configuration", &AxisAlignedBoxShapeDebugDisplayComponent::m_boxShapeConfig)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeDebugDisplayComponent::Activate()
|
||||
{
|
||||
EntityDebugDisplayComponent::Activate();
|
||||
ShapeComponentNotificationsBus::Handler::BusConnect(GetEntityId());
|
||||
m_nonUniformScale = AZ::Vector3::CreateOne();
|
||||
AZ::NonUniformScaleRequestBus::EventResult(m_nonUniformScale, GetEntityId(), &AZ::NonUniformScaleRequests::GetScale);
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeDebugDisplayComponent::Deactivate()
|
||||
{
|
||||
ShapeComponentNotificationsBus::Handler::BusDisconnect();
|
||||
EntityDebugDisplayComponent::Deactivate();
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeDebugDisplayComponent::Draw(AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
AZ::Matrix3x4 saveMatrix;
|
||||
ShapeDrawParams drawParams = g_defaultShapeDrawParams;
|
||||
drawParams.m_shapeColor = m_boxShapeConfig.GetDrawColor();
|
||||
drawParams.m_filled = m_boxShapeConfig.IsFilled();
|
||||
AZ::Transform transform = GetCurrentTransform();
|
||||
transform.SetRotation(AZ::Quaternion::CreateIdentity());
|
||||
saveMatrix = debugDisplay.PopPremultipliedMatrix();
|
||||
debugDisplay.PushMatrix(transform);
|
||||
DrawBoxShape(drawParams, m_boxShapeConfig, debugDisplay, m_nonUniformScale);
|
||||
debugDisplay.PopMatrix();
|
||||
debugDisplay.PushPremultipliedMatrix(saveMatrix);
|
||||
}
|
||||
|
||||
bool AxisAlignedBoxShapeDebugDisplayComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
|
||||
{
|
||||
if (const auto config = azrtti_cast<const BoxShapeConfig*>(baseConfig))
|
||||
{
|
||||
m_boxShapeConfig = *config;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AxisAlignedBoxShapeDebugDisplayComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
|
||||
{
|
||||
if (auto outConfig = azrtti_cast<BoxShapeConfig*>(outBaseConfig))
|
||||
{
|
||||
*outConfig = m_boxShapeConfig;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeDebugDisplayComponent::OnShapeChanged(ShapeChangeReasons changeReason)
|
||||
{
|
||||
if (changeReason == ShapeChangeReasons::ShapeChanged)
|
||||
{
|
||||
BoxShapeComponentRequestsBus::EventResult(m_boxShapeConfig, GetEntityId(), &BoxShapeComponentRequests::GetBoxConfiguration);
|
||||
AZ::NonUniformScaleRequestBus::EventResult(m_nonUniformScale, GetEntityId(), &AZ::NonUniformScaleRequests::GetScale);
|
||||
}
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AxisAlignedBoxShape::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AxisAlignedBoxShapeComponent, Component>()
|
||||
->Version(1)
|
||||
->Field("AxisAlignedBoxShape", &AxisAlignedBoxShapeComponent::m_aaboxShape)
|
||||
;
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Constant("AxisAlignedBoxShapeComponentTypeId", BehaviorConstant(AxisAlignedBoxShapeComponentTypeId));
|
||||
}
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeComponent::Activate()
|
||||
{
|
||||
m_aaboxShape.Activate(GetEntityId());
|
||||
}
|
||||
|
||||
void AxisAlignedBoxShapeComponent::Deactivate()
|
||||
{
|
||||
m_aaboxShape.Deactivate();
|
||||
}
|
||||
|
||||
bool AxisAlignedBoxShapeComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
|
||||
{
|
||||
if (const auto config = azrtti_cast<const BoxShapeConfig*>(baseConfig))
|
||||
{
|
||||
m_aaboxShape.SetBoxConfiguration(*config);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AxisAlignedBoxShapeComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
|
||||
{
|
||||
if (auto config = azrtti_cast<BoxShapeConfig*>(outBaseConfig))
|
||||
{
|
||||
*config = m_aaboxShape.GetBoxConfiguration();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace LmbrCentral
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
|
||||
#include "Rendering/EntityDebugDisplayComponent.h"
|
||||
#include "AxisAlignedBoxShape.h"
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
/// Type ID for the AxisAlignedBoxShapeComponent
|
||||
static const AZ::Uuid AxisAlignedBoxShapeComponentTypeId = "{641D817E-1BC6-406A-BBB2-218541808E45}";
|
||||
|
||||
/// Type ID for the EditorAxisAlignedBoxShapeComponent
|
||||
static const AZ::Uuid EditorAxisAlignedBoxShapeComponentTypeId = "{8C027DF6-E157-4159-9BF8-F1B925466F1F}";
|
||||
|
||||
/// Provide a Component interface for AxisAlignedBoxShape functionality.
|
||||
class AxisAlignedBoxShapeComponent
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AxisAlignedBoxShapeComponent, AxisAlignedBoxShapeComponentTypeId)
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
// AZ::Component
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
|
||||
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
|
||||
|
||||
private:
|
||||
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);
|
||||
|
||||
AxisAlignedBoxShape m_aaboxShape; ///< Stores underlying box type for this component.
|
||||
};
|
||||
|
||||
/// Concrete EntityDebugDisplay implementation for BoxShape.
|
||||
class AxisAlignedBoxShapeDebugDisplayComponent
|
||||
: public EntityDebugDisplayComponent
|
||||
, public ShapeComponentNotificationsBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AxisAlignedBoxShapeDebugDisplayComponent, "{BA93F933-1DC9-4E0E-B930-A7E3968D5DD1}", EntityDebugDisplayComponent)
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AxisAlignedBoxShapeDebugDisplayComponent() = default;
|
||||
|
||||
// AZ::Component
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
|
||||
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
|
||||
|
||||
// EntityDebugDisplayComponent
|
||||
void Draw(AzFramework::DebugDisplayRequests& debugDisplay) override;
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(AxisAlignedBoxShapeDebugDisplayComponent)
|
||||
|
||||
// ShapeComponentNotificationsBus
|
||||
void OnShapeChanged(ShapeChangeReasons changeReason) override;
|
||||
|
||||
BoxShapeConfig m_boxShapeConfig; ///< Stores configuration data for box shape.
|
||||
AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne(); ///< Caches non-uniform scale for this entity.
|
||||
};
|
||||
} // namespace LmbrCentral
|
||||
@@ -37,7 +37,7 @@ namespace LmbrCentral
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
void Activate(AZ::EntityId entityId);
|
||||
virtual void Activate(AZ::EntityId entityId);
|
||||
void Deactivate();
|
||||
void InvalidateCache(InvalidateShapeCacheReason reason);
|
||||
|
||||
@@ -67,12 +67,9 @@ namespace LmbrCentral
|
||||
|
||||
void SetDrawColor(const AZ::Color& color) { m_boxShapeConfig.SetDrawColor(color); }
|
||||
|
||||
protected:
|
||||
|
||||
friend class EditorBoxShapeComponent;
|
||||
BoxShapeConfig& ModifyConfiguration() { return m_boxShapeConfig; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
/// Runtime data - cache potentially expensive operations.
|
||||
class BoxIntersectionDataCache
|
||||
: public IntersectionTestDataCache<BoxShapeConfig>
|
||||
@@ -82,6 +79,7 @@ namespace LmbrCentral
|
||||
const AZ::Vector3& currentNonUniformScale = AZ::Vector3::CreateOne()) override;
|
||||
|
||||
friend BoxShape;
|
||||
friend class AxisAlignedBoxShape;
|
||||
|
||||
AZ::Aabb m_aabb; ///< Aabb representing this Box (including the effects of scale).
|
||||
AZ::Obb m_obb; ///< Obb representing this Box (including the effects of scale).
|
||||
@@ -90,12 +88,12 @@ namespace LmbrCentral
|
||||
bool m_axisAligned = true; ///< Indicates whether the box is axis or object aligned.
|
||||
};
|
||||
|
||||
BoxShapeConfig m_boxShapeConfig; ///< Underlying box configuration.
|
||||
BoxIntersectionDataCache m_intersectionDataCache; ///< Caches transient intersection data.
|
||||
AZ::Transform m_currentTransform; ///< Caches the current transform for the entity on which this component lives.
|
||||
AZ::EntityId m_entityId; ///< Id of the entity the box shape is attached to.
|
||||
AZ::NonUniformScaleChangedEvent::Handler m_nonUniformScaleChangedHandler; ///< Responds to changes in non-uniform scale.
|
||||
AZ::Vector3 m_currentNonUniformScale = AZ::Vector3::CreateOne(); ///< Caches the current non-uniform scale.
|
||||
BoxShapeConfig m_boxShapeConfig; ///< Underlying box configuration.
|
||||
};
|
||||
|
||||
void DrawBoxShape(
|
||||
|
||||
@@ -101,23 +101,15 @@ namespace LmbrCentral
|
||||
}
|
||||
}
|
||||
|
||||
namespace ClassConverters
|
||||
{
|
||||
static bool DeprecateBoxColliderConfiguration(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
|
||||
static bool DeprecateBoxColliderComponent(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
|
||||
}
|
||||
|
||||
void BoxShapeConfig::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
// Don't reflect again if we're already reflected to the passed in context
|
||||
if (context->IsTypeReflected(BoxShapeConfigTypeId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
// Deprecate: BoxColliderConfiguration -> BoxShapeConfig
|
||||
serializeContext->ClassDeprecate(
|
||||
"BoxColliderConfiguration",
|
||||
"{282E47CB-9F6D-47AE-A210-4CE879527EFD}",
|
||||
&ClassConverters::DeprecateBoxColliderConfiguration)
|
||||
;
|
||||
|
||||
serializeContext->Class<BoxShapeConfig, ShapeComponentConfig>()
|
||||
->Version(2)
|
||||
->Field("Dimensions", &BoxShapeConfig::m_dimensions)
|
||||
@@ -151,13 +143,6 @@ namespace LmbrCentral
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
// Deprecate: BoxColliderComponent -> BoxShapeComponent
|
||||
serializeContext->ClassDeprecate(
|
||||
"BoxColliderComponent",
|
||||
"{C215EB2A-1803-4EDC-B032-F7C92C142337}",
|
||||
&ClassConverters::DeprecateBoxColliderComponent)
|
||||
;
|
||||
|
||||
serializeContext->Class<BoxShapeComponent, Component>()
|
||||
->Version(2, &ClassConverters::UpgradeBoxShapeComponent)
|
||||
->Field("BoxShape", &BoxShapeComponent::m_boxShape)
|
||||
@@ -205,85 +190,4 @@ namespace LmbrCentral
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace ClassConverters
|
||||
{
|
||||
static bool DeprecateBoxColliderConfiguration(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
/*
|
||||
Old:
|
||||
<Class name="BoxColliderConfiguration" field="Configuration" version="1" type="{282E47CB-9F6D-47AE-A210-4CE879527EFD}">
|
||||
<Class name="Vector3" field="Size" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
</Class>
|
||||
|
||||
New:
|
||||
<Class name="BoxShapeConfig" field="Configuration" version="1" type="{F034FBA2-AC2F-4E66-8152-14DFB90D6283}">
|
||||
<Class name="Vector3" field="Dimensions" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
</Class>
|
||||
*/
|
||||
|
||||
// Cache the Dimensions
|
||||
AZ::Vector3 oldDimensions;
|
||||
const int oldIndex = classElement.FindElement(AZ_CRC("Size", 0xf7c0246a));
|
||||
if (oldIndex != -1)
|
||||
{
|
||||
classElement.GetSubElement(oldIndex).GetData<AZ::Vector3>(oldDimensions);
|
||||
}
|
||||
|
||||
// Convert to BoxShapeConfig
|
||||
const bool result = classElement.Convert(context, "{F034FBA2-AC2F-4E66-8152-14DFB90D6283}");
|
||||
if (result)
|
||||
{
|
||||
const int newIndex = classElement.AddElement<AZ::Vector3>(context, "Dimensions");
|
||||
if (newIndex != -1)
|
||||
{
|
||||
classElement.GetSubElement(newIndex).SetData<AZ::Vector3>(context, oldDimensions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DeprecateBoxColliderComponent(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
/*
|
||||
Old:
|
||||
<Class name="BoxColliderComponent" version="1" type="{C215EB2A-1803-4EDC-B032-F7C92C142337}">
|
||||
<Class name="BoxColliderConfiguration" field="Configuration" version="1" type="{282E47CB-9F6D-47AE-A210-4CE879527EFD}">
|
||||
<Class name="Vector3" field="Size" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
|
||||
New:
|
||||
<Class name="BoxShapeComponent" version="1" type="{5EDF4B9E-0D3D-40B8-8C91-5142BCFC30A6}">
|
||||
<Class name="BoxShapeConfig" field="Configuration" version="1" type="{F034FBA2-AC2F-4E66-8152-14DFB90D6283}">
|
||||
<Class name="Vector3" field="Dimensions" value="1.0000000 2.0000000 3.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
*/
|
||||
|
||||
// Cache the Configuration
|
||||
BoxShapeConfig configuration;
|
||||
int configIndex = classElement.FindElement(AZ_CRC("Configuration", 0xa5e2a5d7));
|
||||
if (configIndex != -1)
|
||||
{
|
||||
classElement.GetSubElement(configIndex).GetData<BoxShapeConfig>(configuration);
|
||||
}
|
||||
|
||||
// Convert to BoxShapeComponent
|
||||
const bool result = classElement.Convert(context, BoxShapeComponentTypeId);
|
||||
if (result)
|
||||
{
|
||||
configIndex = classElement.AddElement<BoxShapeConfig>(context, "Configuration");
|
||||
if (configIndex != -1)
|
||||
{
|
||||
classElement.GetSubElement(configIndex).SetData<BoxShapeConfig>(context, configuration);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ClassConverters
|
||||
|
||||
} // namespace LmbrCentral
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzToolsFramework/ComponentModes/BoxComponentMode.h>
|
||||
#include <AzToolsFramework/Maths/TransformUtils.h>
|
||||
|
||||
#include "AxisAlignedBoxShapeComponent.h"
|
||||
#include "EditorAxisAlignedBoxShapeComponent.h"
|
||||
#include "EditorShapeComponentConverters.h"
|
||||
#include "ShapeDisplay.h"
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
void EditorAxisAlignedBoxShapeComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorAxisAlignedBoxShapeComponent, EditorBaseShapeComponent>()
|
||||
->Version(1)
|
||||
->Field("AxisAlignedBoxShape", &EditorAxisAlignedBoxShapeComponent::m_aaboxShape)
|
||||
->Field("ComponentMode", &EditorAxisAlignedBoxShapeComponent::m_componentModeDelegate)
|
||||
;
|
||||
|
||||
if (auto editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorAxisAlignedBoxShapeComponent>(
|
||||
"Axis Aligned Box Shape", "The Axis Aligned Box Shape component creates a box around the associated entity")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Shape")
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Box_Shape.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Box_Shape.svg")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/shape/axis-aligned-box-shape/")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorAxisAlignedBoxShapeComponent::m_aaboxShape, "Axis Aligned Box Shape", "Axis Aligned Box Shape Configuration")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAxisAlignedBoxShapeComponent::ConfigurationChanged)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorAxisAlignedBoxShapeComponent::m_componentModeDelegate, "Component Mode", "Axis Aligned Box Shape Component Mode")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::Init()
|
||||
{
|
||||
EditorBaseShapeComponent::Init();
|
||||
|
||||
SetShapeComponentConfig(&m_aaboxShape.ModifyConfiguration());
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::Activate()
|
||||
{
|
||||
EditorBaseShapeComponent::Activate();
|
||||
m_aaboxShape.Activate(GetEntityId());
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId());
|
||||
AzToolsFramework::BoxManipulatorRequestBus::Handler::BusConnect(
|
||||
AZ::EntityComponentIdPair(GetEntityId(), GetId()));
|
||||
|
||||
// ComponentMode
|
||||
m_componentModeDelegate.ConnectWithSingleComponentMode<
|
||||
EditorAxisAlignedBoxShapeComponent, AzToolsFramework::BoxComponentMode>(
|
||||
AZ::EntityComponentIdPair(GetEntityId(), GetId()), this);
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::Deactivate()
|
||||
{
|
||||
m_componentModeDelegate.Disconnect();
|
||||
|
||||
AzToolsFramework::BoxManipulatorRequestBus::Handler::BusDisconnect();
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
|
||||
m_aaboxShape.Deactivate();
|
||||
EditorBaseShapeComponent::Deactivate();
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
EditorBaseShapeComponent::GetProvidedServices(provided);
|
||||
provided.push_back(AZ_CRC_CE("BoxShapeService"));
|
||||
provided.push_back(AZ_CRC_CE("AxisAlignedBoxShapeService"));
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
dependent.push_back(AZ_CRC_CE("NonUniformScaleService"));
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::DisplayEntityViewport(
|
||||
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
DisplayShape(
|
||||
debugDisplay, [this]() { return CanDraw(); },
|
||||
[this](AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
DrawBoxShape(
|
||||
{ m_aaboxShape.GetBoxConfiguration().GetDrawColor(), m_shapeWireColor, m_aaboxShape.GetBoxConfiguration().IsFilled() },
|
||||
m_aaboxShape.GetBoxConfiguration(), debugDisplay, m_aaboxShape.GetCurrentNonUniformScale());
|
||||
},
|
||||
m_aaboxShape.GetCurrentTransform());
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::ConfigurationChanged()
|
||||
{
|
||||
m_aaboxShape.InvalidateCache(InvalidateShapeCacheReason::ShapeChange);
|
||||
|
||||
ShapeComponentNotificationsBus::Event(GetEntityId(),
|
||||
&ShapeComponentNotificationsBus::Events::OnShapeChanged,
|
||||
ShapeComponentNotifications::ShapeChangeReasons::ShapeChanged);
|
||||
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::Refresh,
|
||||
AZ::EntityComponentIdPair(GetEntityId(), GetId()));
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::BuildGameEntity(AZ::Entity* gameEntity)
|
||||
{
|
||||
if (AxisAlignedBoxShapeComponent* boxShapeComponent = gameEntity->CreateComponent<AxisAlignedBoxShapeComponent>())
|
||||
{
|
||||
boxShapeComponent->SetConfiguration(m_aaboxShape.GetBoxConfiguration());
|
||||
}
|
||||
|
||||
if (m_visibleInGameView)
|
||||
{
|
||||
if (auto component = gameEntity->CreateComponent<AxisAlignedBoxShapeDebugDisplayComponent>())
|
||||
{
|
||||
component->SetConfiguration(m_aaboxShape.GetBoxConfiguration());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::OnTransformChanged(
|
||||
const AZ::Transform& /*local*/, const AZ::Transform& /*world*/)
|
||||
{
|
||||
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
|
||||
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::Refresh,
|
||||
AZ::EntityComponentIdPair(GetEntityId(), GetId()));
|
||||
}
|
||||
|
||||
AZ::Vector3 EditorAxisAlignedBoxShapeComponent::GetDimensions()
|
||||
{
|
||||
return m_aaboxShape.GetBoxDimensions();
|
||||
}
|
||||
|
||||
void EditorAxisAlignedBoxShapeComponent::SetDimensions(const AZ::Vector3& dimensions)
|
||||
{
|
||||
return m_aaboxShape.SetBoxDimensions(dimensions);
|
||||
}
|
||||
|
||||
AZ::Transform EditorAxisAlignedBoxShapeComponent::GetCurrentTransform()
|
||||
{
|
||||
return AzToolsFramework::TransformNormalizedScale(m_aaboxShape.GetCurrentTransform());
|
||||
}
|
||||
|
||||
AZ::Vector3 EditorAxisAlignedBoxShapeComponent::GetBoxScale()
|
||||
{
|
||||
return AZ::Vector3(m_aaboxShape.GetCurrentTransform().GetUniformScale() * m_aaboxShape.GetCurrentNonUniformScale());
|
||||
}
|
||||
} // namespace LmbrCentral
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AxisAlignedBoxShape.h"
|
||||
#include "AxisAlignedBoxShapeComponent.h"
|
||||
#include "EditorBaseShapeComponent.h"
|
||||
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzToolsFramework/ComponentMode/ComponentModeDelegate.h>
|
||||
#include <AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h>
|
||||
|
||||
|
||||
namespace LmbrCentral
|
||||
{
|
||||
/// Editor representation of Box Shape Component.
|
||||
class EditorAxisAlignedBoxShapeComponent
|
||||
: public EditorBaseShapeComponent
|
||||
, private AzFramework::EntityDebugDisplayEventBus::Handler
|
||||
, private AzToolsFramework::BoxManipulatorRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_EDITOR_COMPONENT(EditorAxisAlignedBoxShapeComponent, EditorAxisAlignedBoxShapeComponentTypeId, EditorBaseShapeComponent);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
EditorAxisAlignedBoxShapeComponent() = default;
|
||||
|
||||
// AZ::Component
|
||||
void Init() override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
protected:
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
// EditorComponentBase
|
||||
void BuildGameEntity(AZ::Entity* gameEntity) override;
|
||||
|
||||
// AZ::TransformNotificationBus::Handler
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(EditorAxisAlignedBoxShapeComponent)
|
||||
|
||||
// AzFramework::EntityDebugDisplayEventBus
|
||||
void DisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay) override;
|
||||
|
||||
// AzToolsFramework::BoxManipulatorRequestBus
|
||||
AZ::Vector3 GetDimensions() override;
|
||||
void SetDimensions(const AZ::Vector3& dimensions) override;
|
||||
AZ::Transform GetCurrentTransform() override;
|
||||
AZ::Vector3 GetBoxScale() override;
|
||||
|
||||
void ConfigurationChanged();
|
||||
|
||||
AxisAlignedBoxShape m_aaboxShape; ///< Stores underlying box representation for this component.
|
||||
|
||||
using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate;
|
||||
ComponentModeDelegate m_componentModeDelegate; /**< Responsible for detecting ComponentMode activation
|
||||
* and creating a concrete ComponentMode.*/
|
||||
};
|
||||
} // namespace LmbrCentral
|
||||
@@ -49,7 +49,7 @@ namespace LmbrCentral
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/shape/box-shape/")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorBoxShapeComponent::m_boxShape, "Box Shape", "Box Shape Configuration")
|
||||
// ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) // disabled - prevents ChangeNotify attribute firing correctly
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorBoxShapeComponent::ConfigurationChanged)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorBoxShapeComponent::m_componentModeDelegate, "Component Mode", "Box Shape Component Mode")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Math/Matrix3x3.h>
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzFramework/Components/NonUniformScaleComponent.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/UnitTest/TestDebugDisplayRequests.h>
|
||||
#include <Shape/AxisAlignedBoxShapeComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class AxisAlignedBoxShapeTest : public AllocatorsFixture
|
||||
{
|
||||
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor> m_axisAlignedBoxShapeComponentDescriptor;
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor> m_axisAlignedBoxShapeDebugDisplayComponentDescriptor;
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor> m_nonUniformScaleComponentDescriptor;
|
||||
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
|
||||
|
||||
m_transformComponentDescriptor =
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor>(AzFramework::TransformComponent::CreateDescriptor());
|
||||
m_transformComponentDescriptor->Reflect(&(*m_serializeContext));
|
||||
m_axisAlignedBoxShapeComponentDescriptor =
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor>(LmbrCentral::AxisAlignedBoxShapeComponent::CreateDescriptor());
|
||||
m_axisAlignedBoxShapeComponentDescriptor->Reflect(&(*m_serializeContext));
|
||||
m_axisAlignedBoxShapeDebugDisplayComponentDescriptor =
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor>(LmbrCentral::AxisAlignedBoxShapeDebugDisplayComponent::CreateDescriptor());
|
||||
m_axisAlignedBoxShapeDebugDisplayComponentDescriptor->Reflect(&(*m_serializeContext));
|
||||
m_nonUniformScaleComponentDescriptor =
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor>(AzFramework::NonUniformScaleComponent::CreateDescriptor());
|
||||
m_nonUniformScaleComponentDescriptor->Reflect(&(*m_serializeContext));
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_transformComponentDescriptor.reset();
|
||||
m_axisAlignedBoxShapeComponentDescriptor.reset();
|
||||
m_axisAlignedBoxShapeDebugDisplayComponentDescriptor.reset();
|
||||
m_nonUniformScaleComponentDescriptor.reset();
|
||||
m_serializeContext.reset();
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
void CreateAxisAlignedBox(const AZ::Transform& transform, const AZ::Vector3& dimensions, AZ::Entity& entity)
|
||||
{
|
||||
entity.CreateComponent<LmbrCentral::AxisAlignedBoxShapeComponent>();
|
||||
entity.CreateComponent<LmbrCentral::AxisAlignedBoxShapeDebugDisplayComponent>();
|
||||
entity.CreateComponent<AzFramework::TransformComponent>();
|
||||
|
||||
entity.Init();
|
||||
entity.Activate();
|
||||
|
||||
AZ::TransformBus::Event(entity.GetId(), &AZ::TransformBus::Events::SetWorldTM, transform);
|
||||
LmbrCentral::BoxShapeComponentRequestsBus::Event(
|
||||
entity.GetId(), &LmbrCentral::BoxShapeComponentRequestsBus::Events::SetBoxDimensions, dimensions);
|
||||
}
|
||||
|
||||
void CreateAxisAlignedBoxWithNonUniformScale(
|
||||
const AZ::Transform& transform, const AZ::Vector3& nonUniformScale, const AZ::Vector3& dimensions, AZ::Entity& entity)
|
||||
{
|
||||
entity.CreateComponent<LmbrCentral::AxisAlignedBoxShapeComponent>();
|
||||
entity.CreateComponent<LmbrCentral::AxisAlignedBoxShapeDebugDisplayComponent>();
|
||||
entity.CreateComponent<AzFramework::TransformComponent>();
|
||||
entity.CreateComponent<AzFramework::NonUniformScaleComponent>();
|
||||
|
||||
entity.Init();
|
||||
entity.Activate();
|
||||
|
||||
AZ::TransformBus::Event(entity.GetId(), &AZ::TransformBus::Events::SetWorldTM, transform);
|
||||
LmbrCentral::BoxShapeComponentRequestsBus::Event(
|
||||
entity.GetId(), &LmbrCentral::BoxShapeComponentRequestsBus::Events::SetBoxDimensions, dimensions);
|
||||
AZ::NonUniformScaleRequestBus::Event(entity.GetId(), &AZ::NonUniformScaleRequests::SetScale, nonUniformScale);
|
||||
}
|
||||
|
||||
void CreateDefaultAxisAlignedBox(const AZ::Transform& transform, AZ::Entity& entity)
|
||||
{
|
||||
CreateAxisAlignedBox(transform, AZ::Vector3(10.0f, 10.0f, 10.0f), entity);
|
||||
}
|
||||
|
||||
TEST_F(AxisAlignedBoxShapeTest, EntityTransformIsCorrect)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
CreateAxisAlignedBox(
|
||||
AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, 0.0f, 0.0f)) * AZ::Transform::CreateRotationZ(AZ::Constants::QuarterPi),
|
||||
AZ::Vector3(1.0f), entity);
|
||||
|
||||
AZ::Transform transform;
|
||||
AZ::TransformBus::EventResult(transform, entity.GetId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
EXPECT_EQ(transform, AZ::Transform::CreateRotationZ(AZ::Constants::QuarterPi));
|
||||
}
|
||||
|
||||
TEST_F(AxisAlignedBoxShapeTest, BoxWithZRotationHasCorrectRayIntersection)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
CreateAxisAlignedBox(
|
||||
AZ::Transform::CreateRotationZ(AZ::Constants::QuarterPi),
|
||||
AZ::Vector3(1.0f), entity);
|
||||
|
||||
bool rayHit = false;
|
||||
float distance;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(5.0f, 0.0f, 0.0f),
|
||||
AZ::Vector3(-1.0f, 0.0f, 0.0f), distance);
|
||||
|
||||
// This test creates a unit box centered on (0, 0, 0) and rotated by 45 degrees. The distance to the box should
|
||||
// be 4.5 if it isn't rotated but less if there is any rotation.
|
||||
EXPECT_TRUE(rayHit);
|
||||
EXPECT_NEAR(distance, 4.5f, 1e-2f);
|
||||
}
|
||||
|
||||
TEST_F(AxisAlignedBoxShapeTest, BoxWithTranslationAndRotationsHasCorrectRayIntersection)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
CreateAxisAlignedBox(
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisX(), AZ::Constants::HalfPi) *
|
||||
AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), AZ::Constants::QuarterPi),
|
||||
AZ::Vector3(-10.0f, -10.0f, -10.0f)),
|
||||
AZ::Vector3(4.0f, 4.0f, 2.0f), entity);
|
||||
|
||||
bool rayHit = false;
|
||||
float distance;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(-10.0f, -10.0f, 0.0f),
|
||||
AZ::Vector3(0.0f, 0.0f, -1.0f), distance);
|
||||
|
||||
// This test creates a box of dimensions (4.0, 4.0, 2.0) centered on (-10, -10, 0) and rotated in X and Z. The distance to the box should
|
||||
// be 9.0 if it isn't rotated but less if there is any rotation.
|
||||
EXPECT_TRUE(rayHit);
|
||||
EXPECT_NEAR(distance, 9.00f, 1e-2f);
|
||||
}
|
||||
|
||||
TEST_F(AxisAlignedBoxShapeTest, BoxWithTranslationHasCorrectRayIntersection)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
CreateAxisAlignedBox(
|
||||
AZ::Transform::CreateTranslation(AZ::Vector3(100.0f, 100.0f, 0.0f)),
|
||||
AZ::Vector3(5.0f, 5.0f, 5.0f), entity);
|
||||
|
||||
bool rayHit = false;
|
||||
float distance;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(100.0f, 100.0f, -100.0f),
|
||||
AZ::Vector3(0.0f, 0.0f, 1.0f), distance);
|
||||
|
||||
// This test creates a box of dimensions (5.0, 5.0, 5.0) centered on (100, 100, 0) and not rotated. The distance to the box
|
||||
// should be 97.5.
|
||||
EXPECT_TRUE(rayHit);
|
||||
EXPECT_NEAR(distance, 97.5f, 1e-2f);
|
||||
}
|
||||
|
||||
TEST_F(AxisAlignedBoxShapeTest, BoxWithTranslationRotationAndScaleHasCorrectRayIntersection)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
CreateAxisAlignedBox(
|
||||
AZ::Transform(
|
||||
AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisY(), AZ::Constants::QuarterPi), 3.0f),
|
||||
AZ::Vector3(2.0f, 4.0f, 1.0f), entity);
|
||||
|
||||
bool rayHit = false;
|
||||
float distance;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(1.0f, -10.0f, 4.0f),
|
||||
AZ::Vector3(0.0f, 1.0f, 0.0f), distance);
|
||||
|
||||
// This test creates a box of dimensions (2.0, 4.0, 1.0) centered on (0, 0, 5) and rotated about the Y axis by 45 degrees.
|
||||
// The distance to the box should be 4.0 if not rotated but scaled and less if it is.
|
||||
EXPECT_TRUE(rayHit);
|
||||
EXPECT_NEAR(distance, 4.0f, 1e-2f);
|
||||
}
|
||||
|
||||
TEST_F(AxisAlignedBoxShapeTest, RayIntersectWithBoxRotatedNonUniformScale)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
CreateAxisAlignedBoxWithNonUniformScale(
|
||||
AZ::Transform(
|
||||
AZ::Vector3(2.0f, -5.0f, 3.0f), AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisY(), AZ::Constants::QuarterPi),
|
||||
0.5f),
|
||||
AZ::Vector3(2.2f, 1.8f, 0.4f), AZ::Vector3(0.2f, 2.6f, 1.2f), entity);
|
||||
|
||||
// This test creates a box of dimensions (2.2, 1.8, 0.4) centered on (2.0, -5, 3) and rotated about the Y axis by 45 degrees.
|
||||
// The box is tested for axis-alignment by firing various rays and ensuring they either hit or miss the box. Any failure here
|
||||
// would show the box has been rotated.
|
||||
|
||||
// Ray should just miss the box
|
||||
bool rayHit = false;
|
||||
float distance = AZ::Constants::FloatMax;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(1.8f, -6.2f, 3.0f),
|
||||
AZ::Vector3(1.0f, 0.0f, 0.0f), distance);
|
||||
EXPECT_FALSE(rayHit);
|
||||
|
||||
// Ray should just hit the box
|
||||
rayHit = false;
|
||||
distance = AZ::Constants::FloatMax;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(1.8f, -6.1f, 3.0f),
|
||||
AZ::Vector3(1.0f, 0.0f, 0.0f), distance);
|
||||
EXPECT_TRUE(rayHit);
|
||||
EXPECT_NEAR(distance, 0.09f, 1e-3f);
|
||||
|
||||
// Ray should just miss the box
|
||||
rayHit = false;
|
||||
distance = AZ::Constants::FloatMax;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(2.2f, -6.2f, 3.0f),
|
||||
AZ::Vector3(0.0f, 1.0f, 0.0f), distance);
|
||||
EXPECT_FALSE(rayHit);
|
||||
|
||||
// Ray should just hit the box
|
||||
rayHit = false;
|
||||
distance = AZ::Constants::FloatMax;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit, entity.GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay, AZ::Vector3(2.1f, -6.2f, 3.0f),
|
||||
AZ::Vector3(0.0f, 1.0f, 0.0f), distance);
|
||||
EXPECT_TRUE(rayHit);
|
||||
EXPECT_NEAR(distance, 0.03f, 1e-3f);
|
||||
}
|
||||
} // namespace UnitTest
|
||||
@@ -34,10 +34,10 @@ namespace
|
||||
0.5f, 1.0f, 2.0f, 4.0f, 8.0f,
|
||||
};
|
||||
|
||||
const uint32_t RayCount = 5;
|
||||
const uint32_t RayCountDisk = 5;
|
||||
|
||||
// Various normalized offset directions from center of disk along disk's surface.
|
||||
const AZStd::array<AZ::Vector3, RayCount> OffsetsFromCenter =
|
||||
const AZStd::array<AZ::Vector3, RayCountDisk> OffsetsFromCenterDisk =
|
||||
{
|
||||
AZ::Vector3(0.18f, -0.50f, 0.0f).GetNormalized(),
|
||||
AZ::Vector3(-0.08f, 0.59f, 0.0f).GetNormalized(),
|
||||
@@ -47,7 +47,7 @@ namespace
|
||||
};
|
||||
|
||||
// Various directions away from a point on the disk's surface
|
||||
const AZStd::array<AZ::Vector3, RayCount> OffsetsFromSurface =
|
||||
const AZStd::array<AZ::Vector3, RayCountDisk> OffsetsFromSurfaceDisk =
|
||||
{
|
||||
AZ::Vector3(0.69f, 0.38f, 0.09f).GetNormalized(),
|
||||
AZ::Vector3(-0.98f, -0.68f, -0.28f).GetNormalized(),
|
||||
@@ -57,7 +57,7 @@ namespace
|
||||
};
|
||||
|
||||
// Various distance away from the surface for the rays
|
||||
const AZStd::array<float, RayCount> RayDistances =
|
||||
const AZStd::array<float, RayCountDisk> RayDistancesDisk =
|
||||
{
|
||||
0.5f, 1.0f, 2.0f, 4.0f, 8.0f
|
||||
};
|
||||
@@ -185,7 +185,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
// Offsets from center scaled down from the disk edge so that all the rays should hit
|
||||
const AZStd::array<float, RayCount> offsetFromCenterScale =
|
||||
const AZStd::array<float, RayCountDisk> offsetFromCenterScale =
|
||||
{
|
||||
0.8f,
|
||||
0.2f,
|
||||
@@ -197,20 +197,20 @@ namespace UnitTest
|
||||
// Construct rays and test against the different disks
|
||||
for (uint32_t diskIndex = 0; diskIndex < DiskCount; ++diskIndex)
|
||||
{
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCount; ++rayIndex)
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCountDisk; ++rayIndex)
|
||||
{
|
||||
AZ::Vector3 scaledOffsetFromCenter = OffsetsFromCenter[rayIndex] * DiskRadii[diskIndex] * offsetFromCenterScale[rayIndex];
|
||||
AZ::Vector3 scaledOffsetFromCenter = OffsetsFromCenterDisk[rayIndex] * DiskRadii[diskIndex] * offsetFromCenterScale[rayIndex];
|
||||
AZ::Vector3 positionOnDiskSurface = DiskTransforms[diskIndex].TransformPoint(scaledOffsetFromCenter);
|
||||
AZ::Vector3 rayOrigin = positionOnDiskSurface + OffsetsFromSurface[rayIndex] * RayDistances[rayIndex];
|
||||
AZ::Vector3 rayOrigin = positionOnDiskSurface + OffsetsFromSurfaceDisk[rayIndex] * RayDistancesDisk[rayIndex];
|
||||
|
||||
bool rayHit2 = false;
|
||||
float distance2;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit2, diskEntities[diskIndex].GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay,
|
||||
rayOrigin, -OffsetsFromSurface[rayIndex], distance2);
|
||||
rayOrigin, -OffsetsFromSurfaceDisk[rayIndex], distance2);
|
||||
|
||||
EXPECT_TRUE(rayHit2);
|
||||
EXPECT_NEAR(distance2, RayDistances[rayIndex], 1e-4f);
|
||||
EXPECT_NEAR(distance2, RayDistancesDisk[rayIndex], 1e-4f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
// Offsets from center scaled up from the disk edge so that all the rays should miss
|
||||
const AZStd::array<float, RayCount> offsetFromCenterScale =
|
||||
const AZStd::array<float, RayCountDisk> offsetFromCenterScale =
|
||||
{
|
||||
1.8f,
|
||||
1.2f,
|
||||
@@ -253,17 +253,17 @@ namespace UnitTest
|
||||
// Construct rays and test against the different disks
|
||||
for (uint32_t diskIndex = 0; diskIndex < DiskCount; ++diskIndex)
|
||||
{
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCount; ++rayIndex)
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCountDisk; ++rayIndex)
|
||||
{
|
||||
AZ::Vector3 scaledOffsetFromCenter = OffsetsFromCenter[rayIndex] * DiskRadii[diskIndex] * offsetFromCenterScale[rayIndex];
|
||||
AZ::Vector3 scaledOffsetFromCenter = OffsetsFromCenterDisk[rayIndex] * DiskRadii[diskIndex] * offsetFromCenterScale[rayIndex];
|
||||
AZ::Vector3 positionOnDiskSurface = DiskTransforms[diskIndex].TransformPoint(scaledOffsetFromCenter);
|
||||
AZ::Vector3 rayOrigin = positionOnDiskSurface + OffsetsFromSurface[rayIndex] * RayDistances[rayIndex];
|
||||
AZ::Vector3 rayOrigin = positionOnDiskSurface + OffsetsFromSurfaceDisk[rayIndex] * RayDistancesDisk[rayIndex];
|
||||
|
||||
bool rayHit2 = false;
|
||||
float distance2;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit2, diskEntities[diskIndex].GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay,
|
||||
rayOrigin, -OffsetsFromSurface[rayIndex], distance2);
|
||||
rayOrigin, -OffsetsFromSurfaceDisk[rayIndex], distance2);
|
||||
|
||||
EXPECT_FALSE(rayHit2);
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ namespace
|
||||
LmbrCentral::QuadShapeConfig(1.0f, 0.5f),
|
||||
};
|
||||
|
||||
const uint32_t RayCount = 5;
|
||||
const uint32_t RayCountQuad = 5;
|
||||
|
||||
// Various normalized offset directions from center of quad along quad's surface.
|
||||
const AZStd::array<AZ::Vector3, RayCount> OffsetsFromCenter =
|
||||
const AZStd::array<AZ::Vector3, RayCountQuad> OffsetsFromCenterQuad =
|
||||
{
|
||||
AZ::Vector3( 0.18f, -0.50f, 0.0f).GetNormalized(),
|
||||
AZ::Vector3(-0.08f, 0.59f, 0.0f).GetNormalized(),
|
||||
@@ -54,7 +54,7 @@ namespace
|
||||
};
|
||||
|
||||
// Various directions away from a point on the quad's surface
|
||||
const AZStd::array<AZ::Vector3, RayCount> OffsetsFromSurface =
|
||||
const AZStd::array<AZ::Vector3, RayCountQuad> OffsetsFromSurfaceQuad =
|
||||
{
|
||||
AZ::Vector3( 0.69f, 0.38f, 0.09f).GetNormalized(),
|
||||
AZ::Vector3(-0.98f, -0.68f, -0.28f).GetNormalized(),
|
||||
@@ -64,7 +64,7 @@ namespace
|
||||
};
|
||||
|
||||
// Various distance away from the surface for the rays
|
||||
const AZStd::array<float, RayCount> RayDistances =
|
||||
const AZStd::array<float, RayCountQuad> RayDistancesQuad =
|
||||
{
|
||||
0.5f, 1.0f, 2.0f, 4.0f, 8.0f
|
||||
};
|
||||
@@ -248,23 +248,23 @@ namespace UnitTest
|
||||
// Construct rays and test against the different quads
|
||||
for (uint32_t quadIndex = 0; quadIndex < QuadCount; ++quadIndex)
|
||||
{
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCount; ++rayIndex)
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCountQuad; ++rayIndex)
|
||||
{
|
||||
// OffsetsFromCenter are all less than 1, so scale by the dimensions of the quad.
|
||||
// OffsetsFromCenterQuad are all less than 1, so scale by the dimensions of the quad.
|
||||
AZ::Vector3 scaledWidthHeight = AZ::Vector3(QuadDims[quadIndex].m_width, QuadDims[quadIndex].m_height, 0.0f);
|
||||
// Scale the offset and multiply by 0.5 because distance from center is half the width/height
|
||||
AZ::Vector3 scaledOffsetFromCenter = OffsetsFromCenter[rayIndex] * scaledWidthHeight * 0.5f;
|
||||
AZ::Vector3 scaledOffsetFromCenter = OffsetsFromCenterQuad[rayIndex] * scaledWidthHeight * 0.5f;
|
||||
AZ::Vector3 positionOnQuadSurface = QuadTransforms[quadIndex].TransformPoint(scaledOffsetFromCenter);
|
||||
AZ::Vector3 rayOrigin = positionOnQuadSurface + OffsetsFromSurface[rayIndex] * RayDistances[rayIndex];
|
||||
AZ::Vector3 rayOrigin = positionOnQuadSurface + OffsetsFromSurfaceQuad[rayIndex] * RayDistancesQuad[rayIndex];
|
||||
|
||||
bool rayHit2 = false;
|
||||
float distance2;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit2, quadEntities[quadIndex].GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay,
|
||||
rayOrigin, -OffsetsFromSurface[rayIndex], distance2);
|
||||
rayOrigin, -OffsetsFromSurfaceQuad[rayIndex], distance2);
|
||||
|
||||
EXPECT_TRUE(rayHit2);
|
||||
EXPECT_NEAR(distance2, RayDistances[rayIndex], 1e-4f);
|
||||
EXPECT_NEAR(distance2, RayDistancesQuad[rayIndex], 1e-4f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,20 +297,20 @@ namespace UnitTest
|
||||
// Construct rays and test against the different quads
|
||||
for (uint32_t quadIndex = 0; quadIndex < QuadCount; ++quadIndex)
|
||||
{
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCount; ++rayIndex)
|
||||
for (uint32_t rayIndex = 0; rayIndex < RayCountQuad; ++rayIndex)
|
||||
{
|
||||
// OffsetsFromCenter are all less than 1, so scale by the dimensions of the quad.
|
||||
// OffsetsFromCenterQuad are all less than 1, so scale by the dimensions of the quad.
|
||||
AZ::Vector3 scaledWidthHeight = AZ::Vector3(QuadDims[quadIndex].m_width, QuadDims[quadIndex].m_height, 0.0f);
|
||||
// Scale the offset and add 1.0 to OffsetsFromCenter to ensure the point is outside the quad.
|
||||
AZ::Vector3 scaledOffsetFromCenter = (AZ::Vector3::CreateOne() + OffsetsFromCenter[rayIndex]) * scaledWidthHeight;
|
||||
// Scale the offset and add 1.0 to OffsetsFromCenterQuad to ensure the point is outside the quad.
|
||||
AZ::Vector3 scaledOffsetFromCenter = (AZ::Vector3::CreateOne() + OffsetsFromCenterQuad[rayIndex]) * scaledWidthHeight;
|
||||
AZ::Vector3 positionOnQuadSurface = QuadTransforms[quadIndex].TransformPoint(scaledOffsetFromCenter);
|
||||
AZ::Vector3 rayOrigin = positionOnQuadSurface + OffsetsFromSurface[rayIndex] * RayDistances[rayIndex];
|
||||
AZ::Vector3 rayOrigin = positionOnQuadSurface + OffsetsFromSurfaceQuad[rayIndex] * RayDistancesQuad[rayIndex];
|
||||
|
||||
bool rayHit2 = false;
|
||||
float distance2;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(
|
||||
rayHit2, quadEntities[quadIndex].GetId(), &LmbrCentral::ShapeComponentRequests::IntersectRay,
|
||||
rayOrigin, -OffsetsFromSurface[rayIndex], distance2);
|
||||
rayOrigin, -OffsetsFromSurfaceQuad[rayIndex], distance2);
|
||||
|
||||
EXPECT_FALSE(rayHit2);
|
||||
}
|
||||
|
||||
@@ -21,13 +21,16 @@ namespace LmbrCentral
|
||||
/// Type ID for the EditorBoxShapeComponent
|
||||
static const AZ::Uuid EditorBoxShapeComponentTypeId = "{2ADD9043-48E8-4263-859A-72E0024372BF}";
|
||||
|
||||
/// Type ID for the BoxShapeConfig
|
||||
static const AZ::Uuid BoxShapeConfigTypeId = "{F034FBA2-AC2F-4E66-8152-14DFB90D6283}";
|
||||
|
||||
/// Configuration data for BoxShapeComponent
|
||||
class BoxShapeConfig
|
||||
: public ShapeComponentConfig
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BoxShapeConfig, AZ::SystemAllocator, 0)
|
||||
AZ_RTTI(BoxShapeConfig, "{F034FBA2-AC2F-4E66-8152-14DFB90D6283}", ShapeComponentConfig)
|
||||
AZ_RTTI(BoxShapeConfig, BoxShapeConfigTypeId, ShapeComponentConfig)
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ set(FILES
|
||||
Source/Shape/EditorDiskShapeComponent.cpp
|
||||
Source/Shape/EditorBoxShapeComponent.h
|
||||
Source/Shape/EditorBoxShapeComponent.cpp
|
||||
Source/Shape/EditorAxisAlignedBoxShapeComponent.h
|
||||
Source/Shape/EditorAxisAlignedBoxShapeComponent.cpp
|
||||
Source/Shape/EditorCylinderShapeComponent.h
|
||||
Source/Shape/EditorCylinderShapeComponent.cpp
|
||||
Source/Shape/EditorCapsuleShapeComponent.h
|
||||
|
||||
@@ -106,6 +106,10 @@ set(FILES
|
||||
Source/Shape/SphereShape.cpp
|
||||
Source/Shape/SphereShapeComponent.h
|
||||
Source/Shape/SphereShapeComponent.cpp
|
||||
Source/Shape/AxisAlignedBoxShape.h
|
||||
Source/Shape/AxisAlignedBoxShape.cpp
|
||||
Source/Shape/AxisAlignedBoxShapeComponent.h
|
||||
Source/Shape/AxisAlignedBoxShapeComponent.cpp
|
||||
Source/Shape/BoxShape.h
|
||||
Source/Shape/BoxShape.cpp
|
||||
Source/Shape/BoxShapeComponent.h
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
set(FILES
|
||||
Tests/AudioComponentTests.cpp
|
||||
Tests/AxisAlignedBoxShapeTest.cpp
|
||||
Tests/BoxShapeTest.cpp
|
||||
Tests/BundlingSystemComponentTests.cpp
|
||||
Tests/SphereShapeTest.cpp
|
||||
|
||||
@@ -78,6 +78,8 @@ namespace ScriptCanvas
|
||||
variableIds.insert(scopedVariableId->m_identifier);
|
||||
}
|
||||
}
|
||||
|
||||
Node::CollectVariableReferences(variableIds);
|
||||
}
|
||||
|
||||
bool EBusEventHandler::ContainsReferencesToVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const
|
||||
@@ -90,11 +92,14 @@ namespace ScriptCanvas
|
||||
|
||||
if (scopedVariableId)
|
||||
{
|
||||
return variableIds.find(scopedVariableId->m_identifier) != variableIds.end();
|
||||
if(variableIds.find(scopedVariableId->m_identifier) != variableIds.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return Node::ContainsReferencesToVariables(variableIds);
|
||||
}
|
||||
|
||||
size_t EBusEventHandler::GenerateFingerprint() const
|
||||
|
||||
@@ -105,17 +105,19 @@ namespace Terrain
|
||||
AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId());
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusConnect(GetEntityId());
|
||||
TerrainAreaRequestBus::Handler::BusConnect(GetEntityId());
|
||||
TerrainSpawnerRequestBus::Handler::BusConnect(GetEntityId());
|
||||
|
||||
TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::RegisterArea, GetEntityId());
|
||||
}
|
||||
|
||||
void TerrainLayerSpawnerComponent::Deactivate()
|
||||
{
|
||||
TerrainAreaRequestBus::Handler::BusDisconnect();
|
||||
TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::UnregisterArea, GetEntityId());
|
||||
|
||||
AZ::TransformNotificationBus::Handler::BusDisconnect();
|
||||
TerrainSpawnerRequestBus::Handler::BusDisconnect();
|
||||
TerrainAreaRequestBus::Handler::BusDisconnect();
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusDisconnect();
|
||||
AZ::TransformNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
}
|
||||
|
||||
bool TerrainLayerSpawnerComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
|
||||
@@ -147,6 +149,17 @@ namespace Terrain
|
||||
{
|
||||
RefreshArea();
|
||||
}
|
||||
|
||||
void TerrainLayerSpawnerComponent::GetPriority(AZ::u32& outLayer, AZ::u32& outPriority)
|
||||
{
|
||||
outLayer = m_configuration.m_layer;
|
||||
outPriority = m_configuration.m_priority;
|
||||
}
|
||||
|
||||
bool TerrainLayerSpawnerComponent::GetUseGroundPlane()
|
||||
{
|
||||
return m_configuration.m_useGroundPlane;
|
||||
}
|
||||
|
||||
void TerrainLayerSpawnerComponent::RegisterArea()
|
||||
{
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace Terrain
|
||||
, private AZ::TransformNotificationBus::Handler
|
||||
, private LmbrCentral::ShapeComponentNotificationsBus::Handler
|
||||
, private Terrain::TerrainAreaRequestBus::Handler
|
||||
, private Terrain::TerrainSpawnerRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
template<typename, typename>
|
||||
@@ -80,7 +81,6 @@ namespace Terrain
|
||||
bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
|
||||
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AZ::TransformNotificationBus::Handler
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
@@ -88,6 +88,10 @@ namespace Terrain
|
||||
// ShapeComponentNotificationsBus
|
||||
void OnShapeChanged(ShapeChangeReasons changeReason) override;
|
||||
|
||||
// TerrainSpawnerRequestBus
|
||||
void GetPriority(AZ::u32& outLayer, AZ::u32& outPriority) override;
|
||||
bool GetUseGroundPlane() override;
|
||||
|
||||
void RegisterArea() override;
|
||||
void RefreshArea() override;
|
||||
|
||||
|
||||
@@ -17,6 +17,33 @@
|
||||
|
||||
using namespace Terrain;
|
||||
|
||||
bool TerrainLayerPriorityComparator::operator()(const AZ::EntityId& layer1id, const AZ::EntityId& layer2id) const
|
||||
{
|
||||
// Comparator for insertion/keylookup.
|
||||
// Sorts into layer/priority order, highest priority first.
|
||||
AZ::u32 priority1, layer1;
|
||||
Terrain::TerrainSpawnerRequestBus::Event(layer1id, &Terrain::TerrainSpawnerRequestBus::Events::GetPriority, layer1, priority1);
|
||||
|
||||
AZ::u32 priority2, layer2;
|
||||
Terrain::TerrainSpawnerRequestBus::Event(layer2id, &Terrain::TerrainSpawnerRequestBus::Events::GetPriority, layer2, priority2);
|
||||
|
||||
if (layer1 < layer2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (layer1 > layer2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (priority1 != priority2)
|
||||
{
|
||||
return priority1 > priority2;
|
||||
}
|
||||
|
||||
return layer1id > layer2id;
|
||||
}
|
||||
|
||||
TerrainSystem::TerrainSystem()
|
||||
{
|
||||
Terrain::TerrainSystemServiceRequestBus::Handler::BusConnect();
|
||||
@@ -78,17 +105,14 @@ float TerrainSystem::GetHeightSynchronous(float x, float y) const
|
||||
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_areaMutex);
|
||||
|
||||
if (!m_registeredAreas.empty())
|
||||
for (auto& [areaId, areaBounds] : m_registeredAreas)
|
||||
{
|
||||
for (auto& [areaId, areaBounds] : m_registeredAreas)
|
||||
inPosition.SetZ(areaBounds.GetMin().GetZ());
|
||||
if (areaBounds.Contains(inPosition))
|
||||
{
|
||||
inPosition.SetZ(areaBounds.GetMin().GetZ());
|
||||
if (areaBounds.Contains(inPosition))
|
||||
{
|
||||
Terrain::TerrainAreaHeightRequestBus::Event(
|
||||
areaId, &Terrain::TerrainAreaHeightRequestBus::Events::GetHeight, inPosition, outPosition,
|
||||
Terrain::TerrainAreaHeightRequestBus::Events::Sampler::DEFAULT);
|
||||
}
|
||||
Terrain::TerrainAreaHeightRequestBus::Event(
|
||||
areaId, &Terrain::TerrainAreaHeightRequestBus::Events::GetHeight, inPosition, outPosition,
|
||||
Terrain::TerrainAreaHeightRequestBus::Events::Sampler::DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,26 +329,34 @@ void TerrainSystem::SystemDeactivate()
|
||||
|
||||
void TerrainSystem::RegisterArea(AZ::EntityId areaId)
|
||||
{
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_areaMutex);
|
||||
AZ::Aabb aabb = AZ::Aabb::CreateNull();
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(aabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
|
||||
m_registeredAreas[areaId] = aabb;
|
||||
}
|
||||
|
||||
RefreshArea(areaId);
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_areaMutex);
|
||||
AZ::Aabb aabb = AZ::Aabb::CreateNull();
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(aabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
|
||||
m_registeredAreas[areaId] = aabb;
|
||||
m_dirtyRegion.AddAabb(aabb);
|
||||
m_terrainHeightDirty = true;
|
||||
}
|
||||
|
||||
void TerrainSystem::UnregisterArea(AZ::EntityId areaId)
|
||||
{
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_areaMutex);
|
||||
AZ::Aabb aabb = AZ::Aabb::CreateNull();
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(aabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
|
||||
m_registeredAreas.erase(areaId);
|
||||
}
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_areaMutex);
|
||||
|
||||
RefreshArea(areaId);
|
||||
// Remove the data for this entity from the registered areas.
|
||||
// Erase_if is used as erase would use the comparator to lookup the entity id in the map.
|
||||
// As the comparator will get the new layer/priority data for the entity, the id lookup will fail.
|
||||
AZStd::erase_if(
|
||||
m_registeredAreas,
|
||||
[areaId, this](const auto& item)
|
||||
{
|
||||
auto const& [entityId, aabb] = item;
|
||||
if (areaId == entityId)
|
||||
{
|
||||
m_dirtyRegion.AddAabb(aabb);
|
||||
m_terrainHeightDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void TerrainSystem::RefreshArea(AZ::EntityId areaId)
|
||||
@@ -336,7 +368,6 @@ void TerrainSystem::RefreshArea(AZ::EntityId areaId)
|
||||
AZ::Aabb oldAabb = (areaAabb != m_registeredAreas.end()) ? areaAabb->second : AZ::Aabb::CreateNull();
|
||||
AZ::Aabb newAabb = AZ::Aabb::CreateNull();
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(newAabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
|
||||
|
||||
m_registeredAreas[areaId] = newAabb;
|
||||
|
||||
AZ::Aabb expandedAabb = oldAabb;
|
||||
@@ -400,31 +431,37 @@ void TerrainSystem::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/)
|
||||
const uint32_t pixelDataSize = width * height * sizeof(float);
|
||||
memset(pixels.data(), 0, pixelDataSize);
|
||||
|
||||
for (auto& [areaId, areaBounds] : m_registeredAreas)
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
{
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
for (uint32_t x = 0; x < width; x++)
|
||||
{
|
||||
for (uint32_t x = 0; x < width; x++)
|
||||
// Find the first terrain layer that covers this position. This will be the highest priority, so others can be ignored.
|
||||
for (auto& [areaId, areaBounds] : m_registeredAreas)
|
||||
{
|
||||
AZ::Vector3 inPosition(
|
||||
(x * m_currentSettings.m_heightQueryResolution.GetX()) + m_currentSettings.m_worldBounds.GetMin().GetX(),
|
||||
(y * m_currentSettings.m_heightQueryResolution.GetY()) + m_currentSettings.m_worldBounds.GetMin().GetY(),
|
||||
areaBounds.GetMin().GetZ());
|
||||
if (areaBounds.Contains(inPosition))
|
||||
|
||||
if (!areaBounds.Contains(inPosition))
|
||||
{
|
||||
AZ::Vector3 outPosition;
|
||||
const Terrain::TerrainAreaHeightRequests::Sampler sampleFilter =
|
||||
Terrain::TerrainAreaHeightRequests::Sampler::DEFAULT;
|
||||
|
||||
Terrain::TerrainAreaHeightRequestBus::Event(
|
||||
areaId, &Terrain::TerrainAreaHeightRequestBus::Events::GetHeight, inPosition, outPosition, sampleFilter);
|
||||
|
||||
pixels[(y * width) + x] = (outPosition.GetZ() - m_currentSettings.m_worldBounds.GetMin().GetZ()) /
|
||||
m_currentSettings.m_worldBounds.GetExtents().GetZ();
|
||||
continue;
|
||||
}
|
||||
|
||||
AZ::Vector3 outPosition;
|
||||
const Terrain::TerrainAreaHeightRequests::Sampler sampleFilter = Terrain::TerrainAreaHeightRequests::Sampler::DEFAULT;
|
||||
|
||||
Terrain::TerrainAreaHeightRequestBus::Event(
|
||||
areaId, &Terrain::TerrainAreaHeightRequestBus::Events::GetHeight, inPosition, outPosition, sampleFilter);
|
||||
|
||||
pixels[(y * width) + x] = (outPosition.GetZ() - m_currentSettings.m_worldBounds.GetMin().GetZ()) /
|
||||
m_currentSettings.m_worldBounds.GetExtents().GetZ();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const AZ::RPI::Scene* scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene().get();
|
||||
auto terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
struct TerrainLayerPriorityComparator
|
||||
{
|
||||
bool operator()(const AZ::EntityId& layer1id, const AZ::EntityId& layer2id) const;
|
||||
};
|
||||
|
||||
class TerrainSystem
|
||||
: public AzFramework::Terrain::TerrainDataRequestBus::Handler
|
||||
, private Terrain::TerrainSystemServiceRequestBus::Handler
|
||||
@@ -112,6 +117,6 @@ namespace Terrain
|
||||
AZ::Aabb m_dirtyRegion;
|
||||
|
||||
mutable AZStd::shared_mutex m_areaMutex;
|
||||
AZStd::unordered_map<AZ::EntityId, AZ::Aabb> m_registeredAreas;
|
||||
AZStd::map<AZ::EntityId, AZ::Aabb, TerrainLayerPriorityComparator> m_registeredAreas;
|
||||
};
|
||||
} // namespace Terrain
|
||||
|
||||
@@ -112,5 +112,26 @@ namespace Terrain
|
||||
};
|
||||
|
||||
using TerrainAreaHeightRequestBus = AZ::EBus<TerrainAreaHeightRequests>;
|
||||
|
||||
/**
|
||||
* A bus for the TerrainSystem to interrogate TerrainLayerSpawners.
|
||||
*/
|
||||
class TerrainSpawnerRequests
|
||||
: public AZ::ComponentBus
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~TerrainSpawnerRequests() = default;
|
||||
|
||||
virtual void GetPriority(AZ::u32& outLayer, AZ::u32& outPriority) = 0;
|
||||
virtual bool GetUseGroundPlane() = 0;
|
||||
|
||||
};
|
||||
|
||||
using TerrainSpawnerRequestBus = AZ::EBus<TerrainSpawnerRequests>;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Memory/MemoryComponent.h>
|
||||
|
||||
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
|
||||
|
||||
#include <Components/TerrainLayerSpawnerComponent.h>
|
||||
#include <LmbrCentral/Shape/BoxShapeComponentBus.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <TerrainMocks.h>
|
||||
|
||||
class LayerSpawnerComponentTest
|
||||
: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
AZ::ComponentApplication m_app;
|
||||
|
||||
AZStd::unique_ptr<AZ::Entity> m_entity;
|
||||
Terrain::TerrainLayerSpawnerComponent* m_layerSpawnerComponent;
|
||||
UnitTest::MockBoxShapeComponent* m_shapeComponent;
|
||||
AZStd::unique_ptr<UnitTest::MockTerrainSystem> m_terrainSystem;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AZ::ComponentApplication::Descriptor appDesc;
|
||||
appDesc.m_memoryBlocksByteSize = 20 * 1024 * 1024;
|
||||
appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_NO_RECORDS;
|
||||
appDesc.m_stackRecordLevels = 20;
|
||||
|
||||
m_app.Create(appDesc);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (m_terrainSystem)
|
||||
{
|
||||
m_terrainSystem->Deactivate();
|
||||
}
|
||||
m_app.Destroy();
|
||||
}
|
||||
|
||||
void CreateEntity()
|
||||
{
|
||||
m_entity = AZStd::make_unique<AZ::Entity>();
|
||||
m_entity->Init();
|
||||
|
||||
ASSERT_TRUE(m_entity);
|
||||
}
|
||||
|
||||
void AddLayerSpawnerAndShapeComponentToEntity()
|
||||
{
|
||||
AddLayerSpawnerAndShapeComponentToEntity(Terrain::TerrainLayerSpawnerConfig());
|
||||
}
|
||||
|
||||
void AddLayerSpawnerAndShapeComponentToEntity(const Terrain::TerrainLayerSpawnerConfig& config)
|
||||
{
|
||||
m_layerSpawnerComponent = m_entity->CreateComponent<Terrain::TerrainLayerSpawnerComponent>(config);
|
||||
m_app.RegisterComponentDescriptor(m_layerSpawnerComponent->CreateDescriptor());
|
||||
|
||||
m_shapeComponent = m_entity->CreateComponent<UnitTest::MockBoxShapeComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_shapeComponent->CreateDescriptor());
|
||||
|
||||
ASSERT_TRUE(m_layerSpawnerComponent);
|
||||
ASSERT_TRUE(m_shapeComponent);
|
||||
}
|
||||
|
||||
void ResetEntity()
|
||||
{
|
||||
m_entity->Deactivate();
|
||||
m_entity->Reset();
|
||||
}
|
||||
|
||||
void CreateMockTerrainSystem()
|
||||
{
|
||||
m_terrainSystem = AZStd::make_unique<UnitTest::MockTerrainSystem>();
|
||||
m_terrainSystem->Activate();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, ActivatEntityActivateSuccess)
|
||||
{
|
||||
CreateEntity();
|
||||
AddLayerSpawnerAndShapeComponentToEntity();
|
||||
|
||||
m_entity->Activate();
|
||||
EXPECT_EQ(m_entity->GetState(), AZ::Entity::State::Active);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, LayerSpawnerDefaultValuesCorrect)
|
||||
{
|
||||
CreateEntity();
|
||||
AddLayerSpawnerAndShapeComponentToEntity();
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
AZ::u32 priority = 999, layer = 999;
|
||||
Terrain::TerrainSpawnerRequestBus::Event(m_entity->GetId(), &Terrain::TerrainSpawnerRequestBus::Events::GetPriority, layer, priority);
|
||||
|
||||
EXPECT_EQ(0, priority);
|
||||
EXPECT_EQ(1, layer);
|
||||
|
||||
bool useGroundPlane = false;
|
||||
|
||||
Terrain::TerrainSpawnerRequestBus::EventResult(useGroundPlane, m_entity->GetId(), &Terrain::TerrainSpawnerRequestBus::Events::GetUseGroundPlane);
|
||||
|
||||
EXPECT_TRUE(useGroundPlane);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, LayerSpawnerConfigValuesCorrect)
|
||||
{
|
||||
CreateEntity();
|
||||
|
||||
constexpr static AZ::u32 testPriority = 15;
|
||||
constexpr static AZ::u32 testLayer = 0;
|
||||
|
||||
Terrain::TerrainLayerSpawnerConfig config;
|
||||
config.m_layer = testLayer;
|
||||
config.m_priority = testPriority;
|
||||
config.m_useGroundPlane = false;
|
||||
|
||||
AddLayerSpawnerAndShapeComponentToEntity(config);
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
AZ::u32 priority = 999, layer = 999;
|
||||
Terrain::TerrainSpawnerRequestBus::Event(m_entity->GetId(), &Terrain::TerrainSpawnerRequestBus::Events::GetPriority, layer, priority);
|
||||
|
||||
EXPECT_EQ(testPriority, priority);
|
||||
EXPECT_EQ(testLayer, layer);
|
||||
|
||||
bool useGroundPlane = true;
|
||||
|
||||
Terrain::TerrainSpawnerRequestBus::EventResult(
|
||||
useGroundPlane, m_entity->GetId(), &Terrain::TerrainSpawnerRequestBus::Events::GetUseGroundPlane);
|
||||
|
||||
EXPECT_FALSE(useGroundPlane);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, LayerSpawnerRegisterAreaUpdatesTerrainSystem)
|
||||
{
|
||||
CreateEntity();
|
||||
|
||||
CreateMockTerrainSystem();
|
||||
|
||||
AddLayerSpawnerAndShapeComponentToEntity();
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
// The Activate call should have registered the area.
|
||||
EXPECT_EQ(1, m_terrainSystem->m_registerAreaCalledCount);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, LayerSpawnerUnregisterAreaUpdatesTerrainSystem)
|
||||
{
|
||||
CreateEntity();
|
||||
|
||||
CreateMockTerrainSystem();
|
||||
|
||||
AddLayerSpawnerAndShapeComponentToEntity();
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
m_layerSpawnerComponent->Deactivate();
|
||||
|
||||
// The Deactivate call should have unregistered the area.
|
||||
EXPECT_EQ(1, m_terrainSystem->m_unregisterAreaCalledCount);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, LayerSpawnerTransformChangedUpdatesTerrainSystem)
|
||||
{
|
||||
CreateEntity();
|
||||
|
||||
CreateMockTerrainSystem();
|
||||
|
||||
AddLayerSpawnerAndShapeComponentToEntity();
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
AZ::TransformNotificationBus::Event(
|
||||
m_entity->GetId(), &AZ::TransformNotificationBus::Events::OnTransformChanged, AZ::Transform(), AZ::Transform());
|
||||
|
||||
EXPECT_EQ(1, m_terrainSystem->m_refreshAreaCalledCount);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
|
||||
TEST_F(LayerSpawnerComponentTest, LayerSpawnerShapeChangedUpdatesTerrainSystem)
|
||||
{
|
||||
CreateEntity();
|
||||
|
||||
CreateMockTerrainSystem();
|
||||
|
||||
AddLayerSpawnerAndShapeComponentToEntity();
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Event(
|
||||
m_entity->GetId(), &LmbrCentral::ShapeComponentNotificationsBus::Events::OnShapeChanged,
|
||||
LmbrCentral::ShapeComponentNotifications::ShapeChangeReasons::ShapeChanged);
|
||||
|
||||
EXPECT_EQ(1, m_terrainSystem->m_refreshAreaCalledCount);
|
||||
|
||||
ResetEntity();
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <LmbrCentral/Shape/ShapeComponentBus.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
static const AZ::Uuid BoxShapeComponentTypeId = "{5EDF4B9E-0D3D-40B8-8C91-5142BCFC30A6}";
|
||||
|
||||
class MockBoxShapeComponent
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(MockBoxShapeComponent, BoxShapeComponentTypeId)
|
||||
static void Reflect([[maybe_unused]] AZ::ReflectContext* context)
|
||||
{
|
||||
}
|
||||
|
||||
void Activate() override
|
||||
{
|
||||
}
|
||||
|
||||
void Deactivate() override
|
||||
{
|
||||
}
|
||||
|
||||
bool ReadInConfig([[maybe_unused]] const AZ::ComponentConfig* baseConfig) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteOutConfig([[maybe_unused]] AZ::ComponentConfig* outBaseConfig) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static void GetProvidedServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("ShapeService", 0xe86aa5fe));
|
||||
provided.push_back(AZ_CRC("BoxShapeService", 0x946a0032));
|
||||
}
|
||||
|
||||
static void GetIncompatibleServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
}
|
||||
|
||||
static void GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
}
|
||||
|
||||
static void GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class MockTerrainSystem : private Terrain::TerrainSystemServiceRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
void Activate() override
|
||||
{
|
||||
Terrain::TerrainSystemServiceRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void Deactivate() override
|
||||
{
|
||||
Terrain::TerrainSystemServiceRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void SetWorldBounds(const AZ::Aabb& worldBounds) override
|
||||
{
|
||||
}
|
||||
|
||||
void SetHeightQueryResolution([[maybe_unused]] AZ::Vector2 queryResolution) override
|
||||
{
|
||||
}
|
||||
|
||||
void RegisterArea([[maybe_unused]] AZ::EntityId areaId) override
|
||||
{
|
||||
m_registerAreaCalledCount++;
|
||||
}
|
||||
|
||||
void UnregisterArea([[maybe_unused]] AZ::EntityId areaId) override
|
||||
{
|
||||
m_unregisterAreaCalledCount++;
|
||||
}
|
||||
|
||||
void RefreshArea([[maybe_unused]] AZ::EntityId areaId) override
|
||||
{
|
||||
m_refreshAreaCalledCount++;
|
||||
}
|
||||
|
||||
int m_registerAreaCalledCount = 0;
|
||||
int m_refreshAreaCalledCount = 0;
|
||||
int m_unregisterAreaCalledCount = 0;
|
||||
};
|
||||
}
|
||||
@@ -7,5 +7,7 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Tests/TerrainMocks.h
|
||||
Tests/TerrainTest.cpp
|
||||
Tests/LayerSpawnerTests.cpp
|
||||
)
|
||||
|
||||
@@ -11,7 +11,6 @@ ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5
|
||||
ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023)
|
||||
ly_associate_package(PACKAGE_NAME RapidXML-1.13-multiplatform TARGETS RapidXML PACKAGE_HASH 510b3c12f8872c54b34733e34f2f69dd21837feafa55bfefa445c98318d96ebf)
|
||||
ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev1-android TARGETS lz4 PACKAGE_HASH da8ec7736640a3e9834f6db1c69e8a0ea61c054fe8b6324509f36928cfc21dc9)
|
||||
ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418)
|
||||
ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665)
|
||||
ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform TARGETS glad PACKAGE_HASH ff97ee9664e97d0854b52a3734c2289329d9f2b4cd69478df6d0ca1f1c9392ee)
|
||||
@@ -28,3 +27,5 @@ ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-android TARGETS Goo
|
||||
ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-android TARGETS libsamplerate PACKAGE_HASH bf13662afe65d02bcfa16258a4caa9b875534978227d6f9f36c9cfa92b3fb12b)
|
||||
ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev1-android TARGETS OpenSSL PACKAGE_HASH 4036d4019d722f0e1b7a1621bf60b5a17ca6a65c9c78fd8701cee1131eec8480)
|
||||
ly_associate_package(PACKAGE_NAME zlib-1.2.11-rev2-android TARGETS zlib PACKAGE_HASH 85b730b97176772538cfcacd6b6aaf4655fc2d368d134d6dd55e02f28f183826)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev4-android TARGETS lz4 PACKAGE_HASH f5b22642d218dbbb442cae61e469e5b241c4740acd258c3e8678e60dec61ea93)
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform
|
||||
ly_associate_package(PACKAGE_NAME RapidXML-1.13-multiplatform TARGETS RapidXML PACKAGE_HASH 510b3c12f8872c54b34733e34f2f69dd21837feafa55bfefa445c98318d96ebf)
|
||||
ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev2-multiplatform TARGETS pybind11 PACKAGE_HASH d8012f907b6c54ac990b899a0788280857e7c93a9595405a28114b48c354eb1b)
|
||||
ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev1-linux TARGETS lz4 PACKAGE_HASH 2e2653ce04a036c38fe28f3971bc3bfb8a4e771335aa8d1b95b0feb3423f1b0a)
|
||||
ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418)
|
||||
ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665)
|
||||
ly_associate_package(PACKAGE_NAME SQLite-3.32.2-rev3-multiplatform TARGETS SQLite PACKAGE_HASH dd4d3de6cbb4ce3d15fc504ba0ae0587e515dc89a25228037035fc0aef4831f4)
|
||||
@@ -28,7 +27,7 @@ ly_associate_package(PACKAGE_NAME PVRTexTool-4.24.0-rev4-multiplatform
|
||||
ly_associate_package(PACKAGE_NAME AWSGameLiftServerSDK-3.4.1-rev1-linux TARGETS AWSGameLiftServerSDK PACKAGE_HASH a8149a95bd100384af6ade97e2b21a56173740d921e6c3da8188cd51554d39af)
|
||||
ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-linux TARGETS freetype PACKAGE_HASH 9ad246873067717962c6b780d28a5ce3cef3321b73c9aea746a039c798f52e93)
|
||||
ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-linux TARGETS tiff PACKAGE_HASH ae92b4d3b189c42ef644abc5cac865d1fb2eb7cb5622ec17e35642b00d1a0a76)
|
||||
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev5-linux TARGETS AWSNativeSDK PACKAGE_HASH 0101a4052d9fce83a6f5515e00f366e97b308ecb8261ad23a6e4eb4365212ab6)
|
||||
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev6-linux TARGETS AWSNativeSDK PACKAGE_HASH 490291e4c8057975c3ab86feb971b8a38871c58bac5e5d86abdd1aeb7141eec4)
|
||||
ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-linux TARGETS Lua PACKAGE_HASH 1adc812abe3dd0dbb2ca9756f81d8f0e0ba45779ac85bf1d8455b25c531a38b0)
|
||||
ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-linux TARGETS PhysX PACKAGE_HASH a110249cbef4f266b0002c4ee9a71f59f373040cefbe6b82f1e1510c811edde6)
|
||||
ly_associate_package(PACKAGE_NAME etc2comp-9cd0f9cae0-rev1-linux TARGETS etc2comp PACKAGE_HASH 9283aa5db5bb7fb90a0ddb7a9f3895317c8ebe8044943124bbb3673a41407430)
|
||||
@@ -46,5 +45,4 @@ ly_associate_package(PACKAGE_NAME azslc-1.7.23-rev2-linux
|
||||
ly_associate_package(PACKAGE_NAME zlib-1.2.11-rev2-linux TARGETS zlib PACKAGE_HASH 16f3b9e11cda525efb62144f354c1cfc30a5def9eff020dbe49cb00ee7d8234f)
|
||||
ly_associate_package(PACKAGE_NAME squish-ccr-deb557d-rev1-linux TARGETS squish-ccr PACKAGE_HASH 85fecafbddc6a41a27c5f59ed4a5dfb123a94cb4666782cf26e63c0a4724c530)
|
||||
ly_associate_package(PACKAGE_NAME ISPCTexComp-36b80aa-rev1-linux TARGETS ISPCTexComp PACKAGE_HASH 065fd12abe4247dde247330313763cf816c3375c221da030bdec35024947f259)
|
||||
|
||||
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev4-linux TARGETS lz4 PACKAGE_HASH 5de3dbd3e2a3537c6555d759b3c5bb98e5456cf85c74ff6d046f809b7087290d)
|
||||
|
||||
+2
-2
@@ -15,7 +15,6 @@ ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform
|
||||
ly_associate_package(PACKAGE_NAME RapidXML-1.13-multiplatform TARGETS RapidXML PACKAGE_HASH 510b3c12f8872c54b34733e34f2f69dd21837feafa55bfefa445c98318d96ebf)
|
||||
ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev2-multiplatform TARGETS pybind11 PACKAGE_HASH d8012f907b6c54ac990b899a0788280857e7c93a9595405a28114b48c354eb1b)
|
||||
ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev1-mac TARGETS lz4 PACKAGE_HASH 3ce6866b43d024452c0412f385ae46aba0e1ae99eb64f7099d3fc539c8460881)
|
||||
ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418)
|
||||
ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665)
|
||||
ly_associate_package(PACKAGE_NAME SQLite-3.32.2-rev3-multiplatform TARGETS SQLite PACKAGE_HASH dd4d3de6cbb4ce3d15fc504ba0ae0587e515dc89a25228037035fc0aef4831f4)
|
||||
@@ -30,7 +29,7 @@ ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev3-ma
|
||||
ly_associate_package(PACKAGE_NAME SPIRVCross-2021.04.29-rev1-mac TARGETS SPIRVCross PACKAGE_HASH 78c6376ed2fd195b9b1f5fb2b56e5267a32c3aa21fb399e905308de470eb4515)
|
||||
ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-mac-ios TARGETS freetype PACKAGE_HASH 67b4f57aed92082d3fd7c16aa244a7d908d90122c296b0a63f73e0a0b8761977)
|
||||
ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-mac-ios TARGETS tiff PACKAGE_HASH a23ae1f8991a29f8e5df09d6d5b00d7768a740f90752cef465558c1768343709)
|
||||
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev4-mac TARGETS AWSNativeSDK PACKAGE_HASH 89e1651cde6b4e6bd80cdb96ed6b624accad9f9688ff38bfca226777f4fcb678)
|
||||
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev5-mac TARGETS AWSNativeSDK PACKAGE_HASH ffb890bd9cf23afb429b9214ad9bac1bf04696f07a0ebb93c42058c482ab2f01)
|
||||
ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev6-mac TARGETS Lua PACKAGE_HASH b9079fd35634774c9269028447562c6b712dbc83b9c64975c095fd423ff04c08)
|
||||
ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-mac TARGETS PhysX PACKAGE_HASH 5e092a11d5c0a50c4dd99bb681a04b566a4f6f29aa08443d9bffc8dc12c27c8e)
|
||||
ly_associate_package(PACKAGE_NAME etc2comp-9cd0f9cae0-rev1-mac TARGETS etc2comp PACKAGE_HASH 1966ab101c89db7ecf30984917e0a48c0d02ee0e4d65b798743842b9469c0818)
|
||||
@@ -44,4 +43,5 @@ ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-mac
|
||||
ly_associate_package(PACKAGE_NAME zlib-1.2.11-rev2-mac TARGETS zlib PACKAGE_HASH 21714e8a6de4f2523ee92a7f52d51fbee29c5f37ced334e00dc3c029115b472e)
|
||||
ly_associate_package(PACKAGE_NAME squish-ccr-deb557d-rev1-mac TARGETS squish-ccr PACKAGE_HASH 155bfbfa17c19a9cd2ef025de14c5db598f4290045d5b0d83ab58cb345089a77)
|
||||
ly_associate_package(PACKAGE_NAME ISPCTexComp-36b80aa-rev1-mac TARGETS ISPCTexComp PACKAGE_HASH 8a4e93277b8face6ea2fd57c6d017bdb55643ed3d6387110bc5f6b3b884dd169)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev4-mac TARGETS lz4 PACKAGE_HASH 891ff630bf34f7ab1d8eaee2ea0a8f1fca89dbdc63fca41ee592703dd488a73b)
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform
|
||||
ly_associate_package(PACKAGE_NAME RapidXML-1.13-multiplatform TARGETS RapidXML PACKAGE_HASH 510b3c12f8872c54b34733e34f2f69dd21837feafa55bfefa445c98318d96ebf)
|
||||
ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev2-multiplatform TARGETS pybind11 PACKAGE_HASH d8012f907b6c54ac990b899a0788280857e7c93a9595405a28114b48c354eb1b)
|
||||
ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev1-windows TARGETS lz4 PACKAGE_HASH 02e6ba2ca1407483bac082fd97803c5e19f48bc576171bfc8cec62412efe639c)
|
||||
ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418)
|
||||
ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665)
|
||||
ly_associate_package(PACKAGE_NAME SQLite-3.32.2-rev3-multiplatform TARGETS SQLite PACKAGE_HASH dd4d3de6cbb4ce3d15fc504ba0ae0587e515dc89a25228037035fc0aef4831f4)
|
||||
@@ -31,7 +30,7 @@ ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev3-wi
|
||||
ly_associate_package(PACKAGE_NAME SPIRVCross-2021.04.29-rev1-windows TARGETS SPIRVCross PACKAGE_HASH 7d601ea9d625b1d509d38bd132a1f433d7e895b16adab76bac6103567a7a6817)
|
||||
ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-windows TARGETS freetype PACKAGE_HASH 88dedc86ccb8c92f14c2c033e51ee7d828fa08eafd6475c6aa963938a99f4bf3)
|
||||
ly_associate_package(PACKAGE_NAME tiff-4.2.0.14-windows TARGETS tiff PACKAGE_HASH ab60d1398e4e1e375ec0f1a00cdb1d812a07c0096d827db575ce52dd6d714207)
|
||||
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev3-windows TARGETS AWSNativeSDK PACKAGE_HASH 929873d4252c464620a9d288e41bd5d47c0bd22750aeb3a1caa68a3da8247c48)
|
||||
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev4-windows TARGETS AWSNativeSDK PACKAGE_HASH a900e80f7259e43aed5c847afee2599ada37f29db70505481397675bcbb6c76c)
|
||||
ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-windows TARGETS Lua PACKAGE_HASH 136faccf1f73891e3fa3b95f908523187792e56f5b92c63c6a6d7e72d1158d40)
|
||||
ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-windows TARGETS PhysX PACKAGE_HASH 0c5ffbd9fa588e5cf7643721a7cfe74d0fe448bf82252d39b3a96d06dfca2298)
|
||||
ly_associate_package(PACKAGE_NAME etc2comp-9cd0f9cae0-rev1-windows TARGETS etc2comp PACKAGE_HASH fc9ae937b2ec0d42d5e7d0e9e8c80e5e4d257673fb33bc9b7d6db76002117123)
|
||||
@@ -51,3 +50,4 @@ ly_associate_package(PACKAGE_NAME Crashpad-0.8.0-rev1-windows
|
||||
ly_associate_package(PACKAGE_NAME zlib-1.2.11-rev2-windows TARGETS zlib PACKAGE_HASH 9afab1d67641ed8bef2fb38fc53942da47f2ab339d9e77d3d20704a48af2da0b)
|
||||
ly_associate_package(PACKAGE_NAME squish-ccr-deb557d-rev1-windows TARGETS squish-ccr PACKAGE_HASH 5c3d9fa491e488ccaf802304ad23b932268a2b2846e383f088779962af2bfa84)
|
||||
ly_associate_package(PACKAGE_NAME ISPCTexComp-36b80aa-rev1-windows TARGETS ISPCTexComp PACKAGE_HASH b6fa6ea28a2808a9a5524c72c37789c525925e435770f2d94eb2d387360fa2d0)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev4-windows TARGETS lz4 PACKAGE_HASH 4ea457b833cd8cfaf8e8e06ed6df601d3e6783b606bdbc44a677f77e19e0db16)
|
||||
|
||||
+1
-1
@@ -11,7 +11,6 @@ ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5
|
||||
ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023)
|
||||
ly_associate_package(PACKAGE_NAME RapidXML-1.13-multiplatform TARGETS RapidXML PACKAGE_HASH 510b3c12f8872c54b34733e34f2f69dd21837feafa55bfefa445c98318d96ebf)
|
||||
ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev1-ios TARGETS lz4 PACKAGE_HASH 7a9391daf53e47e529cf811dca3554c83769f62a2ee52488610ec73214961ae1)
|
||||
ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418)
|
||||
ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665)
|
||||
ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform TARGETS glad PACKAGE_HASH ff97ee9664e97d0854b52a3734c2289329d9f2b4cd69478df6d0ca1f1c9392ee)
|
||||
@@ -29,3 +28,4 @@ ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-ios TARGETS GoogleB
|
||||
ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-ios TARGETS libsamplerate PACKAGE_HASH 7656b961697f490d4f9c35d2e61559f6fc38c32102e542a33c212cd618fc2119)
|
||||
ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev1-ios TARGETS OpenSSL PACKAGE_HASH cd0dfce3086a7172777c63dadbaf0ac3695b676119ecb6d0614b5fb1da03462f)
|
||||
ly_associate_package(PACKAGE_NAME zlib-1.2.11-rev2-ios TARGETS zlib PACKAGE_HASH a59fc0f83a02c616b679799310e9d86fde84514c6d2acefa12c6def0ae4a880c)
|
||||
ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev4-ios TARGETS lz4 PACKAGE_HASH 588ea05739caa9231a9a17a1e8cf64c5b9a265e16528bc05420af7e2534e86c1)
|
||||
|
||||
Vendored
+24
@@ -415,6 +415,19 @@ def ExportTestResults(Map options, String platform, String type, String workspac
|
||||
}
|
||||
}
|
||||
|
||||
def ExportTestScreenshots(Map options, String workspace, String platformName, String jobName, Map params) {
|
||||
catchError(message: "Error exporting test screenshots (this won't fail the build)", buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
def screenshotsFolder = '${workspace}/${ENGINE_REPOSITORY_NAME}/AutomatedTesting/user/PythonTests/Automated/Screenshots'
|
||||
def s3Uploader = '${workspace}/${ENGINE_REPOSITORY_NAME}/scripts/build/tools/upload_to_s3.py'
|
||||
def command = '${options.PYTHON_DIR}/python.cmd -u ${s3Uploader} --base_dir ${screenshotsFolder} ' +
|
||||
'--file_regex "(.*zip$)" --bucket ${env.TEST_SCREENSHOT_BUCKET} ' +
|
||||
'--search_subdirectories True --key_prefix ${branchName}_${env.BUILD_NUMBER}' +
|
||||
'--extra-args {"ACL": "bucket-owner-full-control"}'
|
||||
bat label: "Uploading test screenshots for ${jobName}",
|
||||
script: command
|
||||
}
|
||||
}
|
||||
|
||||
def PostBuildCommonSteps(String workspace, boolean mount = true) {
|
||||
echo 'Starting post-build common steps...'
|
||||
|
||||
@@ -470,6 +483,14 @@ def CreateExportTestResultsStage(Map pipelineConfig, String platformName, String
|
||||
}
|
||||
}
|
||||
|
||||
def CreateExportTestScreenshotsStage(Map pipelineConfig, String platformName, String jobName, Map environmentVars, Map params) {
|
||||
return {
|
||||
stage("${jobName}_screenshots") {
|
||||
ExportTestScreenshots(pipelineConfig, platformName, jobName, environmentVars['WORKSPACE'], params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def CreateTeardownStage(Map environmentVars) {
|
||||
return {
|
||||
stage('Teardown') {
|
||||
@@ -532,6 +553,9 @@ def CreateSingleNode(Map pipelineConfig, def platform, def build_job, Map envVar
|
||||
if (params && params.containsKey('TEST_RESULTS') && params.TEST_RESULTS == 'True') {
|
||||
CreateExportTestResultsStage(pipelineConfig, platform.key, build_job_name, envVars, params).call()
|
||||
}
|
||||
if (params && params.containsKey('TEST_SCREENSHOTS') && params.TEST_SCREENSHOTS == 'True' && currentResult == 'FAILURE') {
|
||||
CreateExportTestScreenshotsStage(pipelineConfig, platform.key, build_job_name, envVars, params).call()
|
||||
}
|
||||
CreateTeardownStage(envVars).call()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user