diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py new file mode 100644 index 0000000000..b899d7dcde --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py @@ -0,0 +1,102 @@ +""" +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 + +Hydra script that is used to create a new level with a default rendering setup. +After the level is setup, screenshots are diffed against golden images are used to verify pass/fail results of the test. + +See the run() function for more in-depth test info. +""" + +import os +import sys + +import azlmbr.legacy.general as general + +sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests")) + +import editor_python_test_tools.hydra_editor_utils as hydra +from editor_python_test_tools.editor_test_helper import EditorTestHelper +from atom_renderer.atom_utils.benchmark_utils import BenchmarkHelper + +SCREEN_WIDTH = 1280 +SCREEN_HEIGHT = 720 +DEGREE_RADIAN_FACTOR = 0.0174533 + +helper = EditorTestHelper(log_prefix="Test_Atom_BasicLevelSetup") + + +def run(): + """ + 1. View -> Layouts -> Restore Default Layout, sets the viewport to ratio 16:9 @ 1280 x 720 + 2. Runs console command r_DisplayInfo = 0 + 3. Opens AtomFeatureIntegrationBenchmark level + 4. Initializes benchmark helper with benchmark name to capture benchmark metadata. + 5. Idles for 100 frames, then collects pass timings for 100 frames. + :return: None + """ + def initial_viewport_setup(screen_width, screen_height): + general.set_viewport_size(screen_width, screen_height) + general.update_viewport() + helper.wait_for_condition( + function=lambda: helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) + and helper.isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1), + timeout_in_seconds=4.0 + ) + result = helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) and helper.isclose( + a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1) + general.log(general.get_viewport_size().x) + general.log(general.get_viewport_size().y) + general.log(general.get_viewport_size().z) + general.log(f"Viewport is set to the expected size: {result}") + general.run_console("r_DisplayInfo = 0") + + def after_level_load(): + """Function to call after creating/opening a level to ensure it loads.""" + # Give everything a second to initialize. + general.idle_enable(True) + general.idle_wait(1.0) + general.update_viewport() + general.idle_wait(0.5) # half a second is more than enough for updating the viewport. + + # Close out problematic windows, FPS meters, and anti-aliasing. + if general.is_helpers_shown(): # Turn off the helper gizmos if visible + general.toggle_helpers() + general.idle_wait(1.0) + if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. + general.close_pane("Error Report") + if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. + general.close_pane("Error Log") + general.idle_wait(1.0) + general.run_console("r_displayInfo=0") + general.run_console("r_antialiasingmode=0") + general.idle_wait(1.0) + + return True + + # Wait for Editor idle loop before executing Python hydra scripts. + general.idle_enable(True) + + general.open_level_no_prompt("AtomFeatureIntegrationBenchmark") + + # Basic setup after opening level. + after_level_load() + initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT) + + general.enter_game_mode() + general.idle_wait(1.0) + helper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=2.0) + benchmarker = BenchmarkHelper("AtomFeatureIntegrationBenchmark") + benchmarker.capture_benchmark_metadata() + general.idle_wait_frames(100) + for i in range(1, 101): + benchmarker.capture_pass_timestamp(i) + general.exit_game_mode() + helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=2.0) + general.log("Capturing complete.") + + +if __name__ == "__main__": + run() diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py new file mode 100644 index 0000000000..21c7489ed3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py @@ -0,0 +1,84 @@ +""" +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 +""" +import azlmbr.atom +import azlmbr.legacy.general as general + +FOLDER_PATH = '@user@/Scripts/PerformanceBenchmarks' +METADATA_FILE = 'benchmark_metadata.json' + +class BenchmarkHelper(object): + """ + A helper to capture benchmark data. + """ + def __init__(self, benchmark_name): + super().__init__() + self.benchmark_name = benchmark_name + self.output_path = f'{FOLDER_PATH}/{benchmark_name}' + self.done = False + self.capturedData = False + self.max_frames_to_wait = 200 + + def capture_benchmark_metadata(self): + """ + Capture benchmark metadata and block further execution until it has been written to the disk. + """ + self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler() + self.handler.connect() + self.handler.add_callback('OnCaptureBenchmarkMetadataFinished', self.on_data_captured) + + self.done = False + self.capturedData = False + success = azlmbr.atom.ProfilingCaptureRequestBus( + azlmbr.bus.Broadcast, "CaptureBenchmarkMetadata", self.benchmark_name, f'{self.output_path}/{METADATA_FILE}' + ) + if success: + self.wait_until_data() + general.log('Benchmark metadata captured.') + else: + general.log('Failed to capture benchmark metadata.') + return self.capturedData + + def capture_pass_timestamp(self, frame_number): + """ + Capture pass timestamps and block further execution until it has been written to the disk. + """ + self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler() + self.handler.connect() + self.handler.add_callback('OnCaptureQueryTimestampFinished', self.on_data_captured) + + self.done = False + self.capturedData = False + success = azlmbr.atom.ProfilingCaptureRequestBus( + azlmbr.bus.Broadcast, "CapturePassTimestamp", f'{self.output_path}/frame{frame_number}_timestamps.json') + if success: + self.wait_until_data() + general.log('Pass timestamps captured.') + else: + general.log('Failed to capture pass timestamps.') + return self.capturedData + + def on_data_captured(self, parameters): + # the parameters come in as a tuple + if parameters[0]: + general.log('Captured data successfully.') + self.capturedData = True + else: + general.log('Failed to capture data.') + self.done = True + self.handler.disconnect() + + def wait_until_data(self): + frames_waited = 0 + while self.done == False: + general.idle_wait_frames(1) + if frames_waited > self.max_frames_to_wait: + general.log('Timed out while waiting for the data to be captured') + self.handler.disconnect() + break + else: + frames_waited = frames_waited + 1 + general.log(f'(waited {frames_waited} frames)') diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py index dad92d0932..ede140c075 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py @@ -14,6 +14,7 @@ import pytest import ly_test_tools.environment.file_system as file_system from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots +from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator import editor_python_test_tools.hydra_test_utils as hydra logger = logging.getLogger(__name__) @@ -83,3 +84,43 @@ class TestAllComponentsIndepthTests(object): for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images): compare_screenshots(test_screenshot, golden_screenshot) + +@pytest.mark.parametrize('rhi', ['dx12', 'vulkan']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) +@pytest.mark.parametrize("level", ["AtomFeatureIntegrationBenchmark"]) +class TestPerformanceBenchmarkSuite(object): + def test_AtomFeatureIntegrationBenchmark( + self, request, editor, workspace, rhi, project, launcher_platform, level): + """ + Please review the hydra script run by this test for more specific test info. + Tests the performance of the Simple level. + """ + expected_lines = [ + "Benchmark metadata captured.", + "Pass timestamps captured.", + "Capturing complete.", + "Captured data successfully." + ] + + unexpected_lines = [ + "Failed to capture data.", + "Failed to capture pass timestamps.", + "Failed to capture benchmark metadata." + ] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_GPUTest_AtomFeatureIntegrationBenchmark.py", + timeout=EDITOR_TIMEOUT, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + cfg_args=[level], + null_renderer=False, + ) + + aggregator = BenchmarkDataAggregator(workspace, logger, 'periodic') + aggregator.upload_metrics(rhi) diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly new file mode 100644 index 0000000000..4fc96f242b --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5232563c3ff322669808ac4daeda3d822e4ef8c9c87db0fa245f0f9c9c34aada +size 23379 diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml new file mode 100644 index 0000000000..15b79f5e4f --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak new file mode 100644 index 0000000000..fecbc0b394 --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e075be2cb7cf5aa98e3503c1119b94c3098b35500c98c4db32d025c9e1afa52d +size 5450 diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt new file mode 100644 index 0000000000..a5e0705349 --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt @@ -0,0 +1,12 @@ +495.045,510.96,35.8437,-0.166,0,-1.82124 +4.79827,4.71364,64.7838,-1.41886,0,2.48964 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 diff --git a/Code/Editor/Util/AffineParts.h b/Code/Editor/Util/AffineParts.h index cb2c609ecd..a2e3d2c79b 100644 --- a/Code/Editor/Util/AffineParts.h +++ b/Code/Editor/Util/AffineParts.h @@ -20,11 +20,11 @@ struct AffineParts Vec3 scale; //!< Stretch factors. float fDet; //!< Sign of determinant. - /** Decompose matrix to its affnie parts. + /** Decompose matrix to its affine parts. */ void Decompose(const Matrix34& mat); - /** Decompose matrix to its affnie parts. + /** Decompose matrix to its affine parts. Assume there`s no stretch rotation. */ void SpectralDecompose(const Matrix34& mat); diff --git a/Code/Framework/AzAutoGen/AzAutoGen.props b/Code/Framework/AzAutoGen/AzAutoGen.props deleted file mode 100644 index 2f809d03a6..0000000000 --- a/Code/Framework/AzAutoGen/AzAutoGen.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - True - - diff --git a/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis b/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis new file mode 100644 index 0000000000..5167714f20 --- /dev/null +++ b/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis @@ -0,0 +1,38 @@ + + + + + null + true + false + {data_.ss.str} + {(const char*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF)} + {data_.n.i.i} + {data_.n.u.u} + {data_.n.i64} + {data_.n.u64} + {data_.n.d} + Object members={data_.o.size} + Array members={data_.a.size} + + data_.o.size + data_.o.capacity + + data_.o.size + + (rapidjson_ly::GenericMember<$T1,$T2>*)(((size_t)data_.o.members) & 0x0000FFFFFFFFFFFF) + + + data_.a.size + data_.a.capacity + + data_.a.size + + (rapidjson_ly::GenericValue<$T1,$T2>*)(((size_t)data_.a.elements) & 0x0000FFFFFFFFFFFF) + + + + + + + diff --git a/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake index bcd08a6e56..6386377fcb 100644 --- a/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake +++ b/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake @@ -30,6 +30,7 @@ set(FILES ../Common/VisualStudio/AzCore/Natvis/azcore.natvis ../Common/VisualStudio/AzCore/Natvis/azcore.natstepfilter ../Common/VisualStudio/AzCore/Natvis/azcore.natjmc + ../Common/VisualStudio/AzCore/Natvis/rapidjson.natvis AzCore/Debug/StackTracer_Windows.cpp ../Common/WinAPI/AzCore/Debug/Trace_WinAPI.cpp ../Common/WinAPI/AzCore/IO/Streamer/StreamerContext_WinAPI.cpp diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h index c0ee4f8e02..66be0b9137 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h @@ -75,6 +75,8 @@ namespace AZ private: static constexpr float RowHeight = 50.0; static constexpr int DefaultFramesToCollect = 50; + static constexpr float MediumFrameTimeLimit = 16.6; // 60 fps + static constexpr float HighFrameTimeLimit = 33.3; // 30 fps // Draw the shared header between the two windows void DrawCommonHeader(); @@ -127,8 +129,11 @@ namespace AZ // Draw the ruler with frame time labels void DrawRuler(); + // Draw the frame time histogram + void DrawFrameTimeHistogram(); + // Converts raw ticks to a pixel value suitable to give to ImDrawList, handles window scrolling - float ConvertTickToPixelSpace(AZStd::sys_time_t tick) const; + float ConvertTickToPixelSpace(AZStd::sys_time_t tick, AZStd::sys_time_t leftBound, AZStd::sys_time_t rightBound) const; AZStd::sys_time_t GetViewportTickWidth() const; diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl index b59747421e..735dace1c7 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl @@ -280,7 +280,7 @@ namespace AZ { ImGui::Columns(3, "Options", true); ImGui::Text("Frames To Collect:"); - ImGui::SliderInt("", &m_framesToCollect, 10, 100, "%d", ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic); + ImGui::SliderInt("", &m_framesToCollect, 10, 10000, "%d", ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic); ImGui::NextColumn(); @@ -295,6 +295,13 @@ namespace AZ "Hold the right mouse button to move around. Zoom by scrolling the mouse wheel while holding ."); } + ImGui::Columns(1, "FrameTimeColumn", true); + + if (ImGui::BeginChild("FrameTimeHistogram", { 0, 50 }, true, ImGuiWindowFlags_NoScrollbar)) + { + DrawFrameTimeHistogram(); + } + ImGui::EndChild(); ImGui::Columns(1, "RulerColumn", true); @@ -519,8 +526,8 @@ namespace AZ ImDrawList* drawList = ImGui::GetWindowDrawList(); - const float startPixel = ConvertTickToPixelSpace(block.m_startTick); - const float endPixel = ConvertTickToPixelSpace(block.m_endTick); + const float startPixel = ConvertTickToPixelSpace(block.m_startTick, m_viewportStartTick, m_viewportEndTick); + const float endPixel = ConvertTickToPixelSpace(block.m_endTick, m_viewportStartTick, m_viewportEndTick); const ImVec2 startPoint = { startPixel, wy + targetRow * RowHeight }; const ImVec2 endPoint = { endPixel, wy + targetRow * RowHeight + 40 }; @@ -656,7 +663,7 @@ namespace AZ while (endTickItr != m_frameEndTicks.end() && *endTickItr < m_viewportEndTick) { - const float horizontalPixel = ConvertTickToPixelSpace(*endTickItr); + const float horizontalPixel = ConvertTickToPixelSpace(*endTickItr, m_viewportStartTick, m_viewportEndTick); drawList->AddLine({ horizontalPixel, wy }, { horizontalPixel, wy + windowHeight }, red); ++endTickItr; } @@ -684,8 +691,8 @@ namespace AZ break; } - const float lastFrameBoundaryPixel = ConvertTickToPixelSpace(lastFrameBoundaryTick); - const float nextFrameBoundaryPixel = ConvertTickToPixelSpace(nextFrameBoundaryTick); + const float lastFrameBoundaryPixel = ConvertTickToPixelSpace(lastFrameBoundaryTick, m_viewportStartTick, m_viewportEndTick); + const float nextFrameBoundaryPixel = ConvertTickToPixelSpace(nextFrameBoundaryTick, m_viewportStartTick, m_viewportEndTick); const AZStd::string label = AZStd::string::format("%.2f ms", CpuProfilerImGuiHelper::TicksToMs(nextFrameBoundaryTick - lastFrameBoundaryTick)); @@ -738,16 +745,98 @@ namespace AZ } } + inline void ImGuiCpuProfiler::DrawFrameTimeHistogram() + { + ImDrawList* drawList = ImGui::GetWindowDrawList(); + const auto [wx, wy] = ImGui::GetWindowPos(); + const ImU32 orange = ImGui::GetColorU32({ 1, .7, 0, 1 }); + const ImU32 red = ImGui::GetColorU32({ 1, 0, 0, 1 }); + + const AZStd::sys_time_t ticksPerSecond = AZStd::GetTimeTicksPerSecond(); + const AZStd::sys_time_t viewportCenter = m_viewportEndTick - (m_viewportEndTick - m_viewportStartTick) / 2; + const AZStd::sys_time_t leftHistogramBound = viewportCenter - ticksPerSecond; + const AZStd::sys_time_t rightHistogramBound = viewportCenter + ticksPerSecond; + + // Draw frame limit lines + drawList->AddLine( + { wx, wy + ImGui::GetWindowHeight() - MediumFrameTimeLimit }, + { wx + ImGui::GetWindowWidth(), wy + ImGui::GetWindowHeight() - MediumFrameTimeLimit }, + orange); + + drawList->AddLine( + { wx, wy + ImGui::GetWindowHeight() - HighFrameTimeLimit }, + { wx + ImGui::GetWindowWidth(), wy + ImGui::GetWindowHeight() - HighFrameTimeLimit }, + red); + + + // Draw viewport bound rectangle + const float leftViewportPixel = ConvertTickToPixelSpace(m_viewportStartTick, leftHistogramBound, rightHistogramBound); + const float rightViewportPixel = ConvertTickToPixelSpace(m_viewportEndTick, leftHistogramBound, rightHistogramBound); + const ImVec2 topLeftPos = { leftViewportPixel, wy }; + const ImVec2 botRightPos = { rightViewportPixel, wy + ImGui::GetWindowHeight() }; + const ImU32 gray = ImGui::GetColorU32({ 1, 1, 1, .3 }); + drawList->AddRectFilled(topLeftPos, botRightPos, gray); + + // Find the first onscreen frame execution time + auto frameEndTickItr = AZStd::lower_bound(m_frameEndTicks.begin(), m_frameEndTicks.end(), leftHistogramBound); + if (frameEndTickItr != m_frameEndTicks.begin()) + { + --frameEndTickItr; + } + + // Since we only store the frame end ticks, we must calculate the execution times on the fly by comparing pairs of elements. + AZStd::sys_time_t lastFrameEndTick = *frameEndTickItr; + while (*frameEndTickItr < rightHistogramBound && ++frameEndTickItr != m_frameEndTicks.end()) + { + const AZStd::sys_time_t frameEndTick = *frameEndTickItr; + + const float framePixelPos = ConvertTickToPixelSpace(frameEndTick, leftHistogramBound, rightHistogramBound); + const float frameTimeMs = CpuProfilerImGuiHelper::TicksToMs(frameEndTick - lastFrameEndTick); + + const ImVec2 lineBottom = { framePixelPos, ImGui::GetWindowHeight() + wy }; + const ImVec2 lineTop = { framePixelPos, ImGui::GetWindowHeight() + wy - frameTimeMs }; + + ImU32 lineColor = ImGui::GetColorU32({ .3, .3, .3, 1 }); // Gray + if (frameTimeMs > HighFrameTimeLimit) + { + lineColor = ImGui::GetColorU32({1, 0, 0, 1}); // Red + } + else if (frameTimeMs > MediumFrameTimeLimit) + { + lineColor = ImGui::GetColorU32({1, .7, 0, 1}); // Orange + } + + drawList->AddLine(lineBottom, lineTop, lineColor, 3.0); + + lastFrameEndTick = frameEndTick; + } + + // Handle input + ImGui::InvisibleButton("HistogramInputCapture", { ImGui::GetWindowWidth(), ImGui::GetWindowHeight() }); + ImGuiIO& io = ImGui::GetIO(); + if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) + { + const float mousePixelX = io.MousePos.x; + const float percentWindow = (mousePixelX - wx) / ImGui::GetWindowWidth(); + const AZStd::sys_time_t newViewportCenterTick = leftHistogramBound + + aznumeric_cast((rightHistogramBound - leftHistogramBound) * percentWindow); + + const AZStd::sys_time_t viewportWidth = GetViewportTickWidth(); + m_viewportEndTick = newViewportCenterTick + viewportWidth / 2; + m_viewportStartTick = newViewportCenterTick - viewportWidth / 2; + } + } + inline AZStd::sys_time_t ImGuiCpuProfiler::GetViewportTickWidth() const { return m_viewportEndTick - m_viewportStartTick; } - inline float ImGuiCpuProfiler::ConvertTickToPixelSpace(AZStd::sys_time_t tick) const + inline float ImGuiCpuProfiler::ConvertTickToPixelSpace(AZStd::sys_time_t tick, AZStd::sys_time_t leftBound, AZStd::sys_time_t rightBound) const { const float wx = ImGui::GetWindowPos().x; - const float tickSpaceShifted = aznumeric_cast(tick - m_viewportStartTick); // This will be close to zero, so FP inaccuracy should not be too bad - const float tickSpaceNormalized = tickSpaceShifted / GetViewportTickWidth(); + const float tickSpaceShifted = aznumeric_cast(tick - leftBound); // This will be close to zero, so FP inaccuracy should not be too bad + const float tickSpaceNormalized = tickSpaceShifted / (rightBound - leftBound); const float pixelSpace = tickSpaceNormalized * ImGui::GetWindowWidth() + wx; return pixelSpace; } diff --git a/Gems/AudioEngineWwise/gem.json b/Gems/AudioEngineWwise/gem.json index dc5f968bc7..699ed8419a 100644 --- a/Gems/AudioEngineWwise/gem.json +++ b/Gems/AudioEngineWwise/gem.json @@ -8,5 +8,5 @@ "canonical_tags": ["Gem"], "user_tags": ["Audio", "Utility", "Tools"], "icon_path": "preview.png", - "requirements": "Users will need to download WWise from the AudioKinetic web site: https://www.audiokinetic.com/download/" + "requirements": "Users will need to download Wwise from the Audiokinetic web site: https://www.audiokinetic.com/download/" } diff --git a/Gems/EMotionFX/Code/CMakeLists.txt b/Gems/EMotionFX/Code/CMakeLists.txt index 5c38faf2a6..ed5447ba25 100644 --- a/Gems/EMotionFX/Code/CMakeLists.txt +++ b/Gems/EMotionFX/Code/CMakeLists.txt @@ -219,8 +219,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/AnimGraphExampleNoDependency.animgraph ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/EmptyAnimGraphExample.animgraph ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/EmptyMotionSetExample.motionset - ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph - ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/MotionSetExample.motionset ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/MotionSetExampleNoDependency.motionset OUTPUT_SUBDIRECTORY diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp index a04f6a327d..fdc4e4d0e5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp @@ -93,9 +93,7 @@ namespace CommandSystem } // load anim graph from file - EMotionFX::Importer::AnimGraphSettings settings; - settings.mDisableNodeVisualization = false; - EMotionFX::AnimGraph* animGraph = EMotionFX::GetImporter().LoadAnimGraph(filename.c_str(), &settings); + EMotionFX::AnimGraph* animGraph = EMotionFX::GetImporter().LoadAnimGraph(filename.c_str()); if (!animGraph) { outResult = AZStd::string::format("Failed to load anim graph from %s.", filename.c_str()); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp index 927ba67b76..cd81d81170 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp @@ -97,7 +97,7 @@ namespace EMotionFX AZ_UNUSED(sourceFile); AZ::ObjectStream::FilterDescriptor loadFilter = AZ::ObjectStream::FilterDescriptor(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES); - AZStd::unique_ptr animGraph(GetImporter().LoadAnimGraph(fullPath, nullptr, loadFilter)); + AZStd::unique_ptr animGraph(GetImporter().LoadAnimGraph(fullPath, loadFilter)); if (!animGraph) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h b/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h index 9514ffdb20..9f7b33a66d 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h @@ -79,9 +79,6 @@ namespace EMotionFX AttributePose(AnimGraphPose* pose) : MCore::Attribute(TYPE_ID) { mValue = pose; } ~AttributePose() {} - - uint32 GetDataSize() const override { return 0; } - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override { MCORE_UNUSED(stream); MCORE_UNUSED(streamEndianType); MCORE_UNUSED(version); return false; } // unsupported }; @@ -130,9 +127,6 @@ namespace EMotionFX AttributeMotionInstance(MotionInstance* motionInstance) : MCore::Attribute(TYPE_ID) { mValue = motionInstance; } ~AttributeMotionInstance() {} - - uint32 GetDataSize() const override { return 0; } - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override { MCORE_UNUSED(stream); MCORE_UNUSED(streamEndianType); MCORE_UNUSED(version); return false; } // unsupported }; class AnimGraphPropertyUtils diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp deleted file mode 100644 index f79057dfa8..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "AnimGraphFileFormat.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace EMotionFX -{ - namespace FileFormat - { - AZ::TypeId GetParameterTypeIdForInterfaceType(uint32 interfaceType) - { - switch (interfaceType) - { - case MCore::ATTRIBUTE_INTERFACETYPE_FLOATSPINNER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_FLOATSLIDER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_INTSPINNER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_INTSLIDER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_CHECKBOX: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR2: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3GIZMO: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR4: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_COLOR: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_STRING: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_TAG: - return azrtti_typeid(); - - case MCore::ATTRIBUTE_INTERFACETYPE_COMBOBOX: - case MCore::ATTRIBUTE_INTERFACETYPE_PROPERTYSET: - case MCore::ATTRIBUTE_INTERFACETYPE_DEFAULT: - default: - break; - } - return AZ::TypeId(); - } - - uint32 GetInterfaceTypeForParameterTypeId(const AZ::TypeId& parameterTypeId) - { - if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_FLOATSPINNER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_FLOATSLIDER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_INTSPINNER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_INTSLIDER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_CHECKBOX; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR2; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3GIZMO; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR4; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_COLOR; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_STRING; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_TAG; - } - return MCORE_INVALIDINDEX32; - } - } -} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h deleted file mode 100644 index 3b88c3605f..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "SharedFileFormatStructs.h" -#include "AzCore/RTTI/TypeInfo.h" - -namespace EMotionFX -{ - namespace FileFormat // so now we are in the namespace EMotionFX::FileFormat - { - // collection of animGraph chunk IDs - enum - { - ANIMGRAPH_CHUNK_BLENDNODE = 400, - ANIMGRAPH_CHUNK_STATETRANSITIONS = 401, - ANIMGRAPH_CHUNK_NODECONNECTIONS = 402, - ANIMGRAPH_CHUNK_PARAMETERS = 403, - ANIMGRAPH_CHUNK_NODEGROUPS = 404, - ANIMGRAPH_CHUNK_GROUPPARAMETERS = 405, - ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS = 406, - ANIMGRAPH_CHUNK_ADDITIONALINFO = 407, - ANIMGRAPH_FORCE_32BIT = 0xFFFFFFFF - }; - - enum - { - ANIMGRAPH_NODEFLAG_COLLAPSED = 1 << 0, - ANIMGRAPH_NODEFLAG_VISUALIZED = 1 << 1, - ANIMGRAPH_NODEFLAG_DISABLED = 1 << 2, - ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT = 1 << 3 - }; - - /* - AnimGraph_Header - - ANIMGRAPH_CHUNK_PARAMETERS: (global animgraph parameters) - uint32 numParameters - AnimGraph_ParamInfo[numParameters] - - ANIMGRAPH_CHUNK_BLENDNODE: - AnimGraph_NodeHeader - - ANIMGRAPH_CHUNK_NODECONNECTIONS: (for last loaded BLENDNODE) - uint32 numConnections - AnimGraph_NodeConnection[numConnections] - - ANIMGRAPH_CHUNK_STATETRANSITIONS: (for last loaded node, assumed to be a state machine) - uint32 numStateTransitions - uint32 blendNodeIndex (the state machine the transitions are for) - AnimGraph_StateTransition[numStateTransitions] - - ANIMGRAPH_CHUNK_NODEGROUPS: - uint32 numNodeGroups - AnimGraph_NodeGroup[numNodeGroups] - - ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS: - uint32 activePresetIndex - uint32 numPresets - AnimGraph_GameControllerPreset[numPresets] - */ - - // AnimGraph file header - struct AnimGraph_Header - { - char mFourCC[4]; - uint8 mEndianType; - uint32 mFileVersion; - uint32 mNumNodes; - uint32 mNumStateTransitions; - uint32 mNumNodeConnections; - uint32 mNumParameters; - - // followed by: - // string mName; - // string mCopyright; - // string mDescription; - // string mCompany; - // string mEMFXVersion; - // string mEMStudioBuildDate; - }; - - // additional info - struct AnimGraph_AdditionalInfo - { - uint8 mUnitType; - }; - - - // the node header - struct AnimGraph_NodeHeader - { - uint32 mTypeID; - uint32 mParentIndex; - uint32 mVersion; - uint32 mNumCustomDataBytes; // number of bytes of node custom data to follow - uint32 mNumChildNodes; - uint32 mNumAttributes; - int32 mVisualPosX; - int32 mVisualPosY; - uint32 mVisualizeColor; - uint8 mFlags; - - // followed by: - // string mName; - // animGraphNode->Save(...) or animGraphNode->Load(...), writing or reading mNumBytes bytes - }; - - - struct AnimGraph_ParameterInfo - { - uint32 mNumComboValues; - uint32 mInterfaceType; - uint32 mAttributeType; - uint16 mFlags; - char mHasMinMax; - - // followed by: - // string mName - // string mInternalName - // string mDescription - // if (mHasMinMax == 1) - // { - // AnimGraph_Attribute mMinValue - // AnimGraph_Attribute mMaxValue - // } - // AnimGraph_Attribute mDefaultValue - // string mComboValues[mNumComboValues] - }; - - - // a node connection - struct AnimGraph_NodeConnection - { - uint32 mSourceNode; - uint32 mTargetNode; - uint16 mSourceNodePort; - uint16 mTargetNodePort; - }; - - - // a state transition - struct AnimGraph_StateTransition - { - uint32 mSourceNode; - uint32 mDestNode; - int32 mStartOffsetX; - int32 mStartOffsetY; - int32 mEndOffsetX; - int32 mEndOffsetY; - uint32 mNumConditions; - - // followed by: - // AnimGraph_NodeHeader (and its followed by data, EXCEPT THE NAME STRING, which is skipped) - // AnimGraph_NodeHeader[mConditions] (and its followed by data, EXCEPT THE NAME STRING, which is skipped) - }; - - - // a node group - struct AnimGraph_NodeGroup - { - FileColor mColor; - uint8 mIsVisible; - uint32 mNumNodes; - - // followed by: - // string mName - // uint32[mNumNodes] (node indices that belong to the group) - }; - - - // a group parameter - struct AnimGraph_GroupParameter - { - uint32 mNumParameters; - uint8 mCollapsed; - - // followed by: - // string mName - // uint32[mNumParameters] (parameter indices that belong to the group) - }; - - - // a game controller parameter info - struct AnimGraph_GameControllerParameterInfo - { - uint8 mAxis; - uint8 mMode; - uint8 mInvert; - - // followed by: - // string mName - }; - - - // a game controller button info - struct AnimGraph_GameControllerButtonInfo - { - uint8 mButtonIndex; - uint8 mMode; - - // followed by: - // string mString - }; - - - // a game controller preset - struct AnimGraph_GameControllerPreset - { - uint32 mNumParameterInfos; - uint32 mNumButtonInfos; - - // followed by: - // string mName - // AnimGraph_GameControllerParameterInfo[mNumParameterInfos] - // AnimGraph_GameControllerButtonInfo[mNumButtonInfos] - }; - - // Conversion functions to support attributes with the old serialization. - // Once we deprecate the old format we can remove these two functions. - AZ::TypeId GetParameterTypeIdForInterfaceType(uint32 interfaceType); - uint32 GetInterfaceTypeForParameterTypeId(const AZ::TypeId& parameterTypeId); - - } // namespace FileFormat -} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp index 87ab61bf59..e1a3e0bbfa 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,6 @@ #include "../AnimGraphTransitionCondition.h" #include "../MCore/Source/Endian.h" #include "../NodeMap.h" -#include "LegacyAnimGraphNodeParser.h" #include #include @@ -245,14 +245,10 @@ namespace EMotionFX { mFileHighVersion = 1; mFileLowVersion = 0; - mIsUnicodeFile = true; // allocate the string buffer used for reading in variable sized strings mStringStorageSize = 256; mStringStorage = (char*)MCore::Allocate(mStringStorageSize, EMFX_MEMCATEGORY_IMPORTER); - mBlendNodes.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER); - mBlendNodes.Reserve(1024); - //mConvertString.Reserve( 256 ); } @@ -281,57 +277,8 @@ namespace EMotionFX mStringStorage = nullptr; mStringStorageSize = 0; - //mConvertString.Clear(); - - // get rid of the blend nodes array - mBlendNodes.Clear(); - - m_entryNodeIndexToStateMachineIdLookupTable.clear(); - } - - - // check if the strings in the file are encoded using unicode or multi-byte - bool SharedHelperData::GetIsUnicodeFile(const char* dateString, MCore::Array* sharedData) - { - // find the helper data - SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID); - SharedHelperData* helperData = static_cast(data); - - AZStd::vector dateParts; - AzFramework::StringFunc::Tokenize(dateString, dateParts, MCore::CharacterConstants::space, false /* keep empty strings */, true /* keep space strings */); - - // decode the month - int32 month = 0; - const AZStd::string& monthString = dateParts[0]; - const char* monthStrings[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - for (int32 i = 0; i < 12; ++i) - { - if (monthString == monthStrings[i]) - { - month = i + 1; - break; - } - } - - //int32 day = dateParts[1].ToInt(); - int32 year; - if (!AzFramework::StringFunc::LooksLikeInt(dateParts[2].c_str(), &year)) - { - return false; - } - - // set if the file contains unicode strings or not based on the compilcation date - if (year < 2012 || (year == 2012 && month < 11)) - { - helperData->mIsUnicodeFile = false; - } - - //LogInfo( "String: '%s', Decoded: %i.%i.%i - isUnicode=%i", dateString, day, month, year, helperData->mIsUnicodeFile ); - - return helperData->mIsUnicodeFile; } - const char* SharedHelperData::ReadString(MCore::Stream* file, MCore::Array* sharedData, MCore::Endian::EEndianType endianType) { MCORE_ASSERT(file); @@ -366,25 +313,6 @@ namespace EMotionFX return helperData->mStringStorage; } - - // get the array of anim graph nodes - MCore::Array& SharedHelperData::GetBlendNodes(MCore::Array* sharedData) - { - // find the helper data - SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID); - SharedHelperData* helperData = static_cast(data); - return helperData->mBlendNodes; - } - - // Get the table of entry state indices to state machines IDs - AZStd::map& SharedHelperData::GetEntryStateToStateMachineTable(MCore::Array* sharedData) - { - // Find the helper data - SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID); - SharedHelperData* helperData = static_cast(data); - return helperData->m_entryNodeIndexToStateMachineIdLookupTable; - } - //----------------------------------------------------------------------------- // constructor @@ -1999,7 +1927,6 @@ namespace EMotionFX //---------------------------------------------------------------------------------------------------------- - // bool ChunkProcessorActorAttachmentNodes::Process(MCore::File* file, Importer::ImportParameters& importParams) { const MCore::Endian::EEndianType endianType = importParams.mEndianType; @@ -2055,866 +1982,6 @@ namespace EMotionFX return true; } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph state transitions - bool ChunkProcessorAnimGraphStateTransitions::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - // read the number of transitions to follow - uint32 numTransitions; - file->Read(&numTransitions, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numTransitions, importParams.mEndianType); - - // read the state machine index - uint32 stateMachineIndex; - file->Read(&stateMachineIndex, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&stateMachineIndex, importParams.mEndianType); - - // get the loaded anim graph nodes - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - if (stateMachineIndex >= blendNodes.GetLength()) - { - if (GetLogging()) - { - AZ_Error("EMotionFX", false, "State machine refers to invalid blend node, state machine index: %d, amount of blend node: %d", stateMachineIndex, blendNodes.GetLength()); - } - return false; - } - AZ_Assert(azrtti_typeid(blendNodes[stateMachineIndex]) == azrtti_typeid(), "ChunkProcessorAnimGraphStateTransitions::Process : Unexpected node type expected AnimGraphStateMachine. Found %u instead", azrtti_typeid(blendNodes[stateMachineIndex])); - AnimGraphStateMachine* stateMachine = static_cast(blendNodes[stateMachineIndex]); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num transitions for state machine '%s' = %d", blendNodes[stateMachineIndex]->GetName(), numTransitions); - } - - stateMachine->ReserveTransitions(numTransitions); - - // read the transitions - FileFormat::AnimGraph_StateTransition transition; - for (uint32 i = 0; i < numTransitions; ++i) - { - // read the transition - file->Read(&transition, sizeof(FileFormat::AnimGraph_StateTransition)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&transition.mSourceNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&transition.mDestNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&transition.mNumConditions, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mStartOffsetX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mStartOffsetY, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mEndOffsetX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mEndOffsetY, importParams.mEndianType); - - //---------------------------------------------- - // read the node header - FileFormat::AnimGraph_NodeHeader nodeHeader; - file->Read(&nodeHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mParentIndex, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumChildNodes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumAttributes, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosY, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVisualizeColor, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- State Transition Node:"); - MCore::LogDetailedInfo(" + Type = %d", nodeHeader.mTypeID); - MCore::LogDetailedInfo(" + Version = %d", nodeHeader.mVersion); - MCore::LogDetailedInfo(" + Num data bytes = %d", nodeHeader.mNumCustomDataBytes); - MCore::LogDetailedInfo(" + Num attributes = %d", nodeHeader.mNumAttributes); - MCore::LogDetailedInfo(" + Num conditions = %d", transition.mNumConditions); - MCore::LogDetailedInfo(" + Source node = %d", transition.mSourceNode); - MCore::LogDetailedInfo(" + Dest node = %d", transition.mDestNode); - } - - // create the transition object - AnimGraphStateTransition* emfxTransition = nullptr; - if (GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID) == azrtti_typeid()) - { - emfxTransition = aznew AnimGraphStateTransition(); - } - - if (emfxTransition) - { - if (transition.mDestNode >= blendNodes.GetLength()) - { - if (GetLogging()) - { - AZ_Error("EMotionFX", false, "State machine transition refers to invalid destination blend node, transition index %d, blend node: %d", i, transition.mDestNode); - } - delete emfxTransition; - emfxTransition = nullptr; - } - // A source node index of MCORE_INVALIDINDEX32 indicates that the transition is a wildcard transition. Don't go into error state in this case. - else if (transition.mSourceNode != MCORE_INVALIDINDEX32 && transition.mSourceNode >= blendNodes.GetLength()) - { - if (GetLogging()) - { - AZ_Error("EMotionFX", false, "State machine transition refers to invalid source blend node, transition index %d, blend node: %d", i, transition.mSourceNode); - } - delete emfxTransition; - emfxTransition = nullptr; - } - else - { - AnimGraphNode* targetNode = blendNodes[transition.mDestNode]; - if (targetNode == nullptr) - { - delete emfxTransition; - emfxTransition = nullptr; - } - else - { - AZ_Assert(azrtti_istypeof(emfxTransition), "ChunkProcessorAnimGraphStateTransitions::Process : Unexpected node type expected AnimGraphStateTransition. Found %u instead", azrtti_typeid(blendNodes[stateMachineIndex])); - - // Now apply the transition settings - // Check if we are dealing with a wildcard transition - if (transition.mSourceNode == MCORE_INVALIDINDEX32) - { - emfxTransition->SetSourceNode(nullptr); - emfxTransition->SetIsWildcardTransition(true); - } - else - { - // set the source node - emfxTransition->SetSourceNode(blendNodes[transition.mSourceNode]); - } - - // set the destination node - emfxTransition->SetTargetNode(targetNode); - - emfxTransition->SetVisualOffsets(transition.mStartOffsetX, transition.mStartOffsetY, transition.mEndOffsetX, transition.mEndOffsetY); - - // now read the attributes - if (!LegacyAnimGraphNodeParser::ParseLegacyAttributes(file, nodeHeader.mNumAttributes, importParams.mEndianType, importParams, *emfxTransition)) - { - delete emfxTransition; - emfxTransition = nullptr; - AZ_Error("EMotionFX", false, "Unable to parse state transition"); - return false; - } - // add the transition to the state machine - stateMachine->AddTransition(emfxTransition); - } - } - } - - if (emfxTransition) - { - // iterate through all conditions - for (uint32 c = 0; c < transition.mNumConditions; ++c) - { - // read the condition node header - FileFormat::AnimGraph_NodeHeader conditionHeader; - file->Read(&conditionHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumAttributes, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo(" - Transition Condition:"); - MCore::LogDetailedInfo(" + Type = %d", conditionHeader.mTypeID); - MCore::LogDetailedInfo(" + Version = %d", conditionHeader.mVersion); - MCore::LogDetailedInfo(" + Num data bytes = %d", conditionHeader.mNumCustomDataBytes); - MCore::LogDetailedInfo(" + Num attributes = %d", conditionHeader.mNumAttributes); - } - - AnimGraphTransitionCondition* emfxCondition = nullptr; - if (!LegacyAnimGraphNodeParser::ParseTransitionConditionChunk(file, importParams, conditionHeader, emfxCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse Transition condition of type %u in legacy file", azrtti_typeid(emfxCondition)); - delete emfxCondition; - emfxCondition = nullptr; - return false; - } - // add the condition to the transition - emfxTransition->AddCondition(emfxCondition); - } - - //emfxTransition->Init( animGraph ); - } - // something went wrong with creating the transition - else - { - MCore::LogWarning("Cannot load and instantiate state transition. State transition from %d to %d will be skipped.", transition.mSourceNode, transition.mDestNode); - - // skip reading the attributes - if (!ForwardAttributes(file, importParams.mEndianType, nodeHeader.mNumAttributes)) - { - return false; - } - - // skip reading the node custom data - if (file->Forward(nodeHeader.mNumCustomDataBytes) == false) - { - return false; - } - - // iterate through all conditions and skip them as well - for (uint32 c = 0; c < transition.mNumConditions; ++c) - { - // read the condition node header - FileFormat::AnimGraph_NodeHeader conditionHeader; - file->Read(&conditionHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumAttributes, importParams.mEndianType); - - // skip reading the attributes - if (!ForwardAttributes(file, importParams.mEndianType, conditionHeader.mNumAttributes)) - { - return false; - } - - // skip reading the node custom data - if (file->Forward(conditionHeader.mNumCustomDataBytes) == false) - { - return false; - } - } - } - } - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph state transitions - bool ChunkProcessorAnimGraphAdditionalInfo::Process(MCore::File* file, Importer::ImportParameters& /*importParams*/) - { - return file->Forward(sizeof(FileFormat::AnimGraph_AdditionalInfo)); - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph node connections - bool ChunkProcessorAnimGraphNodeConnections::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - // read the number of transitions to follow - uint32 numConnections; - file->Read(&numConnections, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numConnections, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num node connections = %d", numConnections); - } - - // get the array of currently loaded nodes - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - - // read the connections - FileFormat::AnimGraph_NodeConnection connection; - for (uint32 i = 0; i < numConnections; ++i) - { - // read the transition - file->Read(&connection, sizeof(FileFormat::AnimGraph_NodeConnection)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&connection.mSourceNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&connection.mTargetNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt16(&connection.mSourceNodePort, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt16(&connection.mTargetNodePort, importParams.mEndianType); - - // log details - if (GetLogging()) - { - MCore::LogDetailedInfo(" + Connection #%d = From node %d (port id %d) into node %d (port id %d)", i, connection.mSourceNode, connection.mSourceNodePort, connection.mTargetNode, connection.mTargetNodePort); - } - - // get the source and the target node and check if they are valid - AnimGraphNode* sourceNode = blendNodes[connection.mSourceNode]; - AnimGraphNode* targetNode = blendNodes[connection.mTargetNode]; - if (sourceNode == nullptr || targetNode == nullptr) - { - MCore::LogWarning("EMotionFX::ChunkProcessorAnimGraphNodeConnections() - Connection cannot be created because the source or target node is invalid! (sourcePortID=%d targetPortID=%d sourceNode=%d targetNode=%d)", connection.mSourceNodePort, connection.mTargetNodePort, connection.mSourceNode, connection.mTargetNode); - continue; - } - - // create the connection - const uint32 sourcePort = blendNodes[connection.mSourceNode]->FindOutputPortByID(connection.mSourceNodePort); - const uint32 targetPort = blendNodes[connection.mTargetNode]->FindInputPortByID(connection.mTargetNodePort); - if (sourcePort != MCORE_INVALIDINDEX32 && targetPort != MCORE_INVALIDINDEX32) - { - blendNodes[connection.mTargetNode]->AddConnection(blendNodes[connection.mSourceNode], static_cast(sourcePort), static_cast(targetPort)); - } - else - { - MCore::LogWarning("EMotionFX::ChunkProcessorAnimGraphNodeConnections() - Connection cannot be created because the source or target port doesn't exist! (sourcePortID=%d targetPortID=%d sourceNode='%s' targetNode=%s')", connection.mSourceNodePort, connection.mTargetNodePort, blendNodes[connection.mSourceNode]->GetName(), blendNodes[connection.mTargetNode]->GetName()); - } - } - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph node - bool ChunkProcessorAnimGraphNode::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the node header - FileFormat::AnimGraph_NodeHeader nodeHeader; - file->Read(&nodeHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mParentIndex, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumChildNodes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumAttributes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVisualizeColor, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosY, importParams.mEndianType); - - const char* nodeName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - if (GetLogging()) - { - MCore::LogDetailedInfo("- Blend Node:"); - MCore::LogDetailedInfo(" + Name = %s", nodeName); - MCore::LogDetailedInfo(" + Parent index = %d", nodeHeader.mParentIndex); - MCore::LogDetailedInfo(" + Type = %d", nodeHeader.mTypeID); - MCore::LogDetailedInfo(" + Version = %d", nodeHeader.mVersion); - MCore::LogDetailedInfo(" + Num data bytes = %d", nodeHeader.mNumCustomDataBytes); - MCore::LogDetailedInfo(" + Num child nodes = %d", nodeHeader.mNumChildNodes); - MCore::LogDetailedInfo(" + Num attributes = %d", nodeHeader.mNumAttributes); - MCore::LogDetailedInfo(" + Visualize Color = %d, %d, %d", MCore::ExtractRed(nodeHeader.mVisualizeColor), MCore::ExtractGreen(nodeHeader.mVisualizeColor), MCore::ExtractBlue(nodeHeader.mVisualizeColor)); - MCore::LogDetailedInfo(" + Visual pos = (%d, %d)", nodeHeader.mVisualPosX, nodeHeader.mVisualPosY); - MCore::LogDetailedInfo(" + Collapsed = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_COLLAPSED) ? "Yes" : "No"); - MCore::LogDetailedInfo(" + Visualized = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VISUALIZED) ? "Yes" : "No"); - MCore::LogDetailedInfo(" + Disabled = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_DISABLED) ? "Yes" : "No"); - MCore::LogDetailedInfo(" + Virtual FinalOut= %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT) ? "Yes" : "No"); - } - - AnimGraphNode* node = nullptr; - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNodeChunk(file - , importParams - , nodeName - , nodeHeader - , node)) - { - if (importParams.mAnimGraph->GetRootStateMachine() == node) - { - importParams.mAnimGraph->SetRootStateMachine(nullptr); - } - - if (node) - { - AnimGraphNode* parentNode = node->GetParentNode(); - if (parentNode) - { - parentNode->RemoveChildNodeByPointer(node, false); - } - } - - delete node; - node = nullptr; - return false; - } - - EMotionFX::GetEventManager().OnCreatedNode(animGraph, node); - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph parameters - bool ChunkProcessorAnimGraphParameters::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the number of parameters - uint32 numParams; - file->Read(&numParams, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numParams, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num parameters = %d", numParams); - } - - // read all parameters - for (uint32 p = 0; p < numParams; ++p) - { - // read the parameter info header - FileFormat::AnimGraph_ParameterInfo paramInfo; - file->Read(¶mInfo, sizeof(FileFormat::AnimGraph_ParameterInfo)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(¶mInfo.mNumComboValues, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(¶mInfo.mInterfaceType, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(¶mInfo.mAttributeType, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt16(¶mInfo.mFlags, importParams.mEndianType); - - // check the attribute type - const uint32 attribType = paramInfo.mAttributeType; - if (attribType == 0) - { - MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to convert interface type %d to an attribute type.", attribType); - return false; - } - - const AZ::TypeId parameterTypeId = EMotionFX::FileFormat::GetParameterTypeIdForInterfaceType(paramInfo.mInterfaceType); - const AZStd::string name = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - AZStd::unique_ptr newParam(EMotionFX::ParameterFactory::Create(parameterTypeId)); - AZ_Assert(azrtti_istypeof(newParam.get()), "Expected a value parameter"); - - if (!newParam) - { - MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to create parameter: '%s'.", name.c_str()); - return false; - } - - // read the strings - newParam->SetName(name); - SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); // We dont use internal name anymore - newParam->SetDescription(SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType)); - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Parameter #%d:", p); - MCore::LogDetailedInfo(" + Name = %s", newParam->GetName().c_str()); - MCore::LogDetailedInfo(" + Description = %s", newParam->GetDescription().c_str()); - MCore::LogDetailedInfo(" + type = %s", newParam->RTTI_GetTypeName()); - MCore::LogDetailedInfo(" + Attribute type = %d", paramInfo.mAttributeType); - MCore::LogDetailedInfo(" + Has MinMax = %d", paramInfo.mHasMinMax); - MCore::LogDetailedInfo(" + Flags = %d", paramInfo.mFlags); - } - - MCore::Attribute* attr(MCore::GetAttributeFactory().CreateAttributeByType(attribType)); - EMotionFX::ValueParameter* valueParameter = static_cast(newParam.get()); - - // create the min, max and default value attributes - if (paramInfo.mHasMinMax == 1) - { - // min value - attr->Read(file, importParams.mEndianType); - valueParameter->SetMinValueFromAttribute(attr); - - // max value - attr->Read(file, importParams.mEndianType); - valueParameter->SetMaxValueFromAttribute(attr); - } - - // default value - attr->Read(file, importParams.mEndianType); - valueParameter->SetDefaultValueFromAttribute(attr); - delete attr; - - // Parameters were previously stored in "AttributeSettings". The calss supported - // multiple values, however, the UI did not, so this ended up not being used. - // Support for multiple values in parameters is possible, however we dont need it now. - // Leaving this code as reference - for (uint32 i = 0; i < paramInfo.mNumComboValues; ++i) - { - SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - } - - if (!animGraph->AddParameter(newParam.get())) - { - MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to add parameter: '%s'.", name.c_str()); - return false; - } - newParam.release(); // ownership moved to animGraph - } - - return true; - } - - - // animGraph node groups - bool ChunkProcessorAnimGraphNodeGroups::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the number of node groups - uint32 numNodeGroups; - file->Read(&numNodeGroups, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numNodeGroups, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num Node Groups = %d", numNodeGroups); - } - - // read all node groups - for (uint32 g = 0; g < numNodeGroups; ++g) - { - // read the node group header - FileFormat::AnimGraph_NodeGroup nodeGroupChunk; - file->Read(&nodeGroupChunk, sizeof(FileFormat::AnimGraph_NodeGroup)); - - MCore::RGBAColor emfxColor(nodeGroupChunk.mColor.mR, nodeGroupChunk.mColor.mG, nodeGroupChunk.mColor.mB, nodeGroupChunk.mColor.mA); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&nodeGroupChunk.mNumNodes, importParams.mEndianType); - MCore::Endian::ConvertRGBAColor(&emfxColor, importParams.mEndianType); - - const AZ::Color color128 = MCore::EmfxColorToAzColor(emfxColor); - const AZ::u32 color32 = color128.ToU32(); - - const char* groupName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - const uint32 numNodes = nodeGroupChunk.mNumNodes; - - // create and fill the new node group - AnimGraphNodeGroup* nodeGroup = aznew AnimGraphNodeGroup(groupName); - animGraph->AddNodeGroup(nodeGroup); - nodeGroup->SetIsVisible(nodeGroupChunk.mIsVisible != 0); - nodeGroup->SetColor(color32); - - // set the nodes of the node group - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - nodeGroup->SetNumNodes(numNodes); - for (uint32 i = 0; i < numNodes; ++i) - { - // read the node index of the current node inside the group - uint32 nodeNr; - file->Read(&nodeNr, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&nodeNr, importParams.mEndianType); - - MCORE_ASSERT(nodeNr != MCORE_INVALIDINDEX32); - - // set the id of the given node to the group - if (nodeNr != MCORE_INVALIDINDEX32 && blendNodes[nodeNr]) - { - nodeGroup->SetNode(i, blendNodes[nodeNr]->GetId()); - } - else - { - nodeGroup->SetNode(i, AnimGraphNodeId::InvalidId); - } - } - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Node Group #%d:", g); - MCore::LogDetailedInfo(" + Name = %s", nodeGroup->GetName()); - MCore::LogDetailedInfo(" + Color = (%.2f, %.2f, %.2f, %.2f)", static_cast(color128.GetR()), static_cast(color128.GetG()), static_cast(color128.GetB()), static_cast(color128.GetA())); - MCore::LogDetailedInfo(" + Num Nodes = %i", nodeGroup->GetNumNodes()); - } - } - - return true; - } - - - // animGraph group parameters - bool ChunkProcessorAnimGraphGroupParameters::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the number of group parameters - uint32 numGroupParameters; - file->Read(&numGroupParameters, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numGroupParameters, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num group parameters = %d", numGroupParameters); - } - - // Group parameters is going to re-shuffle the value parameter indices, therefore we - // need to update the connections downstream of parameter nodes. - EMotionFX::ValueParameterVector valueParametersBeforeChange = animGraph->RecursivelyGetValueParameters(); - - // Since relocating a parameter to another parent changes its index, we are going to - // compute all the relationships leaving the value parameters at the root, then relocate - // them. - AZStd::vector > parametersByGroup; - - // read all group parameters - for (uint32 g = 0; g < numGroupParameters; ++g) - { - // read the group parameter header - FileFormat::AnimGraph_GroupParameter groupChunk; - file->Read(&groupChunk, sizeof(FileFormat::AnimGraph_GroupParameter)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&groupChunk.mNumParameters, importParams.mEndianType); - - const char* groupName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - const uint32 numParameters = groupChunk.mNumParameters; - - // create and fill the new group parameter - AZStd::unique_ptr parameter(EMotionFX::ParameterFactory::Create(azrtti_typeid())); - parameter->SetName(groupName); - - // Previously collapsed/expanded state in group parameters was stored in the animgraph file. However, that - // would require to check out the animgraph file if you expand/collapse a group. Because this change was not - // done through commands, the dirty state was not properly restored. - // Collapsing state should be more of a setting per-user than something saved in the animgraph - //groupParameter->SetIsCollapsed(groupChunk.mCollapsed != 0); - - if (!animGraph->AddParameter(parameter.get())) - { - continue; - } - const EMotionFX::GroupParameter* groupParameter = static_cast(parameter.release()); - - parametersByGroup.emplace_back(groupParameter, EMotionFX::ParameterVector()); - AZStd::vector& parametersInGroup = parametersByGroup.back().second; - - // set the parameters of the group parameter - for (uint32 i = 0; i < numParameters; ++i) - { - // read the parameter index - uint32 parameterIndex; - file->Read(¶meterIndex, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(¶meterIndex, importParams.mEndianType); - - MCORE_ASSERT(parameterIndex != MCORE_INVALIDINDEX32); - if (parameterIndex != MCORE_INVALIDINDEX32) - { - const EMotionFX::Parameter* childParameter = animGraph->FindValueParameter(parameterIndex); - parametersInGroup.emplace_back(const_cast(childParameter)); - } - } - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Group parameter #%d:", g); - MCore::LogDetailedInfo(" + Name = %s", groupParameter->GetName().c_str()); - MCore::LogDetailedInfo(" + Num Parameters = %i", groupParameter->GetNumParameters()); - } - } - - // Now move the parameters to their groups - for (const AZStd::pair& groupAndParameters : parametersByGroup) - { - const EMotionFX::GroupParameter* groupParameter = groupAndParameters.first; - for (EMotionFX::Parameter* parameter : groupAndParameters.second) - { - animGraph->TakeParameterFromParent(parameter); - animGraph->AddParameter(const_cast(parameter), groupParameter); - } - } - - const EMotionFX::ValueParameterVector valueParametersAfterChange = animGraph->RecursivelyGetValueParameters(); - - AZStd::vector affectedObjects; - animGraph->RecursiveCollectObjectsOfType(azrtti_typeid(), affectedObjects); - - for (EMotionFX::AnimGraphObject* affectedObject : affectedObjects) - { - EMotionFX::ObjectAffectedByParameterChanges* affectedObjectByParameterChanges = azdynamic_cast(affectedObject); - affectedObjectByParameterChanges->ParameterOrderChanged(valueParametersBeforeChange, valueParametersAfterChange); - } - - return true; - } - - - // animGraph game controller settings - bool ChunkProcessorAnimGraphGameControllerSettings::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - uint32 i; - - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // get the game controller settings for the anim graph and clear it - AnimGraphGameControllerSettings& gameControllerSettings = animGraph->GetGameControllerSettings(); - gameControllerSettings.Clear(); - - // read the number of presets and the active preset index - uint32 activePresetIndex, numPresets; - file->Read(&activePresetIndex, sizeof(uint32)); - file->Read(&numPresets, sizeof(uint32)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&activePresetIndex, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&numPresets, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Game Controller Settings (NumPresets=%d, ActivePreset=%d)", numPresets, activePresetIndex); - } - - // preallocate memory for the presets - gameControllerSettings.SetNumPresets(numPresets); - - // read all presets - for (uint32 p = 0; p < numPresets; ++p) - { - // read the preset chunk - FileFormat::AnimGraph_GameControllerPreset presetChunk; - file->Read(&presetChunk, sizeof(FileFormat::AnimGraph_GameControllerPreset)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&presetChunk.mNumParameterInfos, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&presetChunk.mNumButtonInfos, importParams.mEndianType); - - // read the preset name and get the number of parameter and button infos - const char* presetName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - const uint32 numParamInfos = presetChunk.mNumParameterInfos; - const uint32 numButtonInfos = presetChunk.mNumButtonInfos; - - // create and fill the new preset - AnimGraphGameControllerSettings::Preset* preset = aznew AnimGraphGameControllerSettings::Preset(presetName); - gameControllerSettings.SetPreset(p, preset); - - // read the parameter infos - preset->SetNumParamInfos(numParamInfos); - for (i = 0; i < numParamInfos; ++i) - { - // read the parameter info chunk - FileFormat::AnimGraph_GameControllerParameterInfo paramInfoChunk; - file->Read(¶mInfoChunk, sizeof(FileFormat::AnimGraph_GameControllerParameterInfo)); - - // read the parameter name - const char* parameterName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - - // construct and fill the parameter info - AnimGraphGameControllerSettings::ParameterInfo* parameterInfo = aznew AnimGraphGameControllerSettings::ParameterInfo(parameterName); - parameterInfo->m_axis = paramInfoChunk.mAxis; - parameterInfo->m_invert = (paramInfoChunk.mInvert != 0); - parameterInfo->m_mode = (AnimGraphGameControllerSettings::ParameterMode)paramInfoChunk.mMode; - - preset->SetParamInfo(i, parameterInfo); - } - - // read the button infos - preset->SetNumButtonInfos(numButtonInfos); - for (i = 0; i < numButtonInfos; ++i) - { - // read the button info chunk - FileFormat::AnimGraph_GameControllerButtonInfo buttonInfoChunk; - file->Read(&buttonInfoChunk, sizeof(FileFormat::AnimGraph_GameControllerButtonInfo)); - - // read the button string - const char* buttonString = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - - // construct and fill the button info - AnimGraphGameControllerSettings::ButtonInfo* buttonInfo = aznew AnimGraphGameControllerSettings::ButtonInfo(buttonInfoChunk.mButtonIndex); - buttonInfo->m_mode = (AnimGraphGameControllerSettings::ButtonMode)buttonInfoChunk.mMode; - buttonInfo->m_string = buttonString; - - preset->SetButtonInfo(i, buttonInfo); - } - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Preset '%s':", preset->GetName()); - MCore::LogDetailedInfo(" + Num Param Infos = %d", preset->GetNumParamInfos()); - MCore::LogDetailedInfo(" + Num Button Infos = %d", preset->GetNumButtonInfos()); - } - } - - // set the active preset - if (activePresetIndex != MCORE_INVALIDINDEX32) - { - AnimGraphGameControllerSettings::Preset* activePreset = gameControllerSettings.GetPreset(activePresetIndex); - gameControllerSettings.SetActivePreset(activePreset); - } - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - // MotionSet - //---------------------------------------------------------------------------------------------------------- - - // all submotions in one chunk - bool ChunkProcessorMotionSet::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - const MCore::Endian::EEndianType endianType = importParams.mEndianType; - - FileFormat::MotionSetsChunk motionSetsChunk; - file->Read(&motionSetsChunk, sizeof(FileFormat::MotionSetsChunk)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&motionSetsChunk.mNumSets, endianType); - - // get the number of motion sets and iterate through them - const uint32 numMotionSets = motionSetsChunk.mNumSets; - for (uint32 i = 0; i < numMotionSets; ++i) - { - FileFormat::MotionSetChunk motionSetChunk; - file->Read(&motionSetChunk, sizeof(FileFormat::MotionSetChunk)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&motionSetChunk.mNumChildSets, endianType); - MCore::Endian::ConvertUnsignedInt32(&motionSetChunk.mNumMotionEntries, endianType); - - // get the parent set - const char* parentSetName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - GetMotionManager().Lock(); - MotionSet* parentSet = GetMotionManager().FindMotionSetByName(parentSetName, importParams.m_isOwnedByRuntime); - GetMotionManager().Unlock(); - - // read the motion set name and create our new motion set - const char* motionSetName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - MotionSet* motionSet = aznew MotionSet(motionSetName, parentSet); - motionSet->SetIsOwnedByRuntime(importParams.m_isOwnedByRuntime); - - // set the root motion set to the importer params motion set, this will be returned by the Importer::LoadMotionSet() function - if (parentSet == nullptr) - { - assert(importParams.mMotionSet == nullptr); - importParams.mMotionSet = motionSet; - } - - // read the filename and set it - /*const char* motionSetFileName = */ SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - //motionSet->SetFileName( motionSetFileName ); - - // in case this is not a root motion set add the new motion set as child set to the parent set - if (parentSet) - { - parentSet->AddChildSet(motionSet); - } - - // Read all motion entries. - const uint32 numMotionEntries = motionSetChunk.mNumMotionEntries; - motionSet->ReserveMotionEntries(numMotionEntries); - AZStd::string nativeMotionFileName; - for (uint32 j = 0; j < numMotionEntries; ++j) - { - // read the motion entry - const char* motionFileName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - nativeMotionFileName = motionFileName; - - // read the string id and set it - const char* motionStringID = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - - // add the motion entry to the motion set - MotionSet::MotionEntry* motionEntry = aznew MotionSet::MotionEntry(nativeMotionFileName.c_str(), motionStringID); - motionSet->AddMotionEntry(motionEntry); - } - } - - return true; - } - - - //---------------------------------------------------------------------------------------------------------- // NodeMap //---------------------------------------------------------------------------------------------------------- diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h index 3d0412eb3f..306e4af0c8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h @@ -16,8 +16,6 @@ #include "SharedFileFormatStructs.h" #include "ActorFileFormat.h" #include "MotionFileFormat.h" -#include "AnimGraphFileFormat.h" -#include "MotionSetFileFormat.h" #include "NodeMapFileFormat.h" #include "Importer.h" #include @@ -32,7 +30,6 @@ namespace EMotionFX class Importer; class AnimGraphNode; - /** * Shared importer data class. * Chunks can load data, which might be shared between other chunks during import. @@ -57,20 +54,11 @@ namespace EMotionFX virtual void Reset() {} protected: - /** - * The constructor. - */ SharedData() : BaseObject() {} - - /** - * The destructor. - */ virtual ~SharedData() { Reset(); } }; - - /** * Helper class for reading strings from files and file information storage. */ @@ -108,34 +96,12 @@ namespace EMotionFX */ static const char* ReadString(MCore::Stream* file, MCore::Array* sharedData, MCore::Endian::EEndianType endianType); - /** - * Get the array of currently loaded anim graph nodes. - * @param sharedData The array which holds the shared data objects. - * @result The array of currently loaded anim graph nodes. - */ - static MCore::Array& GetBlendNodes(MCore::Array* sharedData); - - /** - * Get the table to look up a state machine that needs an entry state as they are created. - * @param sharedData The array which holds the shared data objects. - * @result The map whose keys are the indices of entry states and the values are the IDs of the state machines that need those as entry states. - */ - static AZStd::map& GetEntryStateToStateMachineTable(MCore::Array* sharedData); - - /** - * Checks if the strings in the file are encoded using unicode or multi-byte based on the exporter date. - * The first official EMotion FX version to use unicode was compiled on 26th November 2012. - */ - static bool GetIsUnicodeFile(const char* dateString, MCore::Array* sharedData); - public: uint32 mFileHighVersion; /**< The high file version. For example 3 in case of v3.10. */ uint32 mFileLowVersion; /**< The low file version. For example 10 in case of v3.10. */ uint32 mStringStorageSize; /**< The size of the string buffer. */ bool mIsUnicodeFile; /**< True in case strings in the file are saved using unicode character set, false in case they are saved using multi-byte. */ char* mStringStorage; /**< The shared string buffer. */ - MCore::Array mBlendNodes; /**< Array of read anim graph nodes. */ - AZStd::map m_entryNodeIndexToStateMachineIdLookupTable; protected: /** * The constructor. @@ -338,22 +304,6 @@ namespace EMotionFX EMFX_CHUNKPROCESSOR(ChunkProcessorMotionMorphSubMotions, FileFormat::MOTION_CHUNK_MORPHSUBMOTIONS, 1) EMFX_CHUNKPROCESSOR(ChunkProcessorMotionData, FileFormat::MOTION_CHUNK_MOTIONDATA, 1) - // Anim graph file format chunk processors - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphStateTransitions, FileFormat::ANIMGRAPH_CHUNK_STATETRANSITIONS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNodeConnections, FileFormat::ANIMGRAPH_CHUNK_NODECONNECTIONS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphParameters, FileFormat::ANIMGRAPH_CHUNK_PARAMETERS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNodeGroups, FileFormat::ANIMGRAPH_CHUNK_NODEGROUPS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphGroupParameters, FileFormat::ANIMGRAPH_CHUNK_GROUPPARAMETERS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphGameControllerSettings, FileFormat::ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNode, FileFormat::ANIMGRAPH_CHUNK_BLENDNODE, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphAdditionalInfo, FileFormat::ANIMGRAPH_CHUNK_ADDITIONALINFO, 1) - - // motion set file format chunk processors - EMFX_CHUNKPROCESSOR(ChunkProcessorMotionSet, FileFormat::CHUNK_MOTIONSET, 1) - // node map file format chunk processors EMFX_CHUNKPROCESSOR(ChunkProcessorNodeMap, FileFormat::CHUNK_NODEMAP, 1) - - - //------------------------------------------------------------------------------------------------- } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp index 6ac4493275..67cbb91c06 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp @@ -156,85 +156,6 @@ namespace EMotionFX return true; } - - // check if we can process the given motion set file - bool Importer::CheckIfIsValidMotionSetFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const - { - MCORE_ASSERT(f->GetIsOpen()); - - // verify if we actually are dealing with a valid actor file - FileFormat::MotionSet_Header header; - if (f->Read(&header, sizeof(FileFormat::MotionSet_Header)) == 0) - { - MCore::LogError("Failed to read the motion set file header!"); - return false; - } - - // check the FOURCC - if (header.mFourCC[0] != 'M' || header.mFourCC[1] != 'O' || header.mFourCC[2] != 'S' || header.mFourCC[3] != ' ') - { - return false; - } - - // read the chunks - switch (header.mEndianType) - { - case 0: - *outEndianType = MCore::Endian::ENDIAN_LITTLE; - break; - case 1: - *outEndianType = MCore::Endian::ENDIAN_BIG; - break; - default: - MCore::LogError("Unsupported endian type used! (endian type = %d)", header.mEndianType); - return false; - } - ; - - // yes, it is a valid motionset file! - return true; - } - - - - // check if we can process the given anim graph file - bool Importer::CheckIfIsValidAnimGraphFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const - { - MCORE_ASSERT(f->GetIsOpen()); - - // verify if we actually are dealing with a valid actor file - FileFormat::AnimGraph_Header header; - if (f->Read(&header, sizeof(FileFormat::AnimGraph_Header)) == 0) - { - return false; - } - - // check the FOURCC - if (header.mFourCC[0] != 'A' || header.mFourCC[1] != 'N' || header.mFourCC[2] != 'G' || header.mFourCC[3] != 'R') - { - return false; - } - - // read the chunks - switch (header.mEndianType) - { - case 0: - *outEndianType = MCore::Endian::ENDIAN_LITTLE; - break; - case 1: - *outEndianType = MCore::Endian::ENDIAN_BIG; - break; - default: - MCore::LogError("Unsupported endian type used! (endian type = %d)", header.mEndianType); - return false; - } - ; - - // yes, it is a valid anim graph file! - return true; - } - - // check if we can process the given node map file bool Importer::CheckIfIsValidNodeMapFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const { @@ -599,125 +520,32 @@ namespace EMotionFX //------------------------------------------------------------------------------------------------- - // try to load a motion set from disk MotionSet* Importer::LoadMotionSet(AZStd::string filename, MotionSetSettings* settings, const AZ::ObjectStream::FilterDescriptor& loadFilter) { EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePathKeepCase, filename); - const bool isLegacyFile = Importer::CheckFileType(filename.c_str()) == Importer::EFileType::FILETYPE_MOTIONSET; - if (!isLegacyFile) - { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - if (!context) - { - AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); - return nullptr; - } - - EMotionFX::MotionSet* motionSet = EMotionFX::MotionSet::LoadFromFile(filename, context, loadFilter); - if (motionSet) - { - motionSet->SetFilename(filename.c_str()); - } - return motionSet; - } - - ////////////////////////////////////////// - // Legacy file type loading - ////////////////////////////////////////// - - // check if we want to load the motion set even if a motion set with the given filename is already inside the motion manager - if (settings == nullptr || settings->mForceLoading == false) - { - // search the motion set inside the motion manager and return it if it already got loaded - MotionSet* motionSet = GetMotionManager().FindMotionSetByFileName(filename.c_str()); - if (motionSet) - { - MCore::LogInfo(" + Motion set '%s' already loaded, returning already loaded motion set from the MotionManager.", filename.c_str()); - return motionSet; - } - } - - if (GetLogging()) - { - MCore::LogInfo("- Trying to load motion set from file '%s'...", filename.c_str()); - } - - // try to open the file from disk - MCore::DiskFile f; - if (f.Open(filename.c_str(), MCore::DiskFile::READ) == false) + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!context) { - if (GetLogging()) - { - MCore::LogError(" + Failed to open the file for motion set."); - } + AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); return nullptr; } - // retrieve the filesize - const size_t fileSize = f.GetFileSize(); - - // create a temporary buffer for the file - uint8* fileBuffer = (uint8*)MCore::Allocate(fileSize, EMFX_MEMCATEGORY_IMPORTER); - - // read in the complete file - f.Read(fileBuffer, fileSize); - - // close the file again - f.Close(); - - // create the motion set reading from memory - MotionSet* result = LoadMotionSet(fileBuffer, fileSize, settings); - if (result) + EMotionFX::MotionSet* motionSet = EMotionFX::MotionSet::LoadFromFile(filename, context, loadFilter); + if (motionSet) { - result->SetFilename(filename.c_str()); - } - - // delete the filebuffer again - MCore::Free(fileBuffer); - - // check if it worked :) - if (result == nullptr) - { - if (GetLogging()) - { - MCore::LogError(" + Failed to load motion set from file '%s'.", filename.c_str()); - } - } - else - { - if (GetLogging()) + motionSet->SetFilename(filename.c_str()); + if (settings) { - MCore::LogInfo(" + Loading successfully finished."); + motionSet->SetIsOwnedByRuntime(settings->m_isOwnedByRuntime); } } - - // return the result - return result; + return motionSet; } - MotionSet* Importer::LoadMotionSet(uint8* memoryStart, size_t lengthInBytes, MotionSetSettings* settings) { - // Legacy file type loading. - MCore::MemoryFile memFile; - memFile.Open(memoryStart, lengthInBytes); - - const bool isLegacyFile = Importer::CheckFileType(&memFile) == Importer::EFileType::FILETYPE_MOTIONSET; - if (isLegacyFile) - { - // Open the memory file again as CheckFileType() is closing it at the end. - memFile.Open(memoryStart, lengthInBytes); - EMotionFX::MotionSet* motionSet = LoadMotionSet(&memFile, settings); - if (settings) - { - motionSet->SetIsOwnedByRuntime(settings->m_isOwnedByRuntime); - } - return motionSet; - } - - AZ::SerializeContext* context = nullptr; AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); if (!context) @@ -734,58 +562,6 @@ namespace EMotionFX return motionSet; } - - // try to load a motion set from a file - MotionSet* Importer::LoadMotionSet(MCore::File* f, MotionSetSettings* settings) - { - MCORE_ASSERT(f); - MCORE_ASSERT(f->GetIsOpen()); - - // create the shared data - MCore::Array sharedData; - sharedData.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER); - PrepareSharedData(sharedData); - - // load the file header - FileFormat::MotionSet_Header fileHeader; - f->Read(&fileHeader, sizeof(FileFormat::MotionSet_Header)); - if (fileHeader.mFourCC[0] != 'M' || fileHeader.mFourCC[1] != 'O' || fileHeader.mFourCC[2] != 'S' || fileHeader.mFourCC[3] != ' ') - { - MCore::LogError("The motion set file is not a valid file."); - f->Close(); - return nullptr; - } - - // get the endian type - MCore::Endian::EEndianType endianType = (MCore::Endian::EEndianType)fileHeader.mEndianType; - - // init the import parameters - ImportParameters params; - params.mSharedData = &sharedData; - params.mEndianType = endianType; - params.m_isOwnedByRuntime = settings ? settings->m_isOwnedByRuntime : false; - - // read the chunks - while (ProcessChunk(f, params)) - { - } - - // close the file and return a pointer to the actor we loaded - f->Close(); - - // get rid of shared data - ResetSharedData(sharedData); - sharedData.Clear(); - - // check if the motion set got set - if (params.mMotionSet == nullptr) - { - return nullptr; - } - - return params.mMotionSet; - } - //------------------------------------------------------------------------------------------------- // load a node map by filename @@ -1087,19 +863,6 @@ namespace EMotionFX RegisterChunkProcessor(aznew ChunkProcessorMotionMorphSubMotions()); RegisterChunkProcessor(aznew ChunkProcessorMotionData()); - // AnimGraph file format - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphParameters()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphNodeGroups()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphNode()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphStateTransitions()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphNodeConnections()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphGroupParameters()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphGameControllerSettings()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphAdditionalInfo()); - - // motion set file format - RegisterChunkProcessor(aznew ChunkProcessorMotionSet()); - // node map RegisterChunkProcessor(aznew ChunkProcessorNodeMap()); } @@ -1232,6 +995,18 @@ namespace EMotionFX return FILETYPE_UNKNOWN; } + AZStd::string fileExtension; + AZ::StringFunc::Path::GetExtension(filename, fileExtension); + + if (fileExtension == ".animgraph") + { + return FILETYPE_ANIMGRAPH; + } + if (fileExtension == ".motionset") + { + return FILETYPE_MOTIONSET; + } + // try to open the file from disk MCore::MemoryFile memoryFile; memoryFile.Open(); @@ -1272,14 +1047,6 @@ namespace EMotionFX return FILETYPE_MOTION; } - // check for motion set - file->Seek(0); - if (CheckIfIsValidMotionSetFile(file, &endianType)) - { - file->Close(); - return FILETYPE_MOTIONSET; - } - // check for node map file->Seek(0); if (CheckIfIsValidNodeMapFile(file, &endianType)) @@ -1288,14 +1055,6 @@ namespace EMotionFX return FILETYPE_NODEMAP; } - // check for anim graph - file->Seek(0); - if (CheckIfIsValidAnimGraphFile(file, &endianType)) - { - file->Close(); - return FILETYPE_ANIMGRAPH; - } - // close the file again file->Close(); @@ -1304,124 +1063,30 @@ namespace EMotionFX //--------------------------------------------------------- - - // load anim graph by filename - AnimGraph* Importer::LoadAnimGraph(AZStd::string filename, AnimGraphSettings* settings, const AZ::ObjectStream::FilterDescriptor& loadFilter) + AnimGraph* Importer::LoadAnimGraph(AZStd::string filename, const AZ::ObjectStream::FilterDescriptor& loadFilter) { EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePathKeepCase, filename); - const bool isLegacyFile = Importer::CheckFileType(filename.c_str()) == Importer::EFileType::FILETYPE_ANIMGRAPH; - if (!isLegacyFile) - { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - if (!context) - { - AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); - return nullptr; - } - - EMotionFX::AnimGraph* animGraph = EMotionFX::AnimGraph::LoadFromFile(filename, context, loadFilter); - if (animGraph) - { - animGraph->SetFileName(filename.c_str()); - animGraph->RemoveInvalidConnections(); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. - } - - return animGraph; - } - - ////////////////////////////////////////// - // Legacy file type loading - ////////////////////////////////////////// - - // check if we want to load the anim graph even if a anim graph with the given filename is already inside the anim graph manager - if (settings == nullptr || settings->mForceLoading == false) - { - // search the anim graph inside the anim graph manager and return it if it already got loaded - AnimGraph* animGraph = GetAnimGraphManager().FindAnimGraphByFileName(filename.c_str()); - if (animGraph) - { - MCore::LogInfo(" + Anim graph '%s' already loaded, returning already loaded anim graph from the AnimGraphManager.", filename.c_str()); - return animGraph; - } - } - - if (GetLogging()) - { - MCore::LogInfo("- Trying to load anim graph from file '%s'...", filename.c_str()); - } - - // try to open the file from disk - MCore::DiskFile f; - if (!f.Open(filename.c_str(), MCore::DiskFile::READ)) + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!context) { - if (GetLogging()) - { - MCore::LogError(" + Failed to open the file for anim graph '%s', anim graph not loaded!", filename.c_str()); - } + AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); return nullptr; } - // retrieve the filesize - const size_t fileSize = f.GetFileSize(); - - // create a temporary buffer for the file - uint8* fileBuffer = (uint8*)MCore::Allocate(fileSize, EMFX_MEMCATEGORY_IMPORTER); - - // read in the complete file - f.Read(fileBuffer, fileSize); - - // close the file again - f.Close(); - - // create the actor reading from memory - AnimGraph* result = LoadAnimGraph(fileBuffer, fileSize, settings); - if (result) - { - result->SetFileName(filename.c_str()); - result->RemoveInvalidConnections(); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. - } - - // delete the filebuffer again - MCore::Free(fileBuffer); - - // check if it worked - if (result == nullptr) - { - if (GetLogging()) - { - MCore::LogError(" + Failed to load anim graph from file '%s'", filename.c_str()); - } - } - else + EMotionFX::AnimGraph* animGraph = EMotionFX::AnimGraph::LoadFromFile(filename, context, loadFilter); + if (animGraph) { - if (GetLogging()) - { - MCore::LogInfo(" + Loading successfully finished"); - } + animGraph->SetFileName(filename.c_str()); + animGraph->RemoveInvalidConnections(); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. } - // return the result - return result; + return animGraph; } - - // load the anim graph from memory - AnimGraph* Importer::LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes, AnimGraphSettings* settings) + AnimGraph* Importer::LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes) { - // Legacy file type loading. - MCore::MemoryFile memFile; - memFile.Open(memoryStart, lengthInBytes); - - const bool isLegacyFile = Importer::CheckFileType(&memFile) == Importer::EFileType::FILETYPE_ANIMGRAPH; - if (isLegacyFile) - { - // Open the memory file again as CheckFileType() is closing it at the end. - memFile.Open(memoryStart, lengthInBytes); - return LoadAnimGraph(&memFile, settings); - } - AZ::SerializeContext* context = nullptr; AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); if (!context) @@ -1434,123 +1099,6 @@ namespace EMotionFX return animGraph; } - - // load a anim graph from a file object - AnimGraph* Importer::LoadAnimGraph(MCore::File* f, AnimGraphSettings* settings) - { - MCORE_ASSERT(f); - MCORE_ASSERT(f->GetIsOpen()); - - // execute the pre-passes - if (f->GetType() != MCore::MemoryFile::TYPE_ID) - { - MCore::LogError("Given file is not a memory file. Cannot process pre-passes."); - return nullptr; - } - - // copy over the actor settings, or use defaults - AnimGraphSettings animGraphSettings; - if (settings) - { - animGraphSettings = *settings; - } - - // create the shared data - MCore::Array sharedData; - sharedData.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER); - PrepareSharedData(sharedData); - - //----------------------------------------------- - - // load the file header - FileFormat::AnimGraph_Header fileHeader; - f->Read(&fileHeader, sizeof(FileFormat::AnimGraph_Header)); - if (fileHeader.mFourCC[0] != 'A' || fileHeader.mFourCC[1] != 'N' || fileHeader.mFourCC[2] != 'G' || fileHeader.mFourCC[3] != 'R') - { - MCore::LogError("The anim graph file is not a valid anim graph file."); - f->Close(); - return nullptr; - } - - // get the endian type - MCore::Endian::EEndianType endianType = (MCore::Endian::EEndianType)fileHeader.mEndianType; - - // convert endian of the integer values - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mFileVersion, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumNodes, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumStateTransitions, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumNodeConnections, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumParameters, endianType); - - // read the anim graph name, create it, and read the other remaining info strings - SharedHelperData::ReadString(f, &sharedData, endianType); - AnimGraph* animGraph = aznew AnimGraph(); - - if (GetLogDetails()) - { - MCore::LogDetailedInfo("Anim Graph:"); - - SharedHelperData::ReadString(f, &sharedData, endianType); // copyright - SharedHelperData::ReadString(f, &sharedData, endianType); // description - MCore::LogDetailedInfo(" + Company = %s", SharedHelperData::ReadString(f, &sharedData, endianType)); // company - MCore::LogDetailedInfo(" + EMotion FX Version= %s", SharedHelperData::ReadString(f, &sharedData, endianType)); // emfx version - MCore::LogDetailedInfo(" + EMStudio Build = %s", SharedHelperData::ReadString(f, &sharedData, endianType)); // emstudio build - MCore::LogDetailedInfo(" + Num nodes = %d", fileHeader.mNumNodes); - MCore::LogDetailedInfo(" + Num transitions = %d", fileHeader.mNumStateTransitions); - MCore::LogDetailedInfo(" + Num connections = %d", fileHeader.mNumNodeConnections); - MCore::LogDetailedInfo(" + Num parameters = %d", fileHeader.mNumParameters); - MCore::LogDetailedInfo(" + File version = %d", fileHeader.mFileVersion); - MCore::LogDetailedInfo(" + Endian type = %d", fileHeader.mEndianType); - } - else - { - SharedHelperData::ReadString(f, &sharedData, endianType); // copyright - SharedHelperData::ReadString(f, &sharedData, endianType); // description - SharedHelperData::ReadString(f, &sharedData, endianType); // company - SharedHelperData::ReadString(f, &sharedData, endianType); // emfx version - SharedHelperData::ReadString(f, &sharedData, endianType); // emstudio build - } - - // init the import parameters - ImportParameters params; - params.mSharedData = &sharedData; - params.mEndianType = endianType; - params.mAnimGraph = animGraph; - params.mAnimGraphSettings = &animGraphSettings; - - // pre-allocate the blend nodes array to prevent reallocs - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(params.mSharedData); - blendNodes.Reserve(fileHeader.mNumNodes); - - // process all chunks - while (ProcessChunk(f, params)) - { - } - - // close the file and return a pointer to the actor we loaded - f->Close(); - - // get rid of shared data - ResetSharedData(sharedData); - sharedData.Clear(); - - // recursively update attributes of all state machines and blend tree nodes - if (animGraph->GetRootStateMachine()) - { - animGraph->InitAfterLoading(); - animGraph->RemoveInvalidConnections(true); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. - } - else - { - delete animGraph; - animGraph = nullptr; - } - - // return the created actor - return animGraph; - } - - // extract the file information from an actor file bool Importer::ExtractActorFileInfo(FileInfo* outInfo, const char* filename) const { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h index 83121a405a..2b12f93a1a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h @@ -108,18 +108,15 @@ namespace EMotionFX MCore::Array mChunkIDsToIgnore; /**< Add the ID's of the chunks you wish to ignore. */ }; - /** * The motion set import options. * This can be used in combination with the LoadMotionSet method. */ struct EMFX_API MotionSetSettings { - bool mForceLoading = false; /**< Set to true in case you want to load the motion set even if a motion set with the given filename is already inside the motion manager. */ bool m_isOwnedByRuntime = false; }; - /** * The node map import options. * This can be used in combination with the LoadNodeMap method. @@ -130,30 +127,15 @@ namespace EMotionFX bool mLoadNodes = true; /**< Add nodes to the map? (default=true) */ }; - - /** - * The anim graph import settings. - */ - struct EMFX_API AnimGraphSettings - { - bool mForceLoading = false; /**< Set to true in case you want to load the anim graph even if an anim graph with the given filename is already inside the anim graph manager. */ - bool mDisableNodeVisualization = true; /**< Force disabling of node visualization code execution inside the anim graph nodes? */ - }; - - struct EMFX_API ImportParameters { Actor* mActor = nullptr; Motion* mMotion = nullptr; - MotionSet* mMotionSet = nullptr; Importer::ActorSettings* mActorSettings = nullptr; Importer::MotionSettings* mMotionSettings = nullptr; MCore::Array* mSharedData = nullptr; MCore::Endian::EEndianType mEndianType = MCore::Endian::ENDIAN_LITTLE; - AnimGraph* mAnimGraph = nullptr; - Importer::AnimGraphSettings* mAnimGraphSettings = nullptr; - NodeMap* mNodeMap = nullptr; Importer::NodeMapSettings* mNodeMapSettings = nullptr; bool m_isOwnedByRuntime = false; @@ -250,43 +232,24 @@ namespace EMotionFX //------------------------------------------------------------------------------------------------- - /** - * Load a anim graph file from a given file object. - * @param f The file object. - * @param settings The importer settings, or nullptr to use default settings. - * @result The anim graph object, or nullptr when failed. - */ - AnimGraph* LoadAnimGraph(MCore::File* f, AnimGraphSettings* settings = nullptr); - /** * Load a anim graph file by filename. * @param filename The filename to load from. - * @param settings The anim graph importer settings, or nullptr to use default settings. * @param loadFilter The filter descriptor for loading anim graph from file * @result The anim graph object, or nullptr in case loading failed. */ - AnimGraph* LoadAnimGraph(AZStd::string, AnimGraphSettings* settings = nullptr, const AZ::ObjectStream::FilterDescriptor& loadFilter = AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); + AnimGraph* LoadAnimGraph(AZStd::string, const AZ::ObjectStream::FilterDescriptor& loadFilter = AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); /** * Load a anim graph file from a memory location. * @param memoryStart The start address of the file in memory. * @param lengthInBytes The length of the file, in bytes. - * @param settings The settings to use during loading, or nullptr when you want to use default settings, which would load everything. * @result The anim graph object, or nullptr in case loading failed. */ - AnimGraph* LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes, AnimGraphSettings* settings = nullptr); + AnimGraph* LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes); //------------------------------------------------------------------------------------------------- - /** - * Load a motion set from a given file. - * A file does not have to be stored on disk, but can also be in memory or in an archive or on some network stream. Anything is possible. - * @param f The file to load the motion set from (after load, the file will be closed). - * @param settings The motion set importer settings, or nullptr to use default settings. - * @result The motion set object, or nullptr in case loading failed. - */ - MotionSet* LoadMotionSet(MCore::File* f, MotionSetSettings* settings = nullptr); - /** * Loads a motion set from a file on disk. * @param filename The name of the file on disk. @@ -430,30 +393,6 @@ namespace EMotionFX */ bool CheckIfIsValidMotionFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const; - /** - * Verify if the given file is a valid motion set file that can be processed by the importer. - * Please note that the specified must already been opened and must also be pointing to the location where the - * XPM file header will be stored (the start of the file). The file will not be closed after this method! - * The endian type of the file will be written inside the outEndianType parameter. - * Also note that the file position (read position / cursor) will point after the header after this function has been executed. - * @param f The file to perform the check on. - * @param outEndianType The value that will contain the endian type used by the file. - * @result Returns true when the file is a valid actor file that can be processed by the importer. Otherwise false is returned. - */ - bool CheckIfIsValidMotionSetFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const; - - /** - * Verify if the given file is a valid anim graph file that can be processed by the importer. - * Please note that the specified must already been opened and must also be pointing to the location where the - * XPM file header will be stored (the start of the file). The file will not be closed after this method! - * The endian type of the file will be written inside the outEndianType parameter. - * Also note that the file position (read position / cursor) will point after the header after this function has been executed. - * @param f The file to perform the check on. - * @param outEndianType The value that will contain the endian type used by the file. - * @result Returns true when the file is a valid actor file that can be processed by the importer. Otherwise false is returned. - */ - bool CheckIfIsValidAnimGraphFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const; - /** * Verify if the given file is a valid node map file that can be processed by the importer. * Please note that the specified must already been opened and must also be pointing to the location where the diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp deleted file mode 100644 index db3db121dd..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp +++ /dev/null @@ -1,4772 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#include "LegacyAnimGraphNodeParser.h" -#include -#include -#include "../ConstraintTransformRotationAngles.h" -#include "ChunkProcessors.h" -#include "../AnimGraph.h" -#include "../AnimGraphStateMachine.h" -#include "../AnimGraphBindPoseNode.h" -#include "../AnimGraphHubNode.h" -#include "../AnimGraphParameterCondition.h" -#include "../AnimGraphVector2Condition.h" -#include "../AnimGraphMotionCondition.h" -#include "../AnimGraphStateCondition.h" -#include "../AnimGraphTimeCondition.h" -#include "../AnimGraphPlayTimeCondition.h" -#include "../AnimGraphTagCondition.h" -#include "../BlendTreeMotionFrameNode.h" -#include "../BlendTreeBlendNNode.h" -#include "../BlendTreeFloatConditionNode.h" -#include "../BlendTreeFloatSwitchNode.h" -#include "../BlendTreeBoolLogicNode.h" -#include "../AnimGraphMotionNode.h" -#include "../BlendTreeAccumTransformNode.h" -#include "../BlendTreeBlend2LegacyNode.h" -#include "../BlendTreeFloatConstantNode.h" -#include "../BlendTreeFloatMath1Node.h" -#include "../BlendTreeFloatMath2Node.h" -#include "../BlendTreeMorphTargetNode.h" -#include "../BlendTreeVector2ComposeNode.h" -#include "../BlendTreeVector3ComposeNode.h" -#include "../BlendTreeVector4ComposeNode.h" -#include "../BlendTreeVector3Math1Node.h" -#include "../BlendTreeVector3Math2Node.h" -#include "../BlendTreeSmoothingNode.h" -#include "../BlendTreeRangeRemapperNode.h" -#include "../BlendTreeTwoLinkIKNode.h" -#include "../BlendTreeLookAtNode.h" -#include "../BlendTreeTransformNode.h" -#include "../BlendTreeMaskLegacyNode.h" -#include "../BlendTreePoseSwitchNode.h" -#include "../BlendTreeVector2DecomposeNode.h" -#include "../BlendTreeVector3DecomposeNode.h" -#include "../BlendTreeVector4DecomposeNode.h" -#include "../BlendTreeDirectionToWeightNode.h" -#include "../BlendTreeMirrorPoseNode.h" -#include "../AnimGraphEntryNode.h" -#include "../AnimGraphExitNode.h" -#include "../BlendTreeParameterNode.h" -#include "../BlendSpace1DNode.h" -#include "../BlendSpace2DNode.h" -#include "../BlendTreeFinalNode.h" -#include "../BlendTree.h" -#include "../BlendSpaceNode.h" -#include "../AnimGraphStateTransition.h" -#include "../AnimGraphMotionCondition.h" -#include "../AnimGraphParameterCondition.h" -#include "../AnimGraphPlayTimeCondition.h" -#include "../AnimGraphStateCondition.h" -#include "../AnimGraphTagCondition.h" -#include "../AnimGraphTimeCondition.h" -#include "../AnimGraphVector2Condition.h" -#include "../BlendTreeFloatConstantNode.h" -#include "../BlendTreeMorphTargetNode.h" -#include "../BlendTreeVector2ComposeNode.h" -#include "../BlendTreeVector3ComposeNode.h" -#include "../BlendTreeVector4ComposeNode.h" -#include "../TwoStringEventData.h" - - -namespace EMotionFX -{ - const AZ::TypeId GetNewTypeIdByOldNodeTypeId(uint32 oldNodeTypeId) - { - switch (oldNodeTypeId) - { - case 0x00000017: return azrtti_typeid(); break; - case 0x00000005: return azrtti_typeid(); break; - case 0x00000002: return azrtti_typeid(); break; - case 0x38658581: return azrtti_typeid(); break; - case 0x32521069: return azrtti_typeid(); break; - case 0x38020071: return azrtti_typeid(); break; - case 0x00000006: return azrtti_typeid(); break; - case 0x00000001: return azrtti_typeid(); break; - case 0x00022100: return azrtti_typeid(); break; - case 0x00022200: return azrtti_typeid(); break; - case 0x00000004: return azrtti_typeid(); break; - case 0x00000013: return azrtti_typeid(); break; - case 0x00000007: return azrtti_typeid(); break; - case 0x00000008: return azrtti_typeid(); break; - case 0x00000009: return azrtti_typeid(); break; - case 0x00000010: return azrtti_typeid(); break; - case 0x00000148: return azrtti_typeid(); break; - case 0x00000012: return azrtti_typeid(); break; - case 0x00000011: return azrtti_typeid(); break; - case 0x00000014: return azrtti_typeid(); break; - case 0x00000016: return azrtti_typeid(); break; - case 0x00002445: return azrtti_typeid(); break; - case 0x00000018: return azrtti_typeid(); break; - case 0x00000020: return azrtti_typeid(); break; - case 0x00000021: return azrtti_typeid(); break; - case 0x00000126: return azrtti_typeid(); break; - case 0x00000227: return azrtti_typeid(); break; - case 0x00000129: return azrtti_typeid(); break; - case 0x00000228: return azrtti_typeid(); break; - case 0x00000128: return azrtti_typeid(); break; - case 0x00000229: return azrtti_typeid(); break; - case 0x00000456: return azrtti_typeid(); break; - case 0x02094017: return azrtti_typeid(); break; - case 0x38427080: return azrtti_typeid(); break; - case 0x00000214: return azrtti_typeid(); break; - case 0x00001286: return azrtti_typeid(); break; - case 0x00040360: return azrtti_typeid(); break; - case 0x00012345: return azrtti_typeid(); break; - case 0x00012346: return azrtti_typeid(); break; - case 0x00001000: return azrtti_typeid(); break; - case 0x00002000: return azrtti_typeid(); break; - case 0x00002123: return azrtti_typeid(); break; - case 0x00002001: return azrtti_typeid(); break; - case 0x09502005: return azrtti_typeid(); break; - case 0x00005210: return azrtti_typeid(); break; - case 0x00029610: return azrtti_typeid(); break; - case 0x00005321: return azrtti_typeid(); break; - default: return AZ::TypeId::CreateNull(); - }; - } - - class LegacyAttributeRotation - { - public: - LegacyAttributeRotation() - {} - - LegacyAttributeRotation(const LegacyAttributeRotation& src): - m_rotation(src.m_rotation), - m_degrees(src.m_degrees), - m_order(src.m_order) - {} - - LegacyAttributeRotation& operator=(const LegacyAttributeRotation& src) - { - m_rotation = src.m_rotation; - m_degrees = src.m_degrees; - m_order = src.m_order; - return *this; - } - - void SetRotation(const AZ::Quaternion& rotation) - { - m_rotation = rotation; - } - - void SetDegrees(const AZ::Vector3& degrees) - { - m_degrees = degrees; - } - - void SetOrder(LegacyERotationOrder order) - { - m_order = order; - } - - const AZ::Quaternion& GetRotation() const - { - return m_rotation; - } - - const AZ::Vector3& GetDegrees() const - { - return m_degrees; - } - - LegacyERotationOrder GetOrder() const - { - return m_order; - } - - private: - AZ::Quaternion m_rotation; /**< The unit quaternion rotation. */ - AZ::Vector3 m_degrees; /**< The rotation angles. As programmer you don't need to setup these values. They are only to display in the GUI. */ - LegacyERotationOrder m_order; /**< The rotation order, which defaults to ZYX. */ - }; - - class LegacyStateFilterLocal - { - public: - LegacyStateFilterLocal() { } - - LegacyStateFilterLocal(const LegacyStateFilterLocal& src) : - m_nodeNames(src.m_nodeNames), - m_groupNames(src.m_groupNames) - { } - - LegacyStateFilterLocal& operator=(const LegacyStateFilterLocal& src) - { - m_nodeNames = src.m_nodeNames; - m_groupNames = src.m_groupNames; - return *this; - } - - void SetNodeNmes(const AZStd::vector& nodeNames) - { - m_nodeNames = nodeNames; - } - - void SetGroupNames(const AZStd::vector& groupNames) - { - m_groupNames = groupNames; - } - - const AZStd::vector& GetNodeNames() const - { - return m_nodeNames; - } - - const AZStd::vector& GetGroupNames() const - { - return m_groupNames; - } - - private: - AZStd::vector m_nodeNames; - AZStd::vector m_groupNames; - }; - -bool LegacyAnimGraphNodeParser::Forward(MCore::File* stream, size_t numBytes) -{ - if(!stream->Forward(numBytes)) - { - AZ_Error("EMotionFX", false, "Unable to skip data in stream"); - return false; - } - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - AZStd::string motionId; - - AZ::u32 numCharacters; - if (stream->Read(&numCharacters, sizeof(AZ::u32)) != sizeof(AZ::u32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - - if (numCharacters > 0) - { - motionId.resize(numCharacters); - if (stream->Read(motionId.data(), numCharacters) != numCharacters) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - AZ::Vector2 position; - if (stream->Read(&position, MCore::AttributeVector2::sizeofVector2) != MCore::AttributeVector2::sizeofVector2) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - float x = position.GetX(); - float y = position.GetY(); - MCore::Endian::ConvertFloat(&x, endianType); - MCore::Endian::ConvertFloat(&y, endianType); - position.Set(x, y); - - - AZ::u8 streamTypeFlags; - if (stream->Read(&streamTypeFlags, sizeof(AZ::u8)) != sizeof(AZ::u8)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - BlendSpaceNode::BlendSpaceMotion::TypeFlags typeFlags = static_cast(streamTypeFlags); - m_value.Set(motionId, position, typeFlags); - return true; -} - -template<> -bool LegacyAttribute>::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of entries - uint32 numEntries; - if (stream->Read(&numEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numEntries, endianType); - - m_value.resize(numEntries); - for (uint32 i = 0; i < numEntries; ++i) - { - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "LegacyParameterMask: unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, endianType); - AZStd::string name; - if (numStringBytes > 0) - { - name.resize(numStringBytes); - // Read the string data - if (stream->Read(name.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "LegacyParameterMask: Unable to read data in stream"); - return false; - } - } - m_value[i] = name; - } - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the value - AZ::Vector2 streamValue; - if (stream->Read(&streamValue, MCore::AttributeVector2::sizeofVector2) != MCore::AttributeVector2::sizeofVector2) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertVector2(&streamValue, endianType); - m_value = streamValue; - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - uint8 version; - if(stream->Read(&version, sizeof(uint8)) != sizeof(uint8)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - switch (version) - { - case 1: - { - AZ::PackedVector3f streamValue; - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - - // Read only the degrees, automatically calculate the quaternion - m_value.SetDegrees(value); - const AZ::Quaternion rotation = MCore::AzEulerAnglesToAzQuat(MCore::Math::DegreesToRadians(value.GetX()), MCore::Math::DegreesToRadians(value.GetY()), MCore::Math::DegreesToRadians(value.GetZ())); - m_value.SetRotation(rotation); - } - break; - case 2: - { - AZ::PackedVector3f streamValue; - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - m_value.SetDegrees(value); - - AZ::Quaternion streamValueQ; - if (stream->Read(&streamValueQ, sizeof(AZ::Quaternion)) != sizeof(AZ::Quaternion)) - { - return false; - } - - // Convert endian - MCore::Endian::ConvertQuaternion(&streamValueQ, endianType); - m_value.SetRotation(streamValueQ); - } - break; - case 3: - { - // Read the value - AZ::PackedVector3f streamValue; - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - m_value.SetDegrees(value); - - // Read the quaternion - AZ::Quaternion streamValueQ; - if (stream->Read(&streamValueQ, sizeof(AZ::Quaternion)) != sizeof(AZ::Quaternion)) - { - return false; - } - - // Convert endian - MCore::Endian::ConvertQuaternion(&streamValueQ, endianType); - m_value.SetRotation(streamValueQ); - - // Read the rotation order - uint8 order = 0; - if (stream->Read(&order, sizeof(uint8)) != sizeof(uint8)) - { - return false; - } - - m_value.SetOrder(static_cast(order)); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unknown version %u parsing legacy attribute rotation", version); - return false; - } - break; - } - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Read the value - AZ::PackedVector3f streamValue(0.0f); - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - - m_value = AZ::PackedVector3f(value.GetX(), value.GetY(), value.GetZ()); - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - AZ_UNUSED(endianType); - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - int8 streamValue; - if (stream->Read(&streamValue, sizeof(int8)) != sizeof(int8)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - m_value = (streamValue == 0) ? false : true; - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - AZStd::string nodeName; - // Read the character data - if (numCharacters > 0) - { - nodeName.resize(numCharacters); - if (stream->Read( nodeName.data(), sizeof(char) * numCharacters) != (sizeof(char) * numCharacters)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - // Read the parent depth - uint32 parentDepth; - if (stream->Read(&parentDepth, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertUnsignedInt32(&parentDepth, endianType); - m_value.first = nodeName; - m_value.second = parentDepth; - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType streamEndianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - AZ_Error("EMotionFX", false, "Unable to skip version for legacy attribute State Filter"); - return false; - } - - // Read the number of group entries - uint32 numGroupEntries; - if (stream->Read(&numGroupEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read num groups"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numGroupEntries, streamEndianType); - - // Read the number of node entries - uint32 numNodeEntries; - if (stream->Read(&numNodeEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read num nodes"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numNodeEntries, streamEndianType); - - // Read the group entries - AZStd::string convTemp; - - AZStd::vector groupNames; - groupNames.resize(numGroupEntries); - - for (uint32 i = 0; i < numGroupEntries; ++i) - { - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read group name size"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, streamEndianType); - - // Read the string data - if (numStringBytes > 0) - { - convTemp.resize(numStringBytes); - if (stream->Read(convTemp.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "Unable to read group name"); - return false; - } - } - else - { - convTemp.clear(); - } - - // Add the entry to the mask - groupNames[i] = convTemp; - } - - // Read the node entries - AZStd::vector nodeNames; - nodeNames.resize(numNodeEntries); - for (uint32 i = 0; i < numNodeEntries; ++i) - { - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read node name size"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, streamEndianType); - - // Read the string data - if (numStringBytes > 0) - { - convTemp.resize(numStringBytes); - if (stream->Read(convTemp.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "Unable to read node name"); - return false; - } - } - else - { - convTemp.clear(); - } - - // Add the entry to the mask - nodeNames[i] = convTemp; - } - m_value.SetNodeNmes(nodeNames); - m_value.SetGroupNames(groupNames); - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - int32 streamValue; - if (stream->Read(&streamValue, sizeof(int32)) != sizeof(int32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - MCore::Endian::ConvertSignedInt32(&streamValue, endianType); - m_value = streamValue; - return true; -} - -template<> -bool LegacyAttribute>::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of entries - uint32 numEntries; - if (stream->Read(&numEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numEntries, endianType); - m_value.resize(numEntries); - // Read the entries - for (uint32 i = 0; i < numEntries; ++i) - { - // Read the weight - float weight; - if (stream->Read(&weight, sizeof(float)) != sizeof(float)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertFloat(&weight, endianType); - - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, endianType); - AZStd::string name; - - if (numStringBytes > 0) - { - name.resize(numStringBytes); - - // Read the string data - if (stream->Read(name.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - // Add the entry to the mask - m_value[i].first = name; - m_value[i].second = weight; - } - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - if (numCharacters == 0) - { - m_value.clear(); - return true; - } - - m_value.resize(numCharacters); - if (stream->Read(m_value.data(), numCharacters) != numCharacters) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - float streamValue; - if (stream->Read(&streamValue, sizeof(float)) != sizeof(float)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - MCore::Endian::ConvertFloat(&streamValue, endianType); - - m_value = streamValue; - return true; -} - -template -const T& LegacyAttribute::GetValue() const -{ - return m_value; -} - -bool LegacyAnimGraphNodeParser::GetBlendSpaceNodeEvaluatorTypeId(uint32 legacyIndex, AZ::TypeId& value) -{ - bool result = true; - switch (legacyIndex) - { - case 0: - { - value = azrtti_typeid(); - } - break; - case 1: - { - value = azrtti_typeid(); - } - break; - case 2: - { - value = azrtti_typeid(); - } - break; - case 3: - { - value = azrtti_typeid(); - } - break; - case 4: - { - value = azrtti_typeid(); - } - break; - case 5: - { - value = azrtti_typeid(); - } - break; - case 6: - { - value = azrtti_typeid(); - } - break; - case 7: - { - value = azrtti_typeid(); - } - break; - case 8: - { - value = azrtti_typeid(); - } - break; - default: - { - result = false; - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::GetBlendSpaceNodeEvaluatorTypeId: Unknown typeid index"); - } - break; - } - return result; -} - -bool LegacyAnimGraphNodeParser::InitializeNodeGeneralData(const char* nodeName, Importer::ImportParameters& importParams, FileFormat::AnimGraph_NodeHeader& nodeHeader, AnimGraphNode* node) -{ - AnimGraph* animGraph = importParams.mAnimGraph; - node->SetName(nodeName); - - node->SetVisualPos(nodeHeader.mVisualPosX, nodeHeader.mVisualPosY); - node->SetIsCollapsed(nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_COLLAPSED); - - const AZ::Color color( - MCore::ExtractRed(nodeHeader.mVisualizeColor)/255.0f, - MCore::ExtractGreen(nodeHeader.mVisualizeColor)/255.0f, - MCore::ExtractBlue(nodeHeader.mVisualizeColor)/255.0f, - 1.0f); - node->SetVisualizeColor(color); - - if (importParams.mAnimGraphSettings->mDisableNodeVisualization == false) - { - node->SetVisualization((nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VISUALIZED) != 0); - } - else - { - node->SetVisualization(false); - } - - node->ReserveChildNodes(nodeHeader.mNumChildNodes); - - if (node->GetSupportsDisable()) - { - node->SetIsEnabled(!(nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_DISABLED)); - } - - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - - // Add the new node to the list of loaded nodes - blendNodes.Add(node); - - AZStd::map& entryNodeIndexToStateMachineIdLookupTable = SharedHelperData::GetEntryStateToStateMachineTable(importParams.mSharedData); - - // Add the node to the anim graph - if (nodeHeader.mParentIndex == MCORE_INVALIDINDEX32) - { - AZ_Assert(azrtti_typeid(node) == azrtti_typeid(), ""); - AnimGraphStateMachine* stateMachine = static_cast(node); - - // Set the root state machine - if (animGraph->GetRootStateMachine() == nullptr) - { - animGraph->SetRootStateMachine(stateMachine); - } - else - { - AZ_Warning("EMotionFX", false, "Anim graph already contains a root state machine. Skipping additional root state machines."); - } - } - else - { - blendNodes[nodeHeader.mParentIndex]->AddChildNode(node); - - AZStd::rbtree_const_iterator> tableIter = entryNodeIndexToStateMachineIdLookupTable.find(AZ::u64(blendNodes[nodeHeader.mParentIndex]->GetId())); - if (tableIter != entryNodeIndexToStateMachineIdLookupTable.end()) - { - AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeById(AnimGraphNodeId((*tableIter).first)); - // The type id check will remove the pointer - if (!animGraphNode) - { - AZ_Error("EMotionFX", false, "Unable to find expected State Machine that needs a registered entry state"); - AZ_Assert(false, "Unable to find expected State Machine that needs a registered entry state"); - return false; - } - if (azrtti_typeid(animGraphNode) != azrtti_typeid()) - { - AZ_Error("EMotionFX", false, "Unexpected parent node type"); - AZ_Assert(false, "Unexpected parent node type"); - return false; - } - AnimGraphStateMachine& parentStateMachine = *(static_cast(animGraphNode)); - uint32 entryStateChildNodeIndex = (*tableIter).second; - if (entryStateChildNodeIndex < parentStateMachine.GetNumChildNodes()) - { - parentStateMachine.SetEntryStateId(parentStateMachine.GetChildNode(entryStateChildNodeIndex)->GetId()); - entryNodeIndexToStateMachineIdLookupTable.erase(tableIter); - } - } - - // Set the final node - if (azrtti_typeid(node) == azrtti_typeid()) - { - AZ_Assert(azrtti_typeid(blendNodes[nodeHeader.mParentIndex]) == azrtti_typeid(), ""); - BlendTree* blendTree = static_cast(blendNodes[nodeHeader.mParentIndex]); - blendTree->SetFinalNodeId(node->GetId()); - } - - // Update the virtual final output node - if (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT) - { - AZ_Assert(azrtti_typeid(blendNodes[nodeHeader.mParentIndex]) == azrtti_typeid(), ""); - BlendTree* blendTree = static_cast(blendNodes[nodeHeader.mParentIndex]); - blendTree->SetVirtualFinalNode(node); - } - return true; - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeMorphTargetNode& blendTreeMorphTargetNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttributeArray legacyAttributeArrayStrings; - if (!legacyAttributeArrayStrings.Parse(stream, endianType)) - { - return false; - } - AZStd::vector morphTargetNames; - morphTargetNames.resize(legacyAttributeArrayStrings.GetValue().size()); - for (int i = 0; i < legacyAttributeArrayStrings.GetValue().size(); i++) - { - morphTargetNames[i] = legacyAttributeArrayStrings.GetValue()[i].GetValue(); - } - blendTreeMorphTargetNode.SetMorphTargetNames(morphTargetNames); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatConstantNode& blendTreeFloatConstantNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConstantNode.SetValue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeLookAtNode& blendTreeLookAtNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeLookAtNode.SetTargetNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeLookAtNode.SetLimitMin(legacyAttribute.GetValue()); - } - break; - case 2: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeLookAtNode.SetLimitMax(legacyAttribute.GetValue()); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - - blendTreeLookAtNode.SetConstraintRotation(legacyAttribute.GetValue().GetRotation()); - } - break; - case 4: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - - blendTreeLookAtNode.SetPostRotation(legacyAttribute.GetValue().GetRotation()); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeLookAtNode.SetFollowSpeed(floatValue); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - ConstraintTransformRotationAngles::EAxis axis = static_cast(static_cast(floatValue)); - blendTreeLookAtNode.SetTwistAxis(axis); - } - break; - case 7: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool limitsEnabled = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeLookAtNode.SetLimitsEnabled(limitsEnabled); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeTwoLinkIKNode& blendTreeTwoLinkIKNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetEndNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetEndEffectorNodeName(legacyAttribute.GetValue()); - } - break; - case 2: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetAlignToNode(legacyAttribute.GetValue()); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetBendDirNodeName(legacyAttribute.GetValue()); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool boolValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeTwoLinkIKNode.SetRotationEnabled(boolValue); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool boolValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeTwoLinkIKNode.SetRelativeBendDir(boolValue); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool boolValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeTwoLinkIKNode.SetExtractBendDir(boolValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatMath1Node& blendTreeFloatMath1Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatMath1Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeFloatMath1Node.SetMathFunction(eMathFunction); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphStateTransition& animGraphStateTransition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0:// ATTRIB_DISABLED - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_DISABLED"); - return false; - } - bool isDisabled = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetIsDisabled(isDisabled); - } - break; - case 1:// ATTRIB_PRIORITY - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_PRIORITY"); - return false; - } - int32 intValue = static_cast(floatValue); - animGraphStateTransition.SetPriority(intValue); - } - break; - case 2:// ATTRIB_CANBEINTERRUPTED - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_CANBEINTERRUPTED"); - return false; - } - bool canBeInterrupted = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetCanBeInterrupted(canBeInterrupted); - } - break; - case 3:// ATTRIB_CANINTERRUPTOTHERTRANSITIONS - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_CANINTERRUPTOTHERTRANSITIONS"); - return false; - } - bool canInterruptOtherTransitions = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetCanInterruptOtherTransitions(canInterruptOtherTransitions); - } - break; - case 4:// ATTRIB_ALLOWSELFINTERRUPTION - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_ALLOWSELFINTERRUPTION"); - return false; - } - bool allowSelfInterruption = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetCanInterruptItself(allowSelfInterruption); - } - break; - case 5:// ATTRIB_ALLOWEDSTATES - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - AZ_Error("EMotionFX", false, "Unable to parse legacy attribute state filter"); - return false; - } - - animGraphStateTransition.SetGroups(legacyAttribute.GetValue().GetGroupNames()); - AZStd::vector nodeIDs; - nodeIDs.resize(legacyAttribute.GetValue().GetNodeNames().size()); - int index = 0; - for (int i = 0; i < legacyAttribute.GetValue().GetNodeNames().size(); i++) - { - AnimGraphNode* node = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().GetNodeNames()[i].c_str()); - if (!node) - { - AZ_Warning("EMotionFX", false, "Missing allowed wild card transition on node (%s): The state (%s) in the allowed source state list does not exist in the graph. Removing." - , animGraphStateTransition.GetTargetNode()->GetName(), legacyAttribute.GetValue().GetNodeNames()[i].c_str()); - } - else - { - nodeIDs[index++] = node->GetId(); - } - } - animGraphStateTransition.SetStateIds(nodeIDs); - } - break; - case 6:// ATTRIB_BLENDTIME - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_BLENDTIME"); - return false; - } - animGraphStateTransition.SetBlendTime(floatValue); - } - break; - case 7:// ATTRIB_SYNC - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_SYNC"); - return false; - } - AnimGraphStateTransition::ESyncMode eSyncMode = static_cast(static_cast(floatValue)); - animGraphStateTransition.SetSyncMode(eSyncMode); - } - break; - case 8:// ATTRIB_EVENTMODE - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_EVENTMODE"); - return false; - } - AnimGraphStateTransition::EEventMode eventMode = static_cast(static_cast(floatValue)); - animGraphStateTransition.SetEventFilterMode(eventMode); - } - break; - case 9:// ATTRIB_INTERPOLATIONTYPE - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_INTERPOLATIONTYPE"); - return false; - } - AnimGraphStateTransition::EInterpolationType interpolationType = static_cast(static_cast(floatValue)); - animGraphStateTransition.SetInterpolationType(interpolationType); - } - break; - case 10:// ATTRIB_EASEIN_SMOOTH - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_EASEIN_SMOOTH"); - return false; - } - animGraphStateTransition.SetEaseInSmoothness(floatValue); - } - break; - case 11:// ATTRIB_EASEOUT_SMOOTH - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_EASEOUT_SMOOTH"); - return false; - } - animGraphStateTransition.SetEaseOutSmoothness(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count parsing AnimGraphStateTransition"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphStateMachine& animGraphStateMachine = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool alwaysStartInEntryState = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateMachine.SetAlwaysStartInEntryState(alwaysStartInEntryState); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeRangeRemapperNode& blendTreeRangeRemapperNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetInputMin(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetInputMax(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetOutputMin(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetOutputMax(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeSmoothingNode& blendTreeSmoothingNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeSmoothingNode.SetInterpolationSpeed(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool useStartValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeSmoothingNode.SetUseStartVAlue(useStartValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeSmoothingNode.SetStartVAlue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeVector3Math2Node& blendTreeVector3Math2Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeVector3Math2Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeVector3Math2Node.SetMathFunction(eMathFunction); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeVector3Math2Node.SetDefaultValue(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeVector3Math1Node& blendTreeVector3Math1Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeVector3Math1Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeVector3Math1Node.SetMathFunction(eMathFunction); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatMath2Node& blendTreeFloatMath2Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatMath2Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeFloatMath2Node.SetMathFunction(eMathFunction); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatMath2Node.SetDefaultValue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeBlend2LegacyNode& blendTreeBlend2Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphObject::ESyncMode syncMode = static_cast(static_cast(floatValue)); - blendTreeBlend2Node.SetSyncMode(syncMode); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphObject::EEventMode eventMode = static_cast(static_cast(floatValue)); - blendTreeBlend2Node.SetEventMode(eventMode); - } - break; - case 2: - { - LegacyAttribute> legacyAttributeNodeMask; - if (!legacyAttributeNodeMask.Parse(stream, endianType)) - { - return false; - } - blendTreeBlend2Node.SetWeightedNodeMask(legacyAttributeNodeMask.GetValue()); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool isAdditive = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeBlend2Node.SetAdditiveBlending(isAdditive); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - - } - } - } - return true; -} - -bool LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(float value) -{ - return value > MCore::Math::epsilon; -} - -bool LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(MCore::File* stream - , MCore::Endian::EEndianType endianType - , const LegacyAttributeHeader& attributeHeader - , float& outputValue) -{ - bool result = true; - switch (attributeHeader.GetAttributeType()) - { - case EMotionFX::LegacyAttributeTypeId::ATTRIBUTE_BOOL_TYPE_ID: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - result = false; - } - else - { - outputValue = legacyAttribute.GetValue() ? 1.0f : 0.0f; - } - } - break; - case EMotionFX::LegacyAttributeTypeId::ATTRIBUTE_INT32_TYPE_ID: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - result = false; - } - else - { - outputValue = static_cast(legacyAttribute.GetValue()); - } - } - break; - case EMotionFX::LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - result = false; - } - outputValue = legacyAttribute.GetValue(); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute type"); - result = false; - } - break; - } - if (!result) - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::TryGetFloatFromAttribute Unable to parse attribute value"); - } - return result; -} - -bool LegacyAttributeHeader::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType, LegacyAttributeHeader& attributeHeader) -{ - AZStd::string name; - name.resize(32); - - // Read the attribute size - uint32 attribType; - if (stream->Read(&attribType, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attribType, endianType); - - // Read the attribute size - uint32 attributeSize; - if (stream->Read(&attributeSize, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attributeSize, endianType); - - // First read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - - // Read the string - if (numCharacters > 0) - { - name.resize(numCharacters); - if (stream->Read(name.data(), numCharacters) != numCharacters) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - attributeHeader.m_attribType = attribType; - attributeHeader.m_attributeSize = attributeSize; - attributeHeader.m_name = name; - return true; -} - -template class LegacyAttribute> -bool LegacyAttributeArray::PopulateAttributeDynamicArray(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Read the number of values - uint32 numValues; - if (stream->Read(&numValues, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numValues, endianType); - - for (uint32 i = 0; i < numValues; ++i) - { - LegacyAttribute legacyAttribute; - legacyAttribute.Parse(stream, endianType); - m_attributes.push_back(legacyAttribute); - } - return true; -} - -template class LegacyAttribute> -bool LegacyAttributeArray::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Write the version of the attribute settings format - uint8 version; - if (stream->Read(&version, sizeof(uint8)) != sizeof(uint8)) - { - AZ_Error("EMotionFX", false, "LegacyAttributeArray::Parse - Failed to read the attribute version."); - return false; - } - if (version == 2) - { - // Read the attribute type id - uint32 attribType; - if (stream->Read(&attribType, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "AttributeArray::ReadData() - Failed to read the attribute type ID."); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attribType, endianType); - m_elementTypeId = attribType; - - if (!LegacyAttributeSettingsParser::Parse(stream, endianType)) - { - return false; - } - } - return PopulateAttributeDynamicArray(stream, endianType); -} - -template class LegacyAttribute> -const AZStd::vector< LegacyAttribute > & LegacyAttributeArray::GetValue() const -{ - return m_attributes; -} - -bool LegacyAttributeSettingsParser::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Write the version of the attribute settings format - uint8 version; - if (stream->Read(&version, sizeof(uint8)) != sizeof(uint8)) - { - AZ_Error("EMotionFX", false, "LegacyAttributeSettingsParser::Parse - Failed to read the attribute version."); - return false; - } - - if (version == 2) - { - // Read the flags (new in version 2) - uint16 flags = 0; - if (stream->Read(&flags, sizeof(uint16)) != sizeof(uint16)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt16(&flags, endianType); - } - - // Read the internal name - uint32 numChars; - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - - AZStd::string tempString; - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - - // Read the name - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - tempString.clear(); - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - - // Read the description - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - tempString.clear(); - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - - // Read the interface type - uint32 interfaceType; - if (stream->Read(&interfaceType, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&interfaceType, endianType); - - // Read the number of combobox values - uint32 numComboValues; - if (stream->Read(&numComboValues, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numComboValues, endianType); - - // Read the combo strings - for (uint32 i = 0; i < numComboValues; ++i) - { - tempString.clear(); - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - } - - for (int skipCounter = 0; skipCounter < 3; ++skipCounter) - { - // Skipping attribute type (default value of settings) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint32))) - { - return false; - } - - // Read the attribute size - uint32 attributeSize; - if (stream->Read(&attributeSize, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attributeSize, endianType); - // Skipping attribute content (default value of settings) - if (!LegacyAnimGraphNodeParser::Forward(stream, attributeSize)) - { - return false; - } - } - - return true; -} - -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute>; -template class LegacyAttribute>; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttributeArray; -template class LegacyAttributeArray; - - -bool LegacyAnimGraphNodeParser::ParseTransitionConditionChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphTransitionCondition*& transitionCondition) -{ - const AZ::TypeId conditionType = GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID); - if (conditionType.IsNull()) - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot convert legacy transition condition id '0x%x' to uuid.", nodeHeader.mTypeID); - return false; - } - - if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphMotionCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphParameterCondition"); - return false; - } - transitionCondition->SetAnimGraph(importParams.mAnimGraph); - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphPlayTimeCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphStateCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphTagCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphTimeCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphVector2Condition"); - return false; - } - } - else - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot parse transition condition with uuid %s. No node parser available", conditionType.ToString().c_str()); - return false; - } - - return true; -} - - -bool LegacyAnimGraphNodeParser::ParseAnimGraphNodeChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const char* nodeName, - FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphNode*& node) -{ - const AZ::TypeId nodeType = GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID); - if (nodeType.IsNull()) - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot convert legacy node id '0x%x' to uuid.", nodeHeader.mTypeID); - return false; - } - - if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphBindPoseNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTree"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFinalNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMotionFrameNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeBlendNNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatConditionNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatSwitchNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeBoolLogicNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphMotionNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeAccumTransformNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeBlend2Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatMath1Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatMath2Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3Math1Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3Math2Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeSmoothingNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeRangeRemapperNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphStateMachine"); - return false; - } - - // Only for this node we need to read legacy Custom Data. - - // Read the entry state child node index - uint32 entryStateNodeIndex; - if (file->Read(&entryStateNodeIndex, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - - // Convert endian if needed - MCore::Endian::ConvertUnsignedInt32(&entryStateNodeIndex, importParams.mEndianType); - AZStd::map& entryNodeIndexToStateMachineIdLookupTable = SharedHelperData::GetEntryStateToStateMachineTable(importParams.mSharedData); - if (!entryNodeIndexToStateMachineIdLookupTable.insert(AZStd::pair(node->GetId(), entryStateNodeIndex)).second) - { - AZ_Assert(false, "Same entry state id for different state machines found"); - AZ_Error("EMotionFX", false, "Same entry state id for different state machines found"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeTwoLinkIKNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeLookAtNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeTransformNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMaskLegacyNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreePoseSwitchNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector2DecomposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3DecomposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector4DecomposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector2ComposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3ComposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector4ComposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeDirectionToWeightNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMirrorPoseNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphEntryNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphExitNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeParameterNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendSpace1DNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendSpace2DNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMorphTargetNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatConstantNode"); - return false; - } - } - else - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot parse node with uuid %s. No node parser available", nodeType.ToString().c_str()); - return false; - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphVector2Condition& animGraphVector2Condition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - animGraphVector2Condition.SetParameterName(legacyAttribute.GetValue()); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphVector2Condition::EOperation operation = static_cast(static_cast(floatValue)); - animGraphVector2Condition.SetOperation(operation); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphParameterCondition::EFunction function = static_cast(static_cast(floatValue)); - animGraphVector2Condition.SetFunction(function); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphVector2Condition.SetTestValue(floatValue); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphVector2Condition.SetRangeValue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphTimeCondition& animGraphTimeCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphTimeCondition.SetCountDownTime(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - const bool useRandomization = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphTimeCondition.SetUseRandomization(useRandomization); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphTimeCondition.SetMinRandomTime(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphTimeCondition.SetMaxRandomTime(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphTagCondition& animGraphTagCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphTagCondition::EFunction function = static_cast(static_cast(floatValue)); - animGraphTagCondition.SetFunction(function); - } - break; - case 1: - { - LegacyAttributeArray legacyAttributeArrayStrings; - if (!legacyAttributeArrayStrings.Parse(stream, endianType)) - { - return false; - } - AZStd::vector tags; - tags.resize(legacyAttributeArrayStrings.GetValue().size()); - for (int i = 0; i < legacyAttributeArrayStrings.GetValue().size(); i++) - { - tags[i] = legacyAttributeArrayStrings.GetValue()[i].GetValue(); - } - animGraphTagCondition.SetTags(tags); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphStateCondition& animGraphStateCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AnimGraphNode* node = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().c_str()); - if (node) - { - animGraphStateCondition.SetStateId(node->GetId()); - } - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphStateCondition::TestFunction testFunction = static_cast(static_cast(floatValue)); - animGraphStateCondition.SetTestFunction(testFunction); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphStateCondition.SetPlayTime(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphPlayTimeCondition& animGraphPlayTimeCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AnimGraphNode* node = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().c_str()); - if (node) - { - animGraphPlayTimeCondition.SetNodeId(node->GetId()); - } - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphPlayTimeCondition.SetPlayTime(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphPlayTimeCondition::Mode mode = static_cast(static_cast(floatValue)); - animGraphPlayTimeCondition.SetMode(mode); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphParameterCondition& animGraphParameterCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - animGraphParameterCondition.SetParameterName(legacyAttribute.GetValue()); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphParameterCondition.SetTestValue(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphParameterCondition.SetRangeValue(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphParameterCondition::EFunction function = static_cast(static_cast(floatValue)); - animGraphParameterCondition.SetFunction(function); - } - break; - case 4: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - animGraphParameterCondition.SetTestString(legacyAttribute.GetValue()); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphParameterCondition::EStringFunction stringFunction = static_cast(static_cast(floatValue)); - animGraphParameterCondition.SetStringFunction(stringFunction); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphMotionCondition& animGraphMotionCondition = static_cast(animGraphObject); - - AZStd::string eventType; - AZStd::string eventParameter; - - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: // ATTRIB_MOTIONNODE - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AnimGraphNode* motionNode = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().c_str()); - if (motionNode) - { - animGraphMotionCondition.SetMotionNodeId(motionNode->GetId()); - } - } - break; - case 1: // ATTRIB_FUNCTION - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphMotionCondition::TestFunction testFunction = static_cast(static_cast(floatValue)); - animGraphMotionCondition.SetTestFunction(testFunction); - } - break; - case 2: // ATTRIB_NUMLOOPS - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AZ::u32 numLoops = static_cast(floatValue); - animGraphMotionCondition.SetNumLoops(numLoops); - } - break; - case 3: // ATTRIB_PLAYTIME - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphMotionCondition.SetPlayTime(floatValue); - } - break; - case 4: // ATTRIB_EVENTTYPE - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - eventType = legacyAttribute.GetValue(); - } - break; - case 5: // ATTRIB_EVENTPARAMETER - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - eventParameter = legacyAttribute.GetValue(); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - - AZStd::shared_ptr eventData = EMotionFX::GetEventManager().FindOrCreateEventData(eventType, eventParameter); - animGraphMotionCondition.SetEventDatas({eventData}); - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeBlendNNode& blendTreeBlendNNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - const AnimGraphObject::ESyncMode syncMode = static_cast(static_cast(floatValue)); - blendTreeBlendNNode.SetSyncMode(syncMode); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - const AnimGraphObject::EEventMode eventMode = static_cast(static_cast(floatValue)); - blendTreeBlendNNode.SetEventMode(eventMode); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeMaskLegacyNode& blendTreeMaskNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for(int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask0(maskStrings); - } - break; - case 1: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for (int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask1(maskStrings); - } - break; - case 2: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for (int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask2(maskStrings); - } - break; - case 3: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for (int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask3(maskStrings); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents0(eventFlag); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents1(eventFlag); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents2(eventFlag); - } - break; - case 7: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents3(eventFlag); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count parsing BlendTreeTransformNode"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeTransformNode& blendTreeTransformNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetTargetNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMinTranslation(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - case 2: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMaxTranslation(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMinRotation(legacyAttribute.GetValue().GetDegrees()); - } - break; - case 4: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMaxRotation(legacyAttribute.GetValue().GetDegrees()); - } - break; - case 5: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMinScale(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - case 6: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMaxScale(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count parsing BlendTreeTransformNode"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeAccumTransformNode& blendTreeAccumTransformNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeAccumTransformNode.SetTargetNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeAccumTransformNode::Axis axis = static_cast(static_cast(floatValue)); - blendTreeAccumTransformNode.SetTranslationAxis(axis); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeAccumTransformNode::Axis axis = static_cast(static_cast(floatValue)); - blendTreeAccumTransformNode.SetRotationAxis(axis); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeAccumTransformNode::ScaleAxis axis = static_cast(static_cast(floatValue)); - blendTreeAccumTransformNode.SetScaleAxis(axis); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeAccumTransformNode.SetTranslateSpeed(floatValue); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeAccumTransformNode.SetRotateSpeed(floatValue); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeAccumTransformNode.SetScaleSpeed(floatValue); - } - break; - case 7: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool translateInvert = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeAccumTransformNode.SetInvertTranslation(translateInvert); - } - break; - case 8: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool rotateInvert = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeAccumTransformNode.SetInvertRotation(rotateInvert); - } - break; - case 9: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool scaleInvert = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeAccumTransformNode.SetInvertScale(scaleInvert); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: unexpected attributes count"); - return false; - } - break; - } - } - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphMotionNode& animGraphMotionNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttributeArray legacyAttributeArrayStrings; - if (!legacyAttributeArrayStrings.Parse(stream, endianType)) - { - return false; - } - const AZStd::vector > & stringAttributes = legacyAttributeArrayStrings.GetValue(); - AZStd::vector stringValues; - for (LegacyAttribute attrStr : stringAttributes) - { - stringValues.push_back(attrStr.GetValue()); - } - animGraphMotionNode.SetMotionIds(stringValues); - } - break; - case 1: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool loop = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetLoop(loop); - } - break; - case 2: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool retarget = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetRetarget(retarget); - } - break; - case 3: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool reverse = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetReverse(reverse); - } - break; - case 4: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool emitEvents = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetEmitEvents(emitEvents); - } - break; - case 5: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool mirror = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetMirrorMotion(mirror); - } - break; - case 6: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool motionExtraction = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetMotionExtraction(motionExtraction); - } - break; - case 7: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - animGraphMotionNode.SetMotionPlaySpeed(legacyAttributeFloat.GetValue()); - } - break; - case 8: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - AnimGraphMotionNode::EIndexMode eIndexMode = static_cast(static_cast(legacyAttributeFloat.GetValue())); - animGraphMotionNode.SetIndexMode(eIndexMode); - } - break; - case 9: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool nextMotionAfterLoop = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetNextMotionAfterLoop(nextMotionAfterLoop); - } - break; - case 10: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool nextMotionAfterLoop = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetNextMotionAfterLoop(nextMotionAfterLoop); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: unexpected attributes count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendSpace2DNode& blendSpace2DNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "BlendSpace2DNode: Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: // ATTRIB_CALCULATION_METHOD_X - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - BlendSpaceNode::ECalculationMethod calculationMethod = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetCalculationMethodX(calculationMethod); - } - break; - case 1: // ATTRIB_EVALUATOR_X - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - uint32 evaluatorIndex = static_cast(floatValue); - AZ::TypeId evaluatorId; - if (!GetBlendSpaceNodeEvaluatorTypeId(evaluatorIndex, evaluatorId)) - { - return false; - } - blendSpace2DNode.SetEvaluatorTypeX(evaluatorId); - } - break; - case 2: // ATTRIB_CALCULATION_METHOD_Y - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - BlendSpaceNode::ECalculationMethod calculationMethod = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetCalculationMethodY(calculationMethod); - } - break; - case 3: // ATTRIB_EVALUATOR_Y - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - uint32 evaluatorIndex = static_cast(floatValue); - AZ::TypeId evaluatorId; - if (!GetBlendSpaceNodeEvaluatorTypeId(evaluatorIndex, evaluatorId)) - { - return false; - } - blendSpace2DNode.SetEvaluatorTypeY(evaluatorId); - } - break; - case 4: // ATTRIB_SYNC - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - AnimGraphObject::ESyncMode syncMode = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetSyncMode(syncMode); - } - break; - case 5: //ATTRIB_SYNC_LEADERMOTION - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendSpace2DNode.SetSyncLeaderMotionId(legacyAttribute.GetValue()); - } - break; - case 6: //ATTRIB_EVENTMODE - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - BlendSpaceNode::EBlendSpaceEventMode eventMode = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetEventFilterMode(eventMode); - } - break; - case 7: // ATTRIB_MOTIONS - { - // Parsing an array of string attributes - LegacyAttributeArray legacyAttributeArray; - if (!legacyAttributeArray.Parse(stream, endianType)) - { - return false; - } - // Get the attribute array and process it - AZStd::vector blendSpaceMotions; - blendSpaceMotions.resize(legacyAttributeArray.GetValue().size()); - int newVectorIndex = 0; - for (LegacyAttribute legacyAttribute : legacyAttributeArray.GetValue()) - { - blendSpaceMotions[newVectorIndex++] = legacyAttribute.GetValue(); - } - blendSpace2DNode.SetMotions(blendSpaceMotions); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected number of attributes"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendSpace1DNode& blendSpace1DNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "BlendSpace1DNode: Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "BlendSpace1DNode: Unable to parse calculation method"); - return false; - } - BlendSpaceNode::ECalculationMethod eCalculationMethod = static_cast(static_cast(floatValue)); - blendSpace1DNode.SetCalculationMethod(eCalculationMethod); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "BlendSpace1DNode: Unable to parse evaluator"); - return false; - } - uint32 evaluatorIndex = static_cast(floatValue); - AZ::TypeId evaluatorUUid; - if (!GetBlendSpaceNodeEvaluatorTypeId(evaluatorIndex, evaluatorUUid)) - { - return false; - } - blendSpace1DNode.SetEvaluatorType(evaluatorUUid); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphNode::ESyncMode eSyncMmode = static_cast(static_cast(floatValue)); - blendSpace1DNode.SetSyncMode(eSyncMmode); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendSpace1DNode.SetSyncLeaderMotionId(legacyAttribute.GetValue()); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendSpaceNode::EBlendSpaceEventMode eventMode = static_cast(static_cast(floatValue)); - blendSpace1DNode.SetEventFilterMode(eventMode); - } - break; - case 5: - { - // Parsing an array of string attributes - LegacyAttributeArray legacyAttributeArray; - if (!legacyAttributeArray.Parse(stream, endianType)) - { - return false; - } - // Get the attribute array and process it - AZStd::vector blendSpaceMotions; - blendSpaceMotions.resize(legacyAttributeArray.GetValue().size()); - int newVectorIndex = 0; - for (LegacyAttribute legacyAttribute : legacyAttributeArray.GetValue()) - { - blendSpaceMotions[newVectorIndex++] = legacyAttribute.GetValue(); - } - blendSpace1DNode.SetMotions(blendSpaceMotions); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - BlendTreeParameterNode& blendTreeParameterNode = static_cast(animGraphObject); - - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(importParams.mAnimGraph); - // **************************************************************************************** - - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(nullptr); - // **************************************************************************************** - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(nullptr); - // **************************************************************************************** - - return false; - } - const AZStd::vector& parameterNames = legacyAttribute.GetValue(); - blendTreeParameterNode.SetParameters(parameterNames); - } - break; - default: - { - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(nullptr); - // **************************************************************************************** - - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeMotionFrameNode& blendTreeFloatConditionNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - // This node needs only one attribute, if any more are found inthe file they will be skipped - if (parsedAttributeCount == 0) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConditionNode.SetNormalizedTimeValue(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes : Unexpected attribute count"); - return false; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatConditionNode& blendTreeFloatConditionNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - - BlendTreeFloatConditionNode::EFunction eFunction = (BlendTreeFloatConditionNode::EFunction)((uint32)floatValue); - blendTreeFloatConditionNode.SetFunction(eFunction); - break; - } - - case 1: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - - blendTreeFloatConditionNode.SetDefaultValue(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 2: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConditionNode.SetTrueResult(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 3: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConditionNode.SetFalseResult(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 4: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatConditionNode::EReturnMode returnMode = static_cast(static_cast(floatValue)); - blendTreeFloatConditionNode.SetFalseReturnMode(returnMode); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 5: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatConditionNode::EReturnMode returnMode = static_cast(static_cast(floatValue)); - blendTreeFloatConditionNode.SetTrueReturnMode(returnMode); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected State in Legacy Node parser"); - return false; - } - } - } - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatSwitchNode& blendTreeFloatSwitchNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue0(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue1(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue2(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue3(floatValue); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue4(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeBoolLogicNode& blendTreeBoolLogicNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeBoolLogicNode::EFunction function = static_cast(static_cast(floatValue)); - blendTreeBoolLogicNode.SetFunction(function); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeBoolLogicNode.SetDefaultValue(floatValue > MCore::Math::epsilon); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeBoolLogicNode.SetTrueResult(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeBoolLogicNode.SetFalseResult(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -} diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h deleted file mode 100644 index 5207b0aa10..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include -#include -#include -#include -#include "Importer.h" -#include "AnimGraphFileFormat.h" -#include "../AnimGraphObject.h" -#include -#include -#include "../AnimGraphNode.h" - - -namespace EMotionFX -{ - class AnimGraphNode; - class AnimGraphStateMachine; - class AnimGraphStateTransition; - class AnimGraphTransitionCondition; - class BlendTreeVector4ComposeNode; - class BlendTreeVector3ComposeNode; - class BlendTreeVector2ComposeNode; - class BlendTreeMorphTargetNode; - class BlendTreeFloatConstantNode; - class BlendTreeLookAtNode; - class BlendTreeTwoLinkIKNode; - class BlendTreeFloatMath1Node; - class AnimGraphStateTransition; - class AnimGraphStateMachine; - class BlendTreeRangeRemapperNode; - class BlendTreeSmoothingNode; - class BlendTreeVector3Math2Node; - class BlendTreeVector3Math1Node; - class BlendTreeFloatMath2Node; - class BlendTreeBlend2LegacyNode; - class AnimGraphVector2Condition; - class AnimGraphTimeCondition; - class AnimGraphTagCondition; - class AnimGraphStateCondition; - class AnimGraphPlayTimeCondition; - class AnimGraphParameterCondition; - class AnimGraphMotionCondition; - class BlendTreeBlendNNode; - class BlendTreeMaskLegacyNode; - class BlendTreeTransformNode; - class BlendTreeAccumTransformNode; - class AnimGraphMotionNode; - class BlendTreeVector4DecomposeNode; - class BlendTreeVector3DecomposeNode; - class BlendTreeVector2DecomposeNode; - class BlendTree; - class BlendTreePoseSwitchNode; - class BlendSpace2DNode; - class BlendSpace1DNode; - class BlendTreeParameterNode; - class AnimGraphExitNode; - class AnimGraphEntryNode; - class BlendTreeMirrorPoseNode; - class BlendTreeDirectionToWeightNode; - class AnimGraphBindPoseNode; - class BlendTreeFinalNode; - class AnimGraphNode; - class BlendTreeMotionFrameNode; - class BlendTreeFloatConditionNode; - class BlendTreeFloatSwitchNode; - class BlendTreeBoolLogicNode; - - const AZ::TypeId GetNewTypeIdByOldNodeTypeId(uint32 oldNodeTypeId); - - enum LegacyAttributeTypeId - { - ATTRIBUTE_FLOAT_TYPE_ID = 0x00000001, - ATTRIBUTE_INT32_TYPE_ID = 0x00000002, - ATTRIBUTE_BOOL_TYPE_ID = 0x00000004 - }; - - enum LegacyERotationOrder - { - ROTATIONORDER_ZYX = 0, - ROTATIONORDER_ZXY = 1, - ROTATIONORDER_YZX = 2, - ROTATIONORDER_YXZ = 3, - ROTATIONORDER_XYZ = 4, - ROTATIONORDER_XZY = 5 - }; - - - class LegacyAttributeHeader - { - public: - LegacyAttributeHeader() { } - - AZ::u32 GetAttributeType() const - { - return m_attribType; - } - - AZ::u32 GetAttributeSize() const - { - return m_attributeSize; - } - - static bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType, LegacyAttributeHeader& attributeHeader); - private: - LegacyAttributeHeader(const LegacyAttributeHeader& src) : - m_attribType(src.m_attribType) - , m_attributeSize(src.m_attributeSize) - , m_name(src.m_name) - { } - - AZ::u32 m_attribType; - AZ::u32 m_attributeSize; - AZStd::string m_name; - }; - - template - class LegacyAttribute - { - public: - bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType); - const T& GetValue() const; - private: - T m_value; - }; - - class LegacyAnimGraphNodeParser - { - public: - static bool ParseAnimGraphNodeChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const char* nodeName, - FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphNode*& node); - - static bool ParseTransitionConditionChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphTransitionCondition*& transitionCondition); - - template - static bool ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - - static bool Forward(MCore::File* stream, size_t numBytes); - - private: - static bool InitializeNodeGeneralData(const char* nodeName, Importer::ImportParameters& importParams, FileFormat::AnimGraph_NodeHeader& nodeHeader, AnimGraphNode* node); - static bool GetBlendSpaceNodeEvaluatorTypeId(uint32 legacyIndex, AZ::TypeId& value); - static bool ConvertFloatAttributeValueToBool(float value); - static bool TryGetFloatFromAttribute(MCore::File* stream, MCore::Endian::EEndianType endianType, const LegacyAttributeHeader& attributeHeader, float& outputValue); - - template - static bool ParseAnimGraphNode(MCore::File* file, - Importer::ImportParameters& importParams, - const char* nodeName, - FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphNode*& node) - { - node = aznew T(); - node->SetAnimGraph(importParams.mAnimGraph); - if (!InitializeNodeGeneralData(nodeName, importParams, nodeHeader, node)) - { - MCore::LogError("Error on initializing node general data"); - return false; - } - if (!ParseLegacyAttributes(file, nodeHeader.mNumAttributes, importParams.mEndianType, importParams, *node)) - { - MCore::LogError("Unable to parse node legacy attributes"); - return false; - } - return true; - } - - template - static bool ParseAnimGraphTransitionCondition(MCore::File* file, - Importer::ImportParameters& importParams, - const FileFormat::AnimGraph_NodeHeader& header, - AnimGraphTransitionCondition*& transitionCondition) - { - transitionCondition = aznew T(); - return ParseLegacyAttributes(file, header.mNumAttributes, importParams.mEndianType, importParams, *transitionCondition); - } - }; - - template class LegacyAttribute> - class LegacyAttributeArray - { - public: - bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType); - const AZStd::vector< LegacyAttribute >& GetValue() const; - private: - bool PopulateAttributeDynamicArray(MCore::File* stream, MCore::Endian::EEndianType endianType); - - AZStd::vector< LegacyAttribute > m_attributes; - // Used when reading version 2 attribute array - uint32 m_elementTypeId; - }; - - class LegacyAttributeSettingsParser - { - public: - static bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType); - }; - - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); -} // Namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h deleted file mode 100644 index 216188022e..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -// include the shared structs -#include "SharedFileFormatStructs.h" - - -namespace EMotionFX -{ - namespace FileFormat - { - // the chunks - enum - { - CHUNK_MOTIONSET = 500 - }; - - - struct MotionSet_Header - { - uint8 mFourCC[4]; // must be "MOS " - uint8 mHiVersion; // high version (2 in case of v2.34) - uint8 mLoVersion; // low version (34 in case of v2.34) - uint8 mEndianType; // the endian in which the data is saved [0=little, 1=big] - }; - - - struct MotionSetsChunk - { - uint32 mNumSets; // the number of motion sets - - // followed by: - // motionSets[mNumSets] - }; - - - struct MotionSetChunk - { - uint32 mNumChildSets; // the number of child motion sets - uint32 mNumMotionEntries; // the number of motion entries - - // followed by: - // string : the name of the parent set - // string : the name of the motion set - // string : the filename and path information (e.g. "Root/Motions/Human_Male/" // obsolete, this got removed and is now just an empty string - // motionEntries[mNumMotionEntries]: motion entries - // MotionEntry: - // string : motion filename without path (e.g. "Walk.motion") - // string : motion set string id (e.g. "WALK") - }; - } // namespace FileFormat -} // namespace EMotionFX - diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h index 2355e7923d..082bcbf0ef 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h @@ -7,6 +7,7 @@ */ #pragma once + #include namespace EMotionFX @@ -20,8 +21,6 @@ namespace EMotionFX SHARED_CHUNK_TIMESTAMP = 51 }; - - // a chunk struct FileChunk { uint32 mChunkID; // the chunk ID @@ -29,7 +28,6 @@ namespace EMotionFX uint32 mVersion; // the version of the chunk }; - // color [0..1] range struct FileColor { @@ -39,16 +37,12 @@ namespace EMotionFX float mA; // alpha }; - - // a 2D vector struct FileVector2 { float mX; float mY; }; - - // a 3D vector struct FileVector3 { float mX; // x+ = to the right @@ -56,7 +50,6 @@ namespace EMotionFX float mZ; // z+ = up }; - // a compressed 3D vector struct File16BitVector3 { @@ -65,7 +58,6 @@ namespace EMotionFX uint16 mZ; // z+ = up }; - // a compressed 3D vector struct File8BitVector3 { @@ -74,8 +66,6 @@ namespace EMotionFX uint8 mZ; // z+ = up }; - - // a quaternion struct FileQuaternion { float mX; @@ -84,7 +74,6 @@ namespace EMotionFX float mW; }; - // the 16 bit component quaternion struct File16BitQuaternion { @@ -94,7 +83,6 @@ namespace EMotionFX int16 mW; }; - // a time stamp chunk struct FileTime { @@ -105,17 +93,5 @@ namespace EMotionFX int8 mMinutes; int8 mSeconds; }; - - - // attribute - struct FileAttribute - { - uint32 mDataType; - uint32 mNumBytes; - uint32 mFlags; - - // followed by: - // uint8 mData[mNumBytes]; - }; } // namespace FileFormat -} // namespace EMotionFX +} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake index 7942a5525f..b12cbe102f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake +++ b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake @@ -364,16 +364,11 @@ set(FILES Source/TwoStringEventData.h Source/Importer/ChunkProcessors.cpp Source/Importer/ChunkProcessors.h - Source/Importer/LegacyAnimGraphNodeParser.cpp - Source/Importer/LegacyAnimGraphNodeParser.h Source/Importer/Importer.cpp Source/Importer/Importer.h - Source/Importer/MotionSetFileFormat.h Source/Importer/NodeMapFileFormat.h Source/Importer/SharedFileFormatStructs.h Source/Importer/ActorFileFormat.h - Source/Importer/AnimGraphFileFormat.cpp - Source/Importer/AnimGraphFileFormat.h Source/Importer/MotionFileFormat.h Source/Parameter/BoolParameter.cpp Source/Parameter/BoolParameter.h diff --git a/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp b/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp index e2b7e7164b..ed2bc1a535 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp +++ b/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp @@ -6,7 +6,6 @@ * */ -// include required headers #include "Attribute.h" #include "AttributeFactory.h" #include "AttributeString.h" @@ -14,20 +13,15 @@ namespace MCore { - // constructor Attribute::Attribute(uint32 typeID) { mTypeID = typeID; } - - // destructor Attribute::~Attribute() { } - - // equal operator Attribute& Attribute::operator=(const Attribute& other) { if (&other != this) @@ -36,25 +30,4 @@ namespace MCore } return *this; } - - // read the attribute - bool Attribute::Read(Stream* stream, Endian::EEndianType sourceEndianType) - { - // read the version - uint8 version; - if (stream->Read(&version, sizeof(uint8)) == 0) - { - return false; - } - - // read the data - const bool result = ReadData(stream, sourceEndianType, version); - if (result == false) - { - return false; - } - - return true; - } - -} // namespace MCore +} // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/Attribute.h b/Gems/EMotionFX/Code/MCore/Source/Attribute.h index 06de883a98..c245e7d778 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Attribute.h +++ b/Gems/EMotionFX/Code/MCore/Source/Attribute.h @@ -8,7 +8,6 @@ #pragma once -// include the required headers #include "StandardHeaders.h" #include "MemoryManager.h" #include "Endian.h" @@ -28,7 +27,6 @@ namespace MCore // forward declarations class AttributeSettings; - // the attribute interface types enum : uint32 { @@ -49,12 +47,6 @@ namespace MCore ATTRIBUTE_INTERFACETYPE_DEFAULT = 0xFFFFFFFF// use the default attribute type that the specific attribute class defines as default }; - - /** - * - * - * - */ class MCORE_API Attribute { friend class AttributeFactory; @@ -70,10 +62,6 @@ namespace MCore virtual uint32 GetClassSize() const = 0; virtual uint32 GetDefaultInterfaceType() const = 0; - // These two members and ReadData can go away once we put the old-format parser - bool Read(Stream* stream, MCore::Endian::EEndianType sourceEndianType); - virtual uint32 GetDataSize() const = 0; // data only - Attribute& operator=(const Attribute& other); virtual void NetworkSerialize(EMotionFX::Network::AnimGraphSnapshotChunkSerializer&) {}; @@ -82,16 +70,5 @@ namespace MCore uint32 mTypeID; /**< The unique type ID of the attribute class. */ Attribute(uint32 typeID); - - /** - * Read the attribute info and data from a given stream. - * Please note that the endian information of the actual data is not being converted. You have to handle that yourself. - * The data endian conversion could be done with for example the static Attribute::ConvertDataEndian method. - * @param stream The stream to read the info and data from. - * @param endianType The endian type in which the data is stored in the stream. - * @param version The version of the attribute. - * @result Returns true when successful, or false when reading failed. - */ - virtual bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) = 0; }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h b/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h index 6ef66c28c2..9a923b5fda 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h @@ -63,23 +63,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeBool() {} - - uint32 GetDataSize() const override { return sizeof(int8); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - MCORE_UNUSED(streamEndianType); - int8 streamValue; - if (stream->Read(&streamValue, sizeof(int8)) == 0) - { - return false; - } - - mValue = (streamValue == 0) ? false : true; - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h b/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h index 4abddf90cd..6287239bf8 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h @@ -79,27 +79,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeColor() {} - - uint32 GetDataSize() const override { return sizeof(RGBAColor); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - RGBAColor streamValue; - if (stream->Read(&streamValue, sizeof(RGBAColor)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertRGBAColor(&streamValue, streamEndianType); - mValue = streamValue; - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h b/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h index 2c9f26e90f..ef650a1430 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h @@ -57,8 +57,6 @@ namespace MCore private: float mValue; /**< The float value. */ - uint32 GetDataSize() const override { return sizeof(float); } - AttributeFloat() : Attribute(TYPE_ID) , mValue(0.0f) {} @@ -66,21 +64,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeFloat() {} - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - float streamValue; - if (stream->Read(&streamValue, sizeof(float)) == 0) - { - return false; - } - - Endian::ConvertFloat(&streamValue, streamEndianType); - mValue = streamValue; - return true; - } }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h b/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h index 75e4f102e3..f13246d438 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h @@ -64,23 +64,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeInt32() {} - - uint32 GetDataSize() const override { return sizeof(int32); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - int32 streamValue; - if (stream->Read(&streamValue, sizeof(int32)) == 0) - { - return false; - } - - Endian::ConvertSignedInt32(&streamValue, streamEndianType); - mValue = streamValue; - return true; - } }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h b/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h index becb6030b7..8f7a6cbc65 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h @@ -66,18 +66,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(pointer) { } ~AttributePointer() {} - - uint32 GetDataSize() const override { return sizeof(void*); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(stream); - MCORE_UNUSED(streamEndianType); - MCORE_UNUSED(version); - - MCore::LogWarning("MCore::AttributePointer::ReadData() - Pointer attributes cannot be read from disk."); - return false; - } }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h b/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h index 4509c3a962..3380cac957 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h @@ -82,26 +82,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeQuaternion() { } - - uint32 GetDataSize() const override { return sizeof(AZ::Quaternion); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::Quaternion streamValue; - if (stream->Read(&streamValue, sizeof(AZ::Quaternion)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertQuaternion(&streamValue, streamEndianType); - mValue = streamValue; - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeString.h b/Gems/EMotionFX/Code/MCore/Source/AttributeString.h index 5e030baf54..4f3f8df6f9 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeString.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeString.h @@ -72,40 +72,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeString() { mValue.clear(); } - - uint32 GetDataSize() const override - { - return sizeof(uint32) + static_cast(mValue.size()); - } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertUnsignedInt32(&numCharacters, streamEndianType); - if (numCharacters == 0) - { - mValue.clear(); - return true; - } - - mValue.resize(numCharacters); - if (stream->Read(mValue.data(), numCharacters) == 0) - { - return false; - } - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h b/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h index b69fd5ebcf..b82c7778f7 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h @@ -78,27 +78,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeVector2() { } - - uint32 GetDataSize() const override { return sizeofVector2; } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::Vector2 streamValue; - if (stream->Read(&streamValue, sizeofVector2) == 0) - { - return false; - } - - // convert endian - Endian::ConvertVector2(&streamValue, streamEndianType); - mValue = streamValue; - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h b/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h index 0151de0d69..ea6b820944 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h @@ -79,27 +79,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeVector3() { } - - uint32 GetDataSize() const override { return sizeof(AZ::Vector3); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::PackedVector3f streamValue(0.0f); - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) == 0) - { - return false; - } - - // convert endian - mValue = AZ::Vector3(streamValue.GetX(), streamValue.GetY(), streamValue.GetZ()); - Endian::ConvertVector3(&mValue, streamEndianType); - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h b/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h index 0df42b6676..93dc4a527b 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h @@ -75,27 +75,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeVector4() { } - - uint32 GetDataSize() const override { return sizeof(AZ::Vector4); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::Vector4 streamValue; - if (stream->Read(&streamValue, sizeof(AZ::Vector4)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertVector4(&streamValue, streamEndianType); - mValue = streamValue; - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp b/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp index d3e39840ab..3e459d31d6 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp @@ -53,8 +53,7 @@ namespace EMotionFX AnimGraphAsset* assetData = asset.GetAs(); assetData->m_emfxAnimGraph.reset(EMotionFX::GetImporter().LoadAnimGraph( assetData->m_emfxNativeData.data(), - assetData->m_emfxNativeData.size(), - nullptr)); + assetData->m_emfxNativeData.size())); if (assetData->m_emfxAnimGraph) { diff --git a/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp b/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp index 3e63af8d63..acdd78fc0f 100644 --- a/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp +++ b/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp @@ -97,16 +97,6 @@ namespace EMotionFX ASSERT_EQ(productDependencies.size(), 0); } - TEST_F(EMotionFXBuilderTests, TestLegacyAnimGraphAsset_NoDependency_OutputNoProductDependencies) - { - const AZStd::string fileName = "@devroot@/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph"; - AZStd::vector productDependencies; - EMotionFXBuilder::AnimGraphBuilderWorker builderWorker; - - ASSERT_TRUE(builderWorker.ParseProductDependencies(ResolvePath(fileName.c_str()), fileName, productDependencies)); - ASSERT_EQ(productDependencies.size(), 0); - } - TEST_F(EMotionFXBuilderTests, TestMotionSetAsset_HasReferenceNode_OutputProductDependencies) { const AZStd::string fileName = "@devroot@/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/MotionSetExample.motionset"; @@ -150,14 +140,4 @@ namespace EMotionFX AZ_TEST_STOP_ASSERTTEST(2); ASSERT_EQ(productDependencies.size(), 0); } - - TEST_F(EMotionFXBuilderTests, TestLegacyMotionSetAsset_ReferenceMotionAssets_OutputProductDependencies) - { - const AZStd::string fileName = "@devroot@/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset"; - ProductPathDependencySet productDependencies; - EMotionFXBuilder::MotionSetBuilderWorker builderWorker; - - ASSERT_TRUE(builderWorker.ParseProductDependencies(ResolvePath(fileName.c_str()), fileName, productDependencies)); - ASSERT_EQ(productDependencies.size(), 25); - } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph b/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph deleted file mode 100644 index 5138720283..0000000000 --- a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:33ff8a4f75b5ad918a833113fb45a21e9075b66a9d0ed8563ee34d93ae905aaf -size 50863 diff --git a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset b/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset deleted file mode 100644 index e5339745ca..0000000000 --- a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8ed5c6c8376df150ebddc8b16714012991c1892a94d2b8ad943a7f96563771e0 -size 2518 diff --git a/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph b/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph index 5138720283..ac370ff38d 100644 --- a/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph +++ b/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:33ff8a4f75b5ad918a833113fb45a21e9075b66a9d0ed8563ee34d93ae905aaf -size 50863 +oid sha256:8825feb4f0946979f8a1258cdf20bb71e358b7597eca1aaed552c2b0a17b2bd9 +size 464733 diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp index 9381d98620..bcce080752 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp @@ -578,7 +578,7 @@ namespace NvCloth const AZ::Vector3& renderTangent = renderTangents[renderVertexIndex]; destTangentsBuffer[index].Set( renderTangent, - 1.0f); + -1.0f); // Shader function ConstructTBN inverts w to change bitangent sign, but the bitangents passed are already corrected, so passing -1.0 to counteract. } if (destBitangentsBuffer) diff --git a/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp b/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp index d7ebc8b371..3c47ad46fd 100644 --- a/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp +++ b/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp @@ -12,7 +12,7 @@ namespace NvCloth { namespace { - const float Tolerance = 0.0001f; + const float Tolerance = 1e-7f; } bool TangentSpaceHelper::CalculateNormals( @@ -34,7 +34,8 @@ namespace NvCloth const size_t vertexCount = vertices.size(); // Reset results - outNormals.resize(vertexCount, AZ::Vector3::CreateZero()); + outNormals.resize(vertexCount); + AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero()); // calculate the normals per triangle for (size_t i = 0; i < triangleCount; ++i) @@ -115,8 +116,10 @@ namespace NvCloth const size_t vertexCount = vertices.size(); // Reset results - outTangents.resize(vertexCount, AZ::Vector3::CreateZero()); - outBitangents.resize(vertexCount, AZ::Vector3::CreateZero()); + outTangents.resize(vertexCount); + outBitangents.resize(vertexCount); + AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero()); + AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero()); // calculate the base vectors per triangle for (size_t i = 0; i < triangleCount; ++i) @@ -193,9 +196,12 @@ namespace NvCloth const size_t vertexCount = vertices.size(); // Reset results - outTangents.resize(vertexCount, AZ::Vector3::CreateZero()); - outBitangents.resize(vertexCount, AZ::Vector3::CreateZero()); - outNormals.resize(vertexCount, AZ::Vector3::CreateZero()); + outTangents.resize(vertexCount); + outBitangents.resize(vertexCount); + outNormals.resize(vertexCount); + AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero()); + AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero()); + AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero()); // calculate the base vectors per triangle for (size_t i = 0; i < triangleCount; ++i) diff --git a/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp b/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp index 4beb03502a..c44d200fe3 100644 --- a/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp +++ b/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp @@ -125,6 +125,9 @@ namespace UnitTest const AZStd::vector& motionConstraints = clothConstraints->GetMotionConstraints(); EXPECT_TRUE(motionConstraints.size() == SimulationParticles.size()); + EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(SimulationParticles[0].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(SimulationParticles[1].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(SimulationParticles[2].GetAsVector3(), Tolerance)); EXPECT_NEAR(motionConstraints[0].GetW(), 6.0f, Tolerance); EXPECT_NEAR(motionConstraints[1].GetW(), 0.0f, Tolerance); EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance); @@ -278,6 +281,9 @@ namespace UnitTest const AZStd::vector& separationConstraints = clothConstraints->GetSeparationConstraints(); EXPECT_TRUE(motionConstraints.size() == newParticles.size()); + EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(newParticles[0].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(newParticles[1].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(newParticles[2].GetAsVector3(), Tolerance)); EXPECT_NEAR(motionConstraints[0].GetW(), 3.0f, Tolerance); EXPECT_NEAR(motionConstraints[1].GetW(), 1.5f, Tolerance); EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance); @@ -286,8 +292,8 @@ namespace UnitTest EXPECT_NEAR(separationConstraints[0].GetW(), 3.0f, Tolerance); EXPECT_NEAR(separationConstraints[1].GetW(), 1.5f, Tolerance); EXPECT_NEAR(separationConstraints[2].GetW(), 0.3f, Tolerance); - EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-3.03902f, 2.80752f, 3.80752f), Tolerance)); - EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-1.41659f, 0.651243f, -0.348757f), Tolerance)); - EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(6.15313f, -0.876132f, 0.123868f), Tolerance)); + EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 3.53553f, 4.53553f), Tolerance)); + EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 2.06066f, 1.06066f), Tolerance)); + EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(1.0f, -3.74767f, -2.74767f), Tolerance)); } } // namespace UnitTest diff --git a/README.md b/README.md index 6b88097739..c129fffb6c 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,13 @@ git clone https://github.com/o3de/o3de.git #### Optional -* Wwise - 2021.1.1.7601 minimum: [https://www.audiokinetic.com/download/](https://www.audiokinetic.com/download/) +* Wwise version 2021.1.1.7601 minimum: [https://www.audiokinetic.com/download/](https://www.audiokinetic.com/download/) * Note: This requires registration and installation of a client application to download - * Make sure to select the SDK(C++) component during installation of Wwise - * You will also need to set an environment variable: `set LY_WWISE_INSTALL_PATH=` - * For example: `set LY_WWISE_INSTALL_PATH="C:\Program Files (x86)\Audiokinetic\Wwise 2021.1.1.7601"` + * Note: It is generally okay to use a more recent version of Wwise, but some SDK updates will require code changes + * Make sure to select the `SDK(C++)` component during installation of Wwise + * CMake can find the Wwise install location in two ways: + * The `LY_WWISE_INSTALL_PATH` CMake cache variable -- this is checked first + * The `WWISEROOT` environment variable which is set when installing Wwise SDK ### Quick Start Build Steps @@ -54,8 +56,7 @@ git clone https://github.com/o3de/o3de.git 1. Install the following redistributables to the following: - Visual Studio and VC++ redistributable can be installed to any location - CMake can be installed to any location, as long as it's available in the system path - - (Optional) Wwise can be installed anywhere, but you will need to set an environment variable for CMake to detect it: `set LY_WWISE_INSTALL_PATH=` - + 1. Configure the source into a solution using this command line, replacing and <3rdParty cache path> to a path you've created: ``` cmake -B -S -G "Visual Studio 16" -DLY_3RDPARTY_PATH=<3rdParty cache path> -DLY_UNITY_BUILD=ON -DLY_PROJECTS=AutomatedTesting diff --git a/cmake/3rdParty/FindWwise.cmake b/cmake/3rdParty/FindWwise.cmake index 8cd6db31dd..4cb95da319 100644 --- a/cmake/3rdParty/FindWwise.cmake +++ b/cmake/3rdParty/FindWwise.cmake @@ -6,25 +6,16 @@ # # -# The current supported version of Wwise -set(WWISE_VERSION 2021.1.1.7601) - # Wwise Install Path -# Initialize to the default 3rdParty path -set(LY_WWISE_INSTALL_PATH "" CACHE PATH "Path to Wwise version ${WWISE_VERSION} installation.") +set(LY_WWISE_INSTALL_PATH "" CACHE PATH "Path to Wwise installation.") +# Check for a known file in the SDK path to verify the path function(is_valid_sdk sdk_path is_valid) set(${is_valid} FALSE PARENT_SCOPE) if(EXISTS ${sdk_path}) set(sdk_version_file ${sdk_path}/SDK/include/AK/AkWwiseSDKVersion.h) if(EXISTS ${sdk_version_file}) - string(FIND ${sdk_path} ${WWISE_VERSION} index) - if(NOT index EQUAL -1) - set(${is_valid} TRUE PARENT_SCOPE) - else() - # The install path doesn't contain the WWISE_VERSION string. - # The path could still be correct, but it would require parsing the AkWwiseSDKVersion.h to verify. - endif() + set(${is_valid} TRUE PARENT_SCOPE) endif() endif() endfunction() @@ -32,19 +23,17 @@ endfunction() # Paths that will be checked, in order: # - CMake cache variable # - WWISEROOT Environment Variable -# - Standard 3rdParty path set(WWISE_SDK_PATHS "${LY_WWISE_INSTALL_PATH}" "$ENV{WWISEROOT}" - "${LY_3RDPARTY_PATH}/Wwise/${WWISE_VERSION}" ) set(found_sdk FALSE) -foreach(test_path ${WWISE_SDK_PATHS}) - is_valid_sdk(${test_path} found_sdk) +foreach(candidate_path ${WWISE_SDK_PATHS}) + is_valid_sdk(${candidate_path} found_sdk) if(found_sdk) - # Update the Wwise Install Path cache variable - set(LY_WWISE_INSTALL_PATH "${test_path}") + # Update the Wwise Install Path variable internally + set(LY_WWISE_INSTALL_PATH "${candidate_path}") break() endif() endforeach() @@ -112,15 +101,14 @@ set(WWISE_COMPILE_DEFINITIONS ) -# The default install path might look different than the standard 3rdParty format (${LY_3RDPARTY_PATH}//). # Use these to get the parent path and folder name before adding the external 3p target. -get_filename_component(WWISE_3P_ROOT ${LY_WWISE_INSTALL_PATH} DIRECTORY) +get_filename_component(WWISE_INSTALL_ROOT ${LY_WWISE_INSTALL_PATH} DIRECTORY) get_filename_component(WWISE_FOLDER ${LY_WWISE_INSTALL_PATH} NAME) ly_add_external_target( NAME Wwise VERSION "${WWISE_FOLDER}" - 3RDPARTY_ROOT_DIRECTORY "${WWISE_3P_ROOT}" + 3RDPARTY_ROOT_DIRECTORY "${WWISE_INSTALL_ROOT}" INCLUDE_DIRECTORIES SDK/include COMPILE_DEFINITIONS ${WWISE_COMPILE_DEFINITIONS} ) diff --git a/cmake/LyAutoGen.cmake b/cmake/LyAutoGen.cmake index a1357e15b4..64cb73a453 100644 --- a/cmake/LyAutoGen.cmake +++ b/cmake/LyAutoGen.cmake @@ -40,7 +40,6 @@ function(ly_add_autogen) ) set_target_properties(${ly_add_autogen_NAME} PROPERTIES AUTOGEN_INPUT_FILES "${AZCG_INPUTFILES}") set_target_properties(${ly_add_autogen_NAME} PROPERTIES AUTOGEN_OUTPUT_FILES "${AUTOGEN_OUTPUTS}") - set_target_properties(${ly_add_autogen_NAME} PROPERTIES VS_USER_PROPS "${LY_ROOT_FOLDER}/Code/Framework/AzAutoGen/AzAutoGen.props") target_sources(${ly_add_autogen_NAME} PRIVATE ${AUTOGEN_OUTPUTS}) endif() diff --git a/cmake/Platform/Common/Directory.Build.props b/cmake/Platform/Common/Directory.Build.props index 1adf33ee89..73aa984073 100644 --- a/cmake/Platform/Common/Directory.Build.props +++ b/cmake/Platform/Common/Directory.Build.props @@ -10,7 +10,10 @@ SPDX-License-Identifier: Apache-2.0 OR MIT true true + @VCPKG_CONFIGURATION_MAPPING@ + + false diff --git a/scripts/o3de.py b/scripts/o3de.py index 06873e1de2..03f737643f 100755 --- a/scripts/o3de.py +++ b/scripts/o3de.py @@ -28,7 +28,7 @@ def add_args(parser, subparsers) -> None: o3de_package_dir = (script_dir / 'o3de').resolve() # add the scripts/o3de directory to the front of the sys.path sys.path.insert(0, str(o3de_package_dir)) - from o3de import engine_template, global_project, register, print_registration, get_registration, \ + from o3de import engine_properties, engine_template, gem_properties, global_project, register, print_registration, get_registration, \ enable_gem, disable_gem, project_properties, sha256 # Remove the temporarily added path sys.path = sys.path[1:] @@ -52,9 +52,15 @@ def add_args(parser, subparsers) -> None: # remove a gem from a project disable_gem.add_args(subparsers) - - # modify project properties + + # modify engine properties + engine_properties.add_args(subparsers) + + # modify project properties project_properties.add_args(subparsers) + + # modify gem properties + gem_properties.add_args(subparsers) # sha256 sha256.add_args(subparsers) diff --git a/scripts/o3de/o3de/engine_properties.py b/scripts/o3de/o3de/engine_properties.py new file mode 100644 index 0000000000..92930dbb1c --- /dev/null +++ b/scripts/o3de/o3de/engine_properties.py @@ -0,0 +1,82 @@ +# +# 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 +# +# + +import argparse +import json +import os +import pathlib +import sys +import logging + +from o3de import manifest, utils + +logger = logging.getLogger() +logging.basicConfig() + +def edit_engine_props(engine_path: pathlib.Path = None, + engine_name: str = None, + new_name: str = None, + new_version: str = None) -> int: + if not engine_path and not engine_name: + logger.error(f'Either a engine path or a engine name must be supplied to lookup engine.json') + return 1 + if not engine_path: + engine_path = manifest.get_registered(engine_name=engine_name) + + if not engine_path: + logger.error(f'Error unable locate engine path: No engine with name {engine_name} is registered in any manifest') + return 1 + + engine_json_data = manifest.get_engine_json_data(engine_path=engine_path) + if not engine_json_data: + return 1 + + if new_name: + if not utils.validate_identifier(new_name): + logger.error(f'Engine name must be fewer than 64 characters, contain only alphanumeric, "_" or "-"' + f' characters, and start with a letter. {new_name}') + return 1 + engine_json_data['engine_name'] = new_name + if new_version: + engine_json_data['O3DEVersion'] = new_version + + return 0 if manifest.save_o3de_manifest(engine_json_data, pathlib.Path(engine_path) / 'engine.json') else 1 + +def _edit_engine_props(args: argparse) -> int: + return edit_engine_props(args.engine_path, + args.engine_name, + args.engine_new_name, + args.engine_version) + +def add_parser_args(parser): + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-ep', '--engine-path', type=pathlib.Path, required=False, + help='The path to the engine.') + group.add_argument('-en', '--engine-name', type=str, required=False, + help='The name of the engine.') + group = parser.add_argument_group('properties', 'arguments for modifying individual engine properties.') + group.add_argument('-enn', '--engine-new-name', type=str, required=False, + help='Sets the name for the engine.') + group.add_argument('-ev', '--engine-version', type=str, required=False, + help='Sets the version for the engine.') + parser.set_defaults(func=_edit_engine_props) + +def add_args(subparsers) -> None: + enable_engine_props_subparser = subparsers.add_parser('edit-engine-properties') + add_parser_args(enable_engine_props_subparser) + + +def main(): + the_parser = argparse.ArgumentParser() + add_parser_args(the_parser) + the_args = the_parser.parse_args() + ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1 + sys.exit(ret) + +if __name__ == "__main__": + main() diff --git a/scripts/o3de/o3de/gem_properties.py b/scripts/o3de/o3de/gem_properties.py new file mode 100644 index 0000000000..c97e5db89d --- /dev/null +++ b/scripts/o3de/o3de/gem_properties.py @@ -0,0 +1,163 @@ +# +# 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 +# +# + +import argparse +import json +import os +import pathlib +import sys +import logging + +from o3de import manifest, utils + +logger = logging.getLogger() +logging.basicConfig() + + +def update_values_in_key_list(existing_values: list, new_values: list or str, remove_values: list or str, + replace_values: list or str): + """ + Updates values within a list by first appending values in the new_values list, removing values in the remove_values + list and then replacing values in the replace_values list + :param existing_values list with existing values to modify + :param new_values list with values to add to the existing value list + :param remove_values list with values to remove from the existing value list + :param replace_values list with values to replace in the existing value list + + returns updated existing value list + """ + if new_values: + new_values = new_values.split() if isinstance(new_values, str) else new_values + existing_values.extend(new_values) + if remove_values: + remove_values = remove_values.split() if isinstance(remove_values, str) else remove_values + existing_values = list(filter(lambda value: value not in remove_values, existing_values)) + if replace_values: + replace_values = replace_values.split() if isinstance(replace_values, str) else replace_values + existing_values = replace_values + + return existing_values + + +def edit_gem_props(gem_path: pathlib.Path = None, + gem_name: str = None, + new_name: str = None, + new_display: str = None, + new_origin: str = None, + new_type: str = None, + new_summary: str = None, + new_icon: str = None, + new_requirements: str = None, + new_tags: list or str = None, + remove_tags: list or str = None, + replace_tags: list or str = None, + ) -> int: + + if not gem_path and not gem_name: + logger.error(f'Either a gem path or a gem name must be supplied to lookup gem.json') + return 1 + if not gem_path: + gem_path = manifest.get_registered(gem_name=gem_name) + + if not gem_path: + logger.error(f'Error unable locate gem path: No gem with name {gem_name} is registered in any manifest') + return 1 + + gem_json_data = manifest.get_gem_json_data(gem_path=gem_path) + if not gem_json_data: + return 1 + + update_key_dict = {} + if new_name: + if not utils.validate_identifier(new_name): + logger.error(f'Engine name must be fewer than 64 characters, contain only alphanumeric, "_" or "-"' + f' characters, and start with a letter. {new_name}') + return 1 + update_key_dict['gem_name'] = new_name + if new_display: + update_key_dict['display_name'] = new_display + if new_origin: + update_key_dict['origin'] = new_origin + if new_type: + update_key_dict['type'] = new_type + if new_summary: + update_key_dict['summary'] = new_summary + if new_icon: + update_key_dict['icon_path'] = new_icon + if new_requirements: + update_key_dict['icon_requirements'] = new_requirements + + update_key_dict['user_tags'] = update_values_in_key_list(gem_json_data.get('user_tags', []), new_tags, + remove_tags, replace_tags) + + gem_json_data.update(update_key_dict) + + return 0 if manifest.save_o3de_manifest(gem_json_data, pathlib.Path(gem_path) / 'gem.json') else 1 + + +def _edit_gem_props(args: argparse) -> int: + return edit_gem_props(args.gem_path, + args.gem_name, + args.gem_new_name, + args.gem_display, + args.gem_origin, + args.gem_type, + args.gem_summary, + args.gem_icon, + args.gem_requirements, + args.add_tags, + args.remove_tags, + args.replace_tags) + + +def add_parser_args(parser): + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-gp', '--gem-path', type=pathlib.Path, required=False, + help='The path to the gem.') + group.add_argument('-gn', '--gem-name', type=str, required=False, + help='The name of the gem.') + group = parser.add_argument_group('properties', 'arguments for modifying individual gem properties.') + group.add_argument('-gnn', '--gem-new-name', type=str, required=False, + help='Sets the name for the gem.') + group.add_argument('-gd', '--gem-display', type=str, required=False, + help='Sets the gem display name.') + group.add_argument('-go', '--gem-origin', type=str, required=False, + help='Sets description for gem origin.') + group.add_argument('-gt', '--gem-type', type=str, required=False, choices=['Code', 'Tool', 'Asset'], + help='Sets the gem type. Can only be one of the selected choices') + group.add_argument('-gs', '--gem-summary', type=str, required=False, + help='Sets the summary description of the gem.') + group.add_argument('-gi', '--gem-icon', type=str, required=False, + help='Sets the path to the projects icon resource.') + group.add_argument('-gr', '--gem-requirements', type=str, required=False, + help='Sets the description of the requirements needed to use the gem') + group = parser.add_mutually_exclusive_group(required=False) + group.add_argument('-at', '--add-tags', type=str, nargs='*', required=False, + help='Adds tag(s) to user_tags property. Can be specified multiple times') + group.add_argument('-dt', '--remove-tags', type=str, nargs='*', required=False, + help='Removes tag(s) from the user_tags property. Can be specified multiple times') + group.add_argument('-rt', '--replace-tags', type=str, nargs='*', required=False, + help='Replace tag(s) in user_tags property. Can be specified multiple times') + parser.set_defaults(func=_edit_gem_props) + + +def add_args(subparsers) -> None: + enable_gem_props_subparser = subparsers.add_parser('edit-gem-properties') + add_parser_args(enable_gem_props_subparser) + + +def main(): + the_parser = argparse.ArgumentParser() + add_parser_args(the_parser) + the_args = the_parser.parse_args() + ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1 + sys.exit(ret) + + +if __name__ == "__main__": + main() diff --git a/scripts/o3de/o3de/project_properties.py b/scripts/o3de/o3de/project_properties.py index 977f9777b2..04731ad3de 100644 --- a/scripts/o3de/o3de/project_properties.py +++ b/scripts/o3de/o3de/project_properties.py @@ -26,7 +26,7 @@ def get_project_props(name: str = None, path: pathlib.Path = None) -> dict: return None return proj_json -def edit_project_props(proj_path: pathlib.Path, +def edit_project_props(proj_path: pathlib.Path = None, proj_name: str = None, new_name: str = None, new_origin: str = None, @@ -71,8 +71,8 @@ def edit_project_props(proj_path: pathlib.Path, tag_list = replace_tags.split() if isinstance(replace_tags, str) else replace_tags proj_json['user_tags'] = tag_list - manifest.save_o3de_manifest(proj_json, pathlib.Path(proj_path) / 'project.json') - return 0 + + return 0 if manifest.save_o3de_manifest(proj_json, pathlib.Path(proj_path) / 'project.json') else 1 def _edit_project_props(args: argparse) -> int: return edit_project_props(args.project_path, diff --git a/scripts/o3de/tests/CMakeLists.txt b/scripts/o3de/tests/CMakeLists.txt index 42ded05b29..00d0774c45 100644 --- a/scripts/o3de/tests/CMakeLists.txt +++ b/scripts/o3de/tests/CMakeLists.txt @@ -39,6 +39,13 @@ ly_add_pytest( EXCLUDE_TEST_RUN_TARGET_FROM_IDE ) +ly_add_pytest( + NAME o3de_engine_properties + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_engine_properties.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) + ly_add_pytest( NAME o3de_project_properties PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_project_properties.py @@ -46,6 +53,13 @@ ly_add_pytest( EXCLUDE_TEST_RUN_TARGET_FROM_IDE ) +ly_add_pytest( + NAME o3de_gem_properties + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_gem_properties.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) + ly_add_pytest( NAME o3de_template PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_engine_template.py diff --git a/scripts/o3de/tests/unit_test_engine_properties.py b/scripts/o3de/tests/unit_test_engine_properties.py new file mode 100644 index 0000000000..19cb7d4e62 --- /dev/null +++ b/scripts/o3de/tests/unit_test_engine_properties.py @@ -0,0 +1,72 @@ +# +# 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 +# +# + +import json +import pytest +import pathlib +from unittest.mock import patch + +from o3de import engine_properties + + +TEST_ENGINE_JSON_PAYLOAD = ''' +{ + "engine_name": "o3de", + "restricted_name": "o3de", + "FileVersion": 1, + "O3DEVersion": "0.0.0.0", + "O3DECopyrightYear": 2021, + "O3DEBuildNumber": 0, + "external_subdirectories": [ + "Gems/TestGem2" + ], + "projects": [ + ], + "templates": [ + "Templates/MinimalProject" + ] +} +''' + + +@pytest.fixture(scope='class') +def init_engine_json_data(request): + class EngineJsonData: + def __init__(self): + self.data = json.loads(TEST_ENGINE_JSON_PAYLOAD) + request.cls.engine_json = EngineJsonData() + +@pytest.mark.usefixtures('init_engine_json_data') +class TestEditEngineProperties: + @pytest.mark.parametrize("engine_path, engine_name, engine_new_name, engine_version, expected_result", [ + pytest.param(pathlib.PurePath('D:/o3de'), None, 'o3de-install', '1.0.0.0', 0), + pytest.param(None, 'o3de-install', 'o3de-sdk', '1.0.0.1', 0), + pytest.param(None, 'o3de-sdk', None, '2.0.0.0', 0), + ] + ) + def test_edit_engine_properties(self, engine_path, engine_name, engine_new_name, engine_version, expected_result): + + def get_engine_json_data(engine_path: pathlib.Path) -> dict: + return self.engine_json.data + + def get_engine_path(engine_name: str) -> pathlib.Path: + return pathlib.Path('D:/o3de') + + def save_o3de_manifest(new_engine_data: dict, engine_path: pathlib.Path) -> bool: + self.engine_json.data = new_engine_data + return True + + with patch('o3de.manifest.get_engine_json_data', side_effect=get_engine_json_data) as get_engine_json_data_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch, \ + patch('o3de.manifest.get_registered', side_effect=get_engine_path) as get_registered_patch: + result = engine_properties.edit_engine_props(engine_path, engine_name, engine_new_name, engine_version) + assert result == expected_result + if engine_new_name: + assert self.engine_json.data.get('engine_name', '') == engine_new_name + if engine_version: + assert self.engine_json.data.get('O3DEVersion', '') == engine_version diff --git a/scripts/o3de/tests/unit_test_gem_properties.py b/scripts/o3de/tests/unit_test_gem_properties.py new file mode 100644 index 0000000000..29d53fbee6 --- /dev/null +++ b/scripts/o3de/tests/unit_test_gem_properties.py @@ -0,0 +1,99 @@ +# +# 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 +# +# + +import json +import pytest +import pathlib +from unittest.mock import patch + +from o3de import gem_properties + + +TEST_GEM_JSON_PAYLOAD = ''' +{ + "gem_name": "TestGem", + "display_name": "TestGem", + "license": "What license TestGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "origin": "The primary repo for TestGem goes here: i.e. http://www.mydomain.com", + "type": "Code", + "summary": "A short description of TestGem.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "TestGem" + ], + "icon_path": "preview.png", + "requirements": "" +} +''' + + +@pytest.fixture(scope='class') +def init_gem_json_data(request): + class GemJsonData: + def __init__(self): + self.data = json.loads(TEST_GEM_JSON_PAYLOAD) + request.cls.gem_json = GemJsonData() + +@pytest.mark.usefixtures('init_gem_json_data') +class TestEditGemProperties: + @pytest.mark.parametrize("gem_path, gem_name, gem_new_name, gem_display, gem_origin,\ + gem_type, gem_summary, gem_icon, gem_requirements,\ + add_tags, remove_tags, replace_tags, expected_tags, expected_result", [ + pytest.param(pathlib.PurePath('D:/TestProject'), + None, 'TestGem2', 'New Gem Name', 'O3DE', 'Code', 'Gem that exercises Default Gem Template', + 'preview.png', '', + ['Physics', 'Rendering', 'Scripting'], None, None, ['TestGem', 'Physics', 'Rendering', 'Scripting'], + 0), + pytest.param(None, + 'TestGem2', None, 'New Gem Name', 'O3DE', 'Asset', 'Gem that exercises Default Gem Template', + 'preview.png', '', None, ['Physics'], None, ['TestGem', 'Rendering', 'Scripting'], 0), + pytest.param(None, + 'TestGem2', None, 'New Gem Name', 'O3DE', 'Tool', 'Gem that exercises Default Gem Template', + 'preview.png', '', None, None, ['Animation', 'TestGem'], ['Animation', 'TestGem'], 0) + ] + ) + def test_edit_gem_properties(self, gem_path, gem_name, gem_new_name, gem_display, gem_origin, + gem_type, gem_summary, gem_icon, gem_requirements, + add_tags, remove_tags, replace_tags, + expected_tags, expected_result): + + def get_gem_json_data(gem_path: pathlib.Path) -> dict: + return self.gem_json.data + + def get_gem_path(gem_name: str) -> pathlib.Path: + return pathlib.Path('D:/TestProject') + + def save_o3de_manifest(new_gem_data: dict, gem_path: pathlib.Path) -> bool: + self.gem_json.data = new_gem_data + return True + + with patch('o3de.manifest.get_gem_json_data', side_effect=get_gem_json_data) as get_gem_json_data_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch, \ + patch('o3de.manifest.get_registered', side_effect=get_gem_path) as get_registered_patch: + result = gem_properties.edit_gem_props(gem_path, gem_name, gem_new_name, gem_display, gem_origin, + gem_type, gem_summary, gem_icon, gem_requirements, + add_tags, remove_tags, replace_tags) + assert result == expected_result + if gem_new_name: + assert self.gem_json.data.get('gem_name', '') == gem_new_name + if gem_display: + assert self.gem_json.data.get('display_name', '') == gem_display + if gem_origin: + assert self.gem_json.data.get('origin', '') == gem_origin + if gem_type: + assert self.gem_json.data.get('type', '') == gem_type + if gem_summary: + assert self.gem_json.data.get('summary', '') == gem_summary + if gem_icon: + assert self.gem_json.data.get('icon_path', '') == gem_icon + if gem_requirements: + assert self.gem_json.data.get('requirments', '') == gem_requirements + + assert set(self.gem_json.data.get('user_tags', [])) == set(expected_tags) diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py index d85ed121c3..f72a4dfe4c 100644 --- a/scripts/o3de/tests/unit_test_project_properties.py +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -58,8 +58,9 @@ class TestEditProjectProperties: return None return self.project_json.data - def save_o3de_manifest(new_proj_data: dict, project_path) -> None: + def save_o3de_manifest(new_proj_data: dict, project_path) -> bool: self.project_json.data = new_proj_data + return True with patch('o3de.manifest.get_project_json_data', side_effect=get_project_json_data) as get_project_json_data_patch, \ patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch: