Limited joint/weight attributes to 4 sets
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / mesh-definition.h
index 595d06e..ec3e160 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_MESH_DEFINITION_H
 #define DALI_SCENE3D_LOADER_MESH_DEFINITION_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/blend-shape-details.h"
-#include "dali-scene3d/public-api/loader/index.h"
-#include "dali-scene3d/public-api/loader/mesh-geometry.h"
-#include "dali-scene3d/public-api/loader/utils.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <memory>
-#include "dali/public-api/common/vector-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/blend-shape-details.h>
+#include <dali-scene3d/public-api/loader/buffer-definition.h>
+#include <dali-scene3d/public-api/loader/index.h>
+#include <dali-scene3d/public-api/loader/mesh-geometry.h>
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Defines a mesh with its attributes, the primitive type to render it as,
@@ -48,11 +45,40 @@ struct DALI_SCENE3D_API MeshDefinition
     INVALID = std::numeric_limits<uint32_t>::max()
   };
 
-  enum Flags : uint16_t
+  enum : uint32_t
+  {
+    MAX_NUMBER_OF_JOINT_SETS = 4
+  };
+
+  enum Flags : uint32_t
   {
     FLIP_UVS_VERTICAL = NthBit(0),
     U32_INDICES       = NthBit(1), // default is unsigned short
-    U16_JOINT_IDS     = NthBit(2), // default is floats
+    U8_INDICES        = NthBit(2), // default is unsigned short
+    U16_JOINT_IDS     = NthBit(3), // default is floats
+    U8_JOINT_IDS      = NthBit(4),
+    U16_WEIGHT        = NthBit(5), // default is floats
+    U8_WEIGHT         = NthBit(6),
+    S8_POSITION       = NthBit(7),  // default is floats
+    U8_POSITION       = NthBit(8),  // default is floats
+    S16_POSITION      = NthBit(9),  // default is floats
+    U16_POSITION      = NthBit(10), // default is floats
+    S8_NORMAL         = NthBit(11), // default is floats
+    S16_NORMAL        = NthBit(12), // default is floats
+    S8_TANGENT        = NthBit(13), // default is floats
+    S16_TANGENT       = NthBit(14), // default is floats
+    S8_TEXCOORD       = NthBit(15), // default is floats
+    U8_TEXCOORD       = NthBit(16), // default is floats
+    S16_TEXCOORD      = NthBit(17), // default is floats
+    U16_TEXCOORD      = NthBit(18), // default is floats
+  };
+
+  enum FlagMasks : uint32_t
+  {
+    POSITIONS_MASK = 0x780,
+    NORMALS_MASK   = 0x1800,
+    TANGENTS_MASK  = 0x6000,
+    TEXCOORDS_MASK = 0x78000,
   };
 
   enum Attributes
@@ -82,7 +108,7 @@ struct DALI_SCENE3D_API MeshDefinition
 
     static void ComputeMinMax(std::vector<float>& min, std::vector<float>& max, uint32_t numComponents, uint32_t count, const float* values);
 
-    static void ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max, uint32_t count, float* values);
+    static void ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max, uint32_t count, float* values, std::vector<uint32_t>* sparseIndices = nullptr);
 
     Blob() = default;
 
@@ -131,8 +157,10 @@ struct DALI_SCENE3D_API MeshDefinition
      *
      * @param[in] count The number of data.
      * @param[in] values Data for the mesh that min / max values will be applied.
+     * @param[in] sparseIndices Pointer to array of sparse indices (or nullptr if not provided)
+     *
      */
