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