DatasmithUtils.h
1 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
2 #pragma once
3 
4 #include "DatasmithDefinitions.h"
5 
6 #include "Containers/Array.h"
7 #include "Containers/UnrealString.h"
8 #include "Math/Vector.h"
9 
10 class FDatasmithMesh;
11 struct FMeshDescription;
12 struct FRawMesh;
13 
14 class DATASMITHCORE_API FDatasmithUtils
15 {
16 public:
17  static void SanitizeNameInplace(FString& InString);
18  static FString SanitizeName(FString InString);
19  static FString SanitizeObjectName(FString InString);
20  static FString SanitizeFileName(FString InString);
21 
22  static float GetEnterpriseVersionAsFloat();
23  static int32 GetEnterpriseVersionAsInt();
24  static FString GetEnterpriseVersionAsString();
25 
26  /** Returns the Datasmith data format version */
27  static float GetDatasmithFormatVersionAsFloat();
28  static int32 GetDatasmithFormatVersionAsInt();
29  static FString GetDatasmithFormatVersionAsString();
30 
31  /** Returns the file extension without the dot, of the DatasmithScene. Currently udatasmith */
32  static const TCHAR* GetFileExtension();
33 
34  /** Returns the long name of Datasmith */
35  static const TCHAR* GetLongAppName();
36  /** Returns the abbreviated name of Datasmith */
37  static const TCHAR* GetShortAppName();
38 
39  /** Computes the area of a triangle */
40  static double AreaTriangle3D(FVector v0, FVector v1, FVector v2);
41 
42  enum class EModelCoordSystem : uint8
43  {
44  ZUp_LeftHanded,
45  ZUp_RightHanded,
46  YUp_LeftHanded,
47  YUp_RightHanded,
48  };
49 
50  template<typename VecType>
51  static FVector ConvertVector(EModelCoordSystem ModelCoordSys, const VecType& V)
52  {
53  switch (ModelCoordSys)
54  {
55  case EModelCoordSystem::YUp_LeftHanded:
56  return FVector(V[2], V[0], V[1]);
57 
58  case EModelCoordSystem::YUp_RightHanded:
59  return FVector(-V[2], V[0], V[1]);
60 
61  case EModelCoordSystem::ZUp_RightHanded:
62  return FVector(-V[0], V[1], V[2]);
63 
64  case EModelCoordSystem::ZUp_LeftHanded:
65  default:
66  return FVector(V[0], V[1], V[2]);
67  }
68  }
69 
70  FTransform static ConvertTransform(EModelCoordSystem SourceCoordSystem, const FTransform& LocalTransform);
71 
72  FMatrix static GetSymmetricMatrix(const FVector& Origin, const FVector& Normal);
73 };
74 
75 class DATASMITHCORE_API FDatasmithMeshUtils
76 {
77 public:
78  /**
79  * @param bValidateRawMesh this boolean indicate if the raw must be valid.
80  * For example a collision mesh don't need to have a valid raw mesh
81  */
82  static bool ToRawMesh(const FDatasmithMesh& Mesh, FRawMesh& RawMesh, bool bValidateRawMesh = true);
83  static bool ToMeshDescription(FDatasmithMesh& DsMesh, FMeshDescription& MeshDescription);
84 
85 
86  /**
87  * Validates that the given UV Channel does not contain a degenerated triangle.
88  *
89  * @param DSMesh The DatasmithMesh to validate.
90  * @param Channel The UV channel to validate, starting at 0
91  */
92  static bool IsUVChannelValid(const FDatasmithMesh& DsMesh, const int32 Channel);
93 };
94 
95 enum class EDSTextureUtilsError : int32
96 {
97  NoError = 0,
98  FileNotFound = -1,
99  InvalidFileType = -2,
100  FileReadIssue = -3,
101  InvalidData = -4,
102  FreeImageNotFound = -5,
103  FileNotSaved = -6,
104  ResizeFailed = -7,
105 };
106 
107 /**
108  * NoResize: Keep original size
109  * NearestPowerOfTwo: resizes to the nearest power of two value (recommended)
110  * PreviousPowerOfTwo: it decreases the value to the previous power of two
111  * NextPowerOfTwo: it increases the value to the next power of two
112  */
113 enum class EDSResizeTextureMode
114 {
115  NoResize,
116  NearestPowerOfTwo,
117  PreviousPowerOfTwo,
118  NextPowerOfTwo
119 };
120 
121 class DATASMITHCORE_API FDatasmithTextureUtils
122 {
123 public:
124  static bool CalculateTextureHash(const TSharedPtr<class IDatasmithTextureElement>& TextureElement);
125  static void CalculateTextureHashes(const TSharedPtr<class IDatasmithScene>& Scene);
126 };
127 
128 /**
129  * Enum mainly used to describe which components of a transform animation are enabled. Should mostly be
130  * used with FDatasmithAnimationUtils::GetChannelTypeComponents
131  */
132 enum class ETransformChannelComponents : uint8
133 {
134  None = 0x00,
135  X = 0x01,
136  Y = 0x02,
137  Z = 0x04,
138  All = X | Y | Z,
139 };
140 ENUM_CLASS_FLAGS(ETransformChannelComponents);
141 
142 class DATASMITHCORE_API FDatasmithAnimationUtils
143 {
144 public:
145  /** Utility to help handling the components of a channel independently of the transform type **/
146  static ETransformChannelComponents GetChannelTypeComponents(EDatasmithTransformChannels Channels, EDatasmithTransformType TransformType);
147 
148  /** Utility to help assembling a transform type's components into a EDatasmithTransformChannels enum **/
149  static EDatasmithTransformChannels SetChannelTypeComponents(ETransformChannelComponents Components, EDatasmithTransformType TransformType);
150 };
151 
152 class DATASMITHCORE_API FDatasmithSceneUtils
153 {
154 public:
155  static TArray<TSharedPtr<class IDatasmithCameraActorElement>> GetAllCameraActorsFromScene(const TSharedPtr<class IDatasmithScene>& Scene);
156  static TArray<TSharedPtr<class IDatasmithLightActorElement>> GetAllLightActorsFromScene(const TSharedPtr<class IDatasmithScene>& Scene);
157  static TArray<TSharedPtr<class IDatasmithMeshActorElement>> GetAllMeshActorsFromScene(const TSharedPtr<class IDatasmithScene>& Scene);
158  static TArray<TSharedPtr<class IDatasmithCustomActorElement>> GetAllCustomActorsFromScene(const TSharedPtr<class IDatasmithScene>& Scene);
159 
160  using TActorHierarchy = TArray<TSharedPtr<class IDatasmithActorElement>, TInlineAllocator<8>>;
161  static bool FindActorHierarchy(const IDatasmithScene* Scene, const TSharedPtr<IDatasmithActorElement>& ToFind, TActorHierarchy& OutHierarchy);
162 
163  static bool IsMaterialIDUsedInScene(const TSharedPtr<class IDatasmithScene>& Scene, const TSharedPtr<class IDatasmithMaterialIDElement>& MaterialElement);
164  static bool IsPostProcessUsedInScene(const TSharedPtr<class IDatasmithScene>& Scene, const TSharedPtr<class IDatasmithPostProcessElement>& PostProcessElement);
165 };
166 
167 /**
168  * Based on a table of frequently used names, this class generates unique names
169  * with a good complexity when the number of name is important.
170  * @note: This abstact class allows various implementation of the cache of known name.
171  * Implementation could use a simple TSet, or reuse existing specific cache structure
172  */
173 class DATASMITHCORE_API FDatasmithUniqueNameProviderBase
174 {
175 public:
176  virtual ~FDatasmithUniqueNameProviderBase() = default;
177 
178  /**
179  * Generates a unique name
180  * @param BaseName Name that will be suffixed with an index to be unique
181  * @return FString unique name. Calling "Contains()" with this name will be false
182  */
183  FString GenerateUniqueName(const FString& BaseName);
184 
185  /**
186  * Register a name as known
187  * @param Name name to register
188  */
189  virtual void AddExistingName(const FString& Name) = 0;
190 
191  /**
192  * Remove a name from the list of existing name
193  * @param Name name to unregister
194  */
195  virtual void RemoveExistingName(const FString& Name) = 0;
196 
197 protected:
198 
199  /**
200  * Check if the given name is already registered
201  *
202  * @param Name name to test
203  * @return true if the name is in the cache
204  */
205  virtual bool Contains(const FString& Name) = 0;
206 
207 private:
208  TMap<FString, int32> FrequentlyUsedNames;
209 };
210 
211 /**
212  * Name provider with internal cache implemented with a simple TSet
213  */
215 {
216 public:
217  void Reserve( int32 NumberOfName ) { KnownNames.Reserve(NumberOfName); }
218 
219  virtual void AddExistingName(const FString& Name) override { KnownNames.Add(Name); }
220  virtual void RemoveExistingName(const FString& Name) override { KnownNames.Remove(Name); }
221 
222 protected:
223  virtual bool Contains(const FString& Name) override { return KnownNames.Contains(Name); }
224 
225 private:
226  TSet<FString> KnownNames;
227 };
228 
229 
230 class DATASMITHCORE_API FDatasmithTransformUtils
231 {
232  /**
233  * Get rotation from FTransform and fix floating point precision issues with quaternion
234  */
235 public:
236  static void GetRotation(const FTransform& InTransform, FQuat& OutRotation)
237  {
238  OutRotation = InTransform.GetRotation();
239 
240  // Workaround to floating point precision issues with quaternion
241  {
242  // this value was found from ONE experience, so I'm waiting on other problem to improve it
243  if (fabs(OutRotation.X) < 0.005) OutRotation.X = 0;
244  if (fabs(OutRotation.Y) < 0.005) OutRotation.Y = 0;
245  if (fabs(OutRotation.Z) < 0.005) OutRotation.Z = 0;
246  if (fabs(OutRotation.W) > 0.999) OutRotation.W = 1;
247  OutRotation.Normalize();
248  }
249  }
250 };
FDatasmithAnimationUtils
Definition: DatasmithUtils.h:142
FDatasmithMesh
Definition: DatasmithMesh.h:6
IDatasmithScene
Definition: IDatasmithSceneElements.h:1405
FDatasmithSceneUtils
Definition: DatasmithUtils.h:152
FDatasmithUniqueNameProvider::AddExistingName
virtual void AddExistingName(const FString &Name) override
Register a name as known.
Definition: DatasmithUtils.h:219
FDatasmithUniqueNameProvider::Contains
virtual bool Contains(const FString &Name) override
Check if the given name is already registered.
Definition: DatasmithUtils.h:223
FDatasmithTransformUtils
Definition: DatasmithUtils.h:230
FDatasmithUniqueNameProviderBase
Based on a table of frequently used names, this class generates unique names with a good complexity w...
Definition: DatasmithUtils.h:173
FDatasmithMeshUtils
Definition: DatasmithUtils.h:75
FDatasmithUniqueNameProvider::RemoveExistingName
virtual void RemoveExistingName(const FString &Name) override
Remove a name from the list of existing name.
Definition: DatasmithUtils.h:220
FDatasmithUtils
Definition: DatasmithUtils.h:14
FDatasmithTextureUtils
Definition: DatasmithUtils.h:121
FDatasmithUniqueNameProvider
Name provider with internal cache implemented with a simple TSet.
Definition: DatasmithUtils.h:214
FDatasmithTransformUtils::GetRotation
static void GetRotation(const FTransform &InTransform, FQuat &OutRotation)
Get rotation from FTransform and fix floating point precision issues with quaternion.
Definition: DatasmithUtils.h:236