Overte C++ Documentation
HFM.h
1 //
2 // HFM.h
3 // libraries/hfm/src
4 //
5 // Created by Sabrina Shanman on 2018/11/02.
6 // Copyright 2018 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_HFM_h_
13 #define hifi_HFM_h_
14 
15 #include <QMetaType>
16 #include <QSet>
17 #include <QVector>
18 
19 #include <glm/glm.hpp>
20 #include <glm/gtc/quaternion.hpp>
21 
22 #include <Extents.h>
23 #include <Transform.h>
24 
25 #include <graphics/Geometry.h>
26 #include <graphics/Material.h>
27 
28 #include <image/ColorChannel.h>
29 
30 #if defined(Q_OS_ANDROID)
31 #define HFM_PACK_NORMALS 0
32 #else
33 #define HFM_PACK_NORMALS 1
34 #endif
35 
36 #if HFM_PACK_NORMALS
37 using NormalType = glm::uint32;
38 #define HFM_NORMAL_ELEMENT gpu::Element::VEC4F_NORMALIZED_XYZ10W2
39 #else
40 using NormalType = glm::vec3;
41 #define HFM_NORMAL_ELEMENT gpu::Element::VEC3F_XYZ
42 #endif
43 
44 #define HFM_PACK_COLORS 1
45 
46 #if HFM_PACK_COLORS
47 using ColorType = glm::uint32;
48 #define HFM_COLOR_ELEMENT gpu::Element::COLOR_RGBA_32
49 #else
50 using ColorType = glm::vec3;
51 #define HFM_COLOR_ELEMENT gpu::Element::VEC3F_XYZ
52 #endif
53 
54 const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 8192 * 8192;
55 
56 
57 using ShapeVertices = std::vector<glm::vec3>;
58 // The version of the Draco mesh binary data itself. See also: FBX_DRACO_MESH_VERSION in FBX.h
59 static const int DRACO_MESH_VERSION = 3;
60 
61 static const int DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES = 1000;
62 static const int DRACO_ATTRIBUTE_MATERIAL_ID = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES;
63 static const int DRACO_ATTRIBUTE_TEX_COORD_1 = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES + 1;
64 static const int DRACO_ATTRIBUTE_ORIGINAL_INDEX = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES + 2;
65 
66 // High Fidelity Model namespace
67 namespace hfm {
68 
70 class Blendshape {
71 public:
72  QVector<int> indices;
73  QVector<glm::vec3> vertices;
74  QVector<glm::vec3> normals;
75  QVector<glm::vec3> tangents;
76 };
77 
78 struct JointShapeInfo {
79  // same units and frame as Joint.translation
80  glm::vec3 avgPoint;
81  std::vector<float> dots;
82  std::vector<glm::vec3> points;
83  std::vector<glm::vec3> debugLines;
84 };
85 
87 class Joint {
88 public:
89  JointShapeInfo shapeInfo;
90  int parentIndex;
91  float distanceToParent;
92 
93  // http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/SDKRef/a00209.html
94 
95  glm::vec3 translation; // T
96  glm::mat4 preTransform; // Roff * Rp
97  glm::quat preRotation; // Rpre
98  glm::quat rotation; // R
99  glm::quat postRotation; // Rpost
100  glm::mat4 postTransform; // Rp-1 * Soff * Sp * S * Sp-1
101 
102  // World = ParentWorld * T * (Roff * Rp) * Rpre * R * Rpost * (Rp-1 * Soff * Sp * S * Sp-1)
103 
104  glm::mat4 transform;
105  glm::vec3 rotationMin; // radians
106  glm::vec3 rotationMax; // radians
107  glm::quat inverseDefaultRotation;
108  glm::quat inverseBindRotation;
109  glm::mat4 bindTransform;
110  QString name;
111  bool isSkeletonJoint;
112  bool bindTransformFoundInCluster;
113 
114  // geometric offset is applied in local space but does NOT affect children.
115  bool hasGeometricOffset;
116  glm::vec3 geometricTranslation;
117  glm::quat geometricRotation;
118  glm::vec3 geometricScaling;
119 };
120 
121 
123 class Cluster {
124 public:
125 
126  int jointIndex;
127  glm::mat4 inverseBindMatrix;
128  Transform inverseBindTransform;
129 };
130 
132 class Texture {
133 public:
134 
135  QString id;
136  QString name;
137  QByteArray filename;
138  QByteArray content;
139  image::ColorChannel sourceChannel { image::ColorChannel::NONE };
140 
141  Transform transform;
142  int maxNumPixels { MAX_NUM_PIXELS_FOR_FBX_TEXTURE };
143  int texcoordSet;
144  QString texcoordSetName;
145 
146  bool isBumpmap{ false };
147 
148  bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
149 };
150 
152 class MeshPart {
153 public:
154 
155  QVector<int> quadIndices; // original indices from the FBX mesh
156  QVector<int> quadTrianglesIndices; // original indices from the FBX mesh of the quad converted as triangles
157  QVector<int> triangleIndices; // original indices from the FBX mesh
158 
159  QString materialID;
160 };
161 
162 class Material {
163 public:
164  Material() {};
165  Material(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor,
166  float shininess, float opacity) :
167  diffuseColor(diffuseColor),
168  specularColor(specularColor),
169  emissiveColor(emissiveColor),
170  shininess(shininess),
171  opacity(opacity) {}
172 
173  void getTextureNames(QSet<QString>& textureList) const;
174  void setMaxNumPixelsPerTexture(int maxNumPixels);
175 
176  glm::vec3 diffuseColor { 1.0f };
177  float diffuseFactor { 1.0f };
178  glm::vec3 specularColor { 0.02f };
179  float specularFactor { 1.0f };
180 
181  glm::vec3 emissiveColor { 0.0f };
182  float emissiveFactor { 0.0f };
183 
184  float shininess { 23.0f };
185  float opacity { 1.0f };
186 
187  float metallic { 0.0f };
188  float roughness { 1.0f };
189  float emissiveIntensity { 1.0f };
190  float ambientFactor { 1.0f };
191 
192  float bumpMultiplier { 1.0f }; // TODO: to be implemented
193 
194  graphics::MaterialKey::OpacityMapMode alphaMode { graphics::MaterialKey::OPACITY_MAP_BLEND };
195  float alphaCutoff { 0.5f };
196 
197  QString materialID;
198  QString name;
199  QString shadingModel;
200  graphics::MaterialPointer _material;
201 
202  Texture normalTexture;
203  Texture albedoTexture;
204  Texture opacityTexture;
205  Texture glossTexture;
206  Texture roughnessTexture;
207  Texture specularTexture;
208  Texture metallicTexture;
209  Texture emissiveTexture;
210  Texture occlusionTexture;
211  Texture scatteringTexture;
212  Texture lightmapTexture;
213  glm::vec2 lightmapParams { 0.0f, 1.0f };
214 
215 
216  bool isPBSMaterial { false };
217  // THe use XXXMap are not really used to drive which map are going or not, debug only
218  bool useNormalMap { false };
219  bool useAlbedoMap { false };
220  bool useOpacityMap { false };
221  bool useRoughnessMap { false };
222  bool useSpecularMap { false };
223  bool useMetallicMap { false };
224  bool useEmissiveMap { false };
225  bool useOcclusionMap { false };
226 
227 
228  bool isMToonMaterial { false };
229  Texture shadeTexture;
230  Texture shadingShiftTexture;
231  Texture matcapTexture;
232  Texture rimTexture;
233  Texture uvAnimationTexture;
234 
235  bool needTangentSpace() const;
236 };
237 
239 class Mesh {
240 public:
241 
242  QVector<MeshPart> parts;
243 
244  QVector<glm::vec3> vertices;
245  QVector<glm::vec3> normals;
246  QVector<glm::vec3> tangents;
247  QVector<glm::vec3> colors;
248  QVector<glm::vec2> texCoords;
249  QVector<glm::vec2> texCoords1;
250  QVector<uint16_t> clusterIndices;
251  QVector<uint16_t> clusterWeights;
252  QVector<int32_t> originalIndices;
253 
254  QVector<Cluster> clusters;
255 
256  Extents meshExtents;
257  glm::mat4 modelTransform;
258 
259  QVector<Blendshape> blendshapes;
260 
261  unsigned int meshIndex; // the order the meshes appeared in the object file
262 
263  graphics::MeshPointer _mesh;
264  bool wasCompressed { false };
265 };
266 
269 public:
270  QVector<glm::quat> rotations;
271  QVector<glm::vec3> translations;
272 };
273 
275 class Light {
276 public:
277  QString name;
278  Transform transform;
279  float intensity;
280  float fogValue;
281  glm::vec3 color;
282 
283  Light() :
284  name(),
285  transform(),
286  intensity(1.0f),
287  fogValue(0.0f),
288  color(1.0f)
289  {}
290 };
291 
292 class FlowData {
293 public:
294  FlowData() {};
295  QVariantMap _physicsConfig;
296  QVariantMap _collisionsConfig;
297  bool shouldInitFlow() const { return _physicsConfig.size() > 0; }
298  bool shouldInitCollisions() const { return _collisionsConfig.size() > 0; }
299 };
300 
302 class Model {
303 public:
304  using Pointer = std::shared_ptr<Model>;
305  using ConstPointer = std::shared_ptr<const Model>;
306 
307  QString originalURL;
308  QString author;
309  QString applicationName;
310 
311  QVector<Joint> joints;
312  QHash<QString, int> jointIndices;
313  bool hasSkeletonJoints;
314 
315  QVector<Mesh> meshes;
316  QVector<QString> scripts;
317 
318  QHash<QString, Material> materials;
319 
320  glm::mat4 offset; // This includes offset, rotation, and scale as specified by the FST file
321 
322  glm::vec3 neckPivot;
323 
324  Extents bindExtents;
325  Extents meshExtents;
326 
327  QVector<AnimationFrame> animationFrames;
328 
329  int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; }
330  QStringList getJointNames() const;
331 
332  bool hasBlendedMeshes() const;
333 
335  Extents getUnscaledMeshExtents() const;
336  const Extents& getMeshExtents() const { return meshExtents; }
337 
338  bool convexHullContains(const glm::vec3& point) const;
339 
340  QHash<int, QString> meshIndicesToModelNames;
341 
343  QString getModelNameOfMesh(int meshIndex) const;
344  void computeKdops();
345 
346  QList<QString> blendshapeChannelNames;
347 
348  QMap<int, glm::quat> jointRotationOffsets;
349  std::vector<ShapeVertices> shapeVertices;
350  FlowData flowData;
351 
352  void debugDump();
353 
363 
371  int loadErrorCount = 0;
372 
373 };
374 
375 };
376 
377 class ExtractedMesh {
378 public:
379  hfm::Mesh mesh;
380  QMultiHash<int, int> newIndices;
381  QVector<QHash<int, int> > blendshapeIndexMaps;
382  QVector<QPair<int, int> > partMaterialTextures;
383  QHash<QString, size_t> texcoordSetMap;
384 };
385 
387 typedef hfm::JointShapeInfo HFMJointShapeInfo;
388 typedef hfm::Joint HFMJoint;
389 typedef hfm::Cluster HFMCluster;
390 typedef hfm::Texture HFMTexture;
391 typedef hfm::MeshPart HFMMeshPart;
392 typedef hfm::Material HFMMaterial;
393 typedef hfm::Mesh HFMMesh;
395 typedef hfm::Light HFMLight;
396 typedef hfm::Model HFMModel;
397 typedef hfm::FlowData FlowData;
398 
399 Q_DECLARE_METATYPE(HFMAnimationFrame)
400 Q_DECLARE_METATYPE(QVector<HFMAnimationFrame>)
401 Q_DECLARE_METATYPE(HFMModel)
402 Q_DECLARE_METATYPE(HFMModel::Pointer)
403 
404 #endif // hifi_HFM_h_
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39
A single animation frame.
Definition: HFM.h:268
A single blendshape.
Definition: HFM.h:70
A single binding to a joint.
Definition: HFM.h:123
A single joint (transformation node).
Definition: HFM.h:87
A light.
Definition: HFM.h:275
A single mesh (with optional blendshapes).
Definition: HFM.h:239
A single part of a mesh (with the same material).
Definition: HFM.h:152
The runtime model format.
Definition: HFM.h:302
Extents getUnscaledMeshExtents() const
Returns the unscaled extents of the model's mesh.
Definition: HFM.cpp:113
int loadWarningCount
Get the number of warnings that were generated when loading this model.
Definition: HFM.h:362
int loadErrorCount
Get the number of errors that were generated when loading this model.
Definition: HFM.h:371
QString applicationName
the name of the application that generated the model
Definition: HFM.h:309
QHash< QString, int > jointIndices
1-based, so as to more easily detect missing indices
Definition: HFM.h:312
QString getModelNameOfMesh(int meshIndex) const
given a meshIndex this will return the name of the model that mesh belongs to if known
Definition: HFM.cpp:175
A texture map.
Definition: HFM.h:132