FeatureMatrix.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/Memory/Memory.h>
  10. #include <AzCore/RTTI/RTTI.h>
  11. #include <AzCore/Math/Vector2.h>
  12. #include <AzCore/Math/Vector3.h>
  13. #include <AzCore/std/containers/vector.h>
  14. #include <AzCore/std/string/string.h>
  15. //! Enable in case you want to use the Eigen SDK Eigen::Matrix as base for the feature matrix (https://eigen.tuxfamily.org/)
  16. //! In case Eigen is disabled, a small simple NxM wrapper class is provided by default.
  17. //#define O3DE_USE_EIGEN
  18. #define O3DE_MM_FLOATTYPE float
  19. #ifdef O3DE_USE_EIGEN
  20. #pragma warning (push, 1)
  21. #pragma warning (disable:4834) // C4834: discarding return value of function with 'nodiscard' attribute
  22. #pragma warning (disable:5031) // #pragma warning(pop): likely mismatch, popping warning state pushed in different file
  23. #pragma warning (disable:4702) // warning C4702: unreachable code
  24. #pragma warning (disable:4723) // warning C4723: potential divide by 0
  25. #include "../../3rdParty/eigen-3.3.9/Eigen/Dense"
  26. #pragma warning (pop)
  27. #endif
  28. namespace EMotionFX::MotionMatching
  29. {
  30. class FeatureSchema;
  31. #ifdef O3DE_USE_EIGEN
  32. // Features are stored in columns, each row represents a frame
  33. // RowMajor: Store row components next to each other in memory for cache-optimized feature access for a given frame.
  34. using FeatureMatrixType = Eigen::Matrix<O3DE_MM_FLOATTYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
  35. #else
  36. //! Small wrapper for a 2D matrix similar to the Eigen::Matrix.
  37. class FeatureMatrixType
  38. {
  39. public:
  40. size_t size() const
  41. {
  42. return m_data.size();
  43. }
  44. size_t rows() const
  45. {
  46. return m_rowCount;
  47. }
  48. size_t cols() const
  49. {
  50. return m_columnCount;
  51. }
  52. void resize(size_t rowCount, size_t columnCount)
  53. {
  54. m_rowCount = rowCount;
  55. m_columnCount = columnCount;
  56. m_data.resize(m_rowCount * m_columnCount);
  57. }
  58. float& operator()(size_t row, size_t column)
  59. {
  60. return m_data[row * m_columnCount + column];
  61. }
  62. const float& operator()(size_t row, size_t column) const
  63. {
  64. return m_data[row * m_columnCount + column];
  65. }
  66. float coeff(size_t row, size_t column) const
  67. {
  68. return m_data[row * m_columnCount + column];
  69. }
  70. private:
  71. AZStd::vector<float> m_data;
  72. size_t m_rowCount = 0;
  73. size_t m_columnCount = 0;
  74. };
  75. #endif
  76. //! The feature matrix is a NxM matrix which stores the extracted feature values for all frames in our motion database based upon a given feature schema.
  77. //! The feature schema defines the order of the columns and values and is used to identify values and find their location inside the matrix.
  78. //! A 3D position feature storing XYZ values e.g. will use three columns in the feature matrix. Every component of a feature is linked to a column index,
  79. //! so e.g. the left foot position Y value might be at column index 6. The group of values or columns that belong to a given feature is what we call a feature block.
  80. //! The accumulated number of dimensions for all features in the schema, while the number of dimensions might vary per feature, form the number of columns of the feature matrix.
  81. //! Each row represents the features of a single frame of the motion database. The number of rows of the feature matrix is defined by the number.
  82. class FeatureMatrix
  83. : public FeatureMatrixType
  84. {
  85. public:
  86. AZ_RTTI(FeatureMatrix, "{E063C9CB-7147-4776-A6E0-98584DD93FEF}");
  87. AZ_CLASS_ALLOCATOR_DECL
  88. #ifdef O3DE_USE_EIGEN
  89. using Index = Eigen::Index;
  90. #else
  91. using Index = size_t;
  92. #endif
  93. virtual ~FeatureMatrix() = default;
  94. void Clear();
  95. void SaveAsCsv(const AZStd::string& filename, const AZStd::vector<AZStd::string>& columnNames = {}) const;
  96. void SaveAsCsv(const AZStd::string& filename, const FeatureSchema* featureSchema) const;
  97. size_t CalcMemoryUsageInBytes() const;
  98. AZ::Vector2 GetVector2(Index row, Index startColumn) const;
  99. void SetVector2(Index row, Index startColumn, const AZ::Vector2& value);
  100. AZ::Vector3 GetVector3(Index row, Index startColumn) const;
  101. void SetVector3(Index row, Index startColumn, const AZ::Vector3& value);
  102. };
  103. } // namespace EMotionFX::MotionMatching