-    void ApplyMinMax(uint32_t count, float* values) const;
+    void ApplyMinMax(uint32_t count, float* values, std::vector<uint32_t>* sparseIndices = nullptr) const;
   };
 
   /**
@@ -162,6 +190,8 @@ struct DALI_SCENE3D_API MeshDefinition
   {
     Blob                        mBlob;
     std::unique_ptr<SparseBlob> mSparse;
+    Index                       mBufferIdx = INVALID_INDEX;
+    bool                        mNormalized{false};
 
     Accessor() = default;
 
@@ -172,9 +202,14 @@ struct DALI_SCENE3D_API MeshDefinition
     Accessor& operator=(Accessor&&) = default;
 
     Accessor(const MeshDefinition::Blob&       blob,
-             const MeshDefinition::SparseBlob& sparse);
+             const MeshDefinition::SparseBlob& sparse,
+             Index                             bufferIndex = INVALID_INDEX,
+             bool                              normalized = false);
+
     Accessor(MeshDefinition::Blob&&       blob,
-             MeshDefinition::SparseBlob&& sparse);
+             MeshDefinition::SparseBlob&& sparse,
+             Index                        bufferIndex = INVALID_INDEX,
+             bool                         normalized = false);
 
     bool IsDefined() const
     {
@@ -192,6 +227,7 @@ struct DALI_SCENE3D_API MeshDefinition
     Accessor    normals;
     Accessor    tangents;
     float       weight = 0.f;
+    uint32_t    mFlags = 0x0;
   };
 
   struct RawData
@@ -233,6 +269,18 @@ struct DALI_SCENE3D_API MeshDefinition
   bool IsSkinned() const;
 
   /**
+   * @brief Determines if the mesh has any vertex colors
+   */
+  bool HasVertexColor() const;
+
+  /**
+   * @brief Returns the number of joint sets defined by the mesh
+   *
+   * @note Clamped to 4 to minimise GPU attrs.
+   */
+  uint32_t GetNumberOfJointSets() const;
+
+  /**
    * @brief Whether the mesh has blend shapes.
    */
   bool HasBlendShapes() const;
@@ -256,7 +304,7 @@ struct DALI_SCENE3D_API MeshDefinition
    *  attribute buffers, as well as blend shape data. This is then returned.
    * @note This can be done on any thread.
    */
-  RawData LoadRaw(const std::string& modelsPath);
+  RawData LoadRaw(const std::string& modelsPath, BufferDefinition::Vector& buffers);
 
   /**
    * @brief Creates a MeshGeometry based firstly on the value of the uri member:
@@ -267,29 +315,38 @@ struct DALI_SCENE3D_API MeshDefinition
    */
   MeshGeometry Load(RawData&& raw) const;
 
+  /**
+   * @brief Retrieves what Components information is in this mesh's BlendShape.
+   *
+   * @param[out] hasPositions True if the BlendShape has position components
+   * @param[out] hasNormals True if the BlendShape has normal components
+   * @param[out] hasTangents True if the BlendShape has tangent components
+   */
+  void RetrieveBlendShapeComponents(bool& hasPositions, bool& hasNormals, bool& hasTangents) const;
+
 public: // DATA
-  uint32_t       mFlags         = 0x0;
-  Geometry::Type mPrimitiveType = Geometry::TRIANGLES;
-  std::string    mUri;
-  Accessor       mIndices;
-  Accessor       mPositions;
-  Accessor       mNormals; // data can be generated based on positions
-  Accessor       mTexCoords;
-  Accessor       mColors;
-  Accessor       mTangents; // data can be generated based on normals and texCoords (the latter isn't mandatory; the results will be better if available)
-  Accessor       mJoints0;
-  Accessor       mWeights0;
-  Property::Type mTangentType{Property::VECTOR3};
+  std::shared_ptr<RawData> mRawData;
+  uint32_t                 mFlags         = 0x0;
+  Geometry::Type           mPrimitiveType = Geometry::TRIANGLES;
+  std::string              mUri; // When the mesh data is loaded from embedded resources, this URI is used as a data stream.
+  Accessor                 mIndices;
+  Accessor                 mPositions;
+  Accessor                 mNormals;  // data can be generated based on positions
+  Accessor                 mTangents; // data can be generated based on normals and texCoords (the latter isn't mandatory; the results will be better if available)
+  std::vector<Accessor>    mTexCoords;
+  std::vector<Accessor>    mColors;
+  std::vector<Accessor>    mJoints;
+  std::vector<Accessor>    mWeights;
+  Property::Type           mTangentType{Property::VECTOR3};
 
   Blob                    mBlendShapeHeader;
   std::vector<BlendShape> mBlendShapes;
   BlendShapes::Version    mBlendShapeVersion = BlendShapes::Version::INVALID;
 
-  Index mSkeletonIdx = INVALID_INDEX;
+  Index          mSkeletonIdx = INVALID_INDEX;
+  ModelPrimitive mModelPrimitive;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_MESH_DEFINITION_H