CsvSerializers.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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/IO/SystemFile.h>
  10. #include <EMotionFX/Source/Pose.h>
  11. #include <EMotionFX/Source/TransformSpace.h>
  12. namespace EMotionFX
  13. {
  14. class ActorInstance;
  15. };
  16. namespace EMotionFX::MotionMatching
  17. {
  18. class FeatureSchema;
  19. class QueryVector;
  20. //! Base class providing some helpers for saving data to CSV files
  21. class EMFX_API CsvWriterBase
  22. {
  23. public:
  24. virtual ~CsvWriterBase();
  25. protected:
  26. bool OpenFile(const char* filename, int openMode);
  27. virtual void End();
  28. bool IsReady() const { return m_file.IsOpen(); }
  29. void WriteLine(AZStd::string& line);
  30. void WriteVector3ToString(const AZ::Vector3& vec, AZStd::string& text);
  31. void WriteFloatArrayToString(const AZStd::vector<float>& values, AZStd::string& text);
  32. protected:
  33. AZ::IO::SystemFile m_file;
  34. AZStd::string m_tempBuffer;
  35. };
  36. //! Store a list of skeletal poses in a table
  37. //! The first row contains the value component names, e.g. "LeftArm.Position.X"
  38. //! Each following row represents a skeletal pose
  39. //! Position and rotation values for all enabled joints are stored (scale is skipped).
  40. //! Position XYZ is stored in 3x columns. Rotation which internally is stored as a quaternion
  41. //! is converted to a rotation matrix and the XY-axes of it are stored as 6x components/columns.
  42. //! To reconstruct the rotation quaternion, we first need the cross-product of the X and Y axes to
  43. //! get the Z axis, create a rotation matrix from that and then convert it back to a quaternion.
  44. class EMFX_API PoseWriterCsv
  45. : public CsvWriterBase
  46. {
  47. public:
  48. virtual ~PoseWriterCsv() = default;
  49. struct WriteSettings
  50. {
  51. bool m_writePositions = true;
  52. bool m_writeRotations = true;
  53. };
  54. bool Begin(const char* filename, ActorInstance* actorInstance, const WriteSettings& writeSettings);
  55. void WritePose(Pose& pose, const ETransformSpace transformSpace);
  56. void End() override;
  57. private:
  58. void SaveColumnNamesToString(AZStd::string& outText);
  59. void SavePoseToString(Pose& pose, const ETransformSpace transformSpace, AZStd::string& outText);
  60. ActorInstance* m_actorInstance = nullptr;
  61. WriteSettings m_settings;
  62. };
  63. //! Store a list of query vectors in a table
  64. //! The first row contains the names of the features in the very vector
  65. //! based on the currently used feature schema
  66. //! Each following row represents a query vector
  67. class EMFX_API QueryVectorWriterCsv
  68. : public CsvWriterBase
  69. {
  70. public:
  71. virtual ~QueryVectorWriterCsv() = default;
  72. bool Begin(const char* filename, const FeatureSchema* featureSchema);
  73. void Write(const QueryVector* queryVector);
  74. };
  75. //! Store a list of best matching frames in a table
  76. //! The first row contains the column name
  77. //! Each following row represents a best matching frame
  78. class EMFX_API BestMatchingFrameWriterCsv
  79. : public CsvWriterBase
  80. {
  81. public:
  82. virtual ~BestMatchingFrameWriterCsv() = default;
  83. bool Begin(const char* filename);
  84. void Write(size_t frame);
  85. };
  86. //! The counter-part to PoseWriterCsv which loads a CSV file containing poses and can apply
  87. //! them onto an actor instance.
  88. class EMFX_API PoseReaderCsv
  89. {
  90. public:
  91. ~PoseReaderCsv();
  92. struct ReadSettings
  93. {
  94. bool m_readPositions = true;
  95. bool m_readRotations = true;
  96. };
  97. bool Begin(const char* filename, const ReadSettings& readSettings);
  98. void ApplyPose(ActorInstance* actorInstance, Pose& pose, const ETransformSpace transformSpace, size_t index);
  99. size_t GetNumPoses() const { return m_poseValueLines.size(); }
  100. void End();
  101. private:
  102. AZStd::string m_columnNamesLine;
  103. AZStd::vector<AZStd::string> m_poseValueLines;
  104. ReadSettings m_settings;
  105. };
  106. } // namespace EMotionFX::MotionMatching