Fixed SVACE and related issues in dali-scene-loader.
[platform/core/uifw/dali-toolkit.git] / dali-scene-loader / public-api / mesh-definition.h
1 #ifndef DALI_SCENE_LOADER_MESH_DEFINITION_H
2 #define DALI_SCENE_LOADER_MESH_DEFINITION_H
3 /*
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // INTERNAL INCLUDES
21 #include "dali-scene-loader/public-api/api.h"
22 #include "dali-scene-loader/public-api/mesh-geometry.h"
23 #include "dali-scene-loader/public-api/blend-shape-details.h"
24 #include "dali-scene-loader/public-api/utils.h"
25 #include "dali-scene-loader/public-api/index.h"
26
27 // EXTERNAL INCLUDES
28 #include "dali/public-api/common/vector-wrapper.h"
29 #include <memory>
30
31 namespace Dali
32 {
33 namespace SceneLoader
34 {
35
36 /**
37  * @brief Defines a mesh with its attributes, the primitive type to render it as,
38  *  and the file to load it from with the offset and length information for the
39  *  individual attribute buffers.
40  */
41 struct DALI_SCENE_LOADER_API MeshDefinition
42 {
43   using Vector = std::vector<std::pair<MeshDefinition, MeshGeometry>>;
44
45   enum : uint32_t { INVALID = std::numeric_limits<uint32_t>::max() };
46
47   enum Flags : uint16_t
48   {
49     FLIP_UVS_VERTICAL = NthBit(0),
50     U32_INDICES = NthBit(1),  // default is unsigned short
51     U16_JOINT_IDS = NthBit(2), // default is floats
52   };
53
54   enum Attributes
55   {
56     INDICES = NthBit(0),
57     POSITIONS = NthBit(1),
58     NORMALS = NthBit(2),
59     TEX_COORDS = NthBit(3),
60     TANGENTS = NthBit(4),
61     LEGACY_BITANGENTS = NthBit(5),  // these are ignored; we're calculating them in the (PBR) shader.
62     JOINTS_0 = NthBit(6),
63     WEIGHTS_0 = NthBit(7),
64   };
65
66   /**
67    * @brief Describes raw data in terms of its position and size in a buffer.
68    *  All units in bytes.
69    */
70   struct Blob
71   {
72     uint32_t mOffset = INVALID;  // the default means that the blob is undefined.
73     uint32_t mLength = 0;  // if the blob is undefined, its data may still be generated. This is enabled by setting length to some non-0 value. Refer to MeshDefinition for details.
74     uint16_t mStride = 0;  // ignore if 0
75     uint16_t mElementSizeHint = 0;  // ignore if 0 or stride == 0
76     std::vector<float> mMin;
77     std::vector<float> mMax;
78
79     static void ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max, uint32_t count, float* values);
80
81     Blob() = default;
82
83     Blob(uint32_t offset, uint32_t length, uint16_t stride = 0, uint16_t elementSizeHint = 0,
84       const std::vector<float>& min = {}, const std::vector<float>& max = {})
85       : mOffset(offset),
86       mLength(length),
87       mStride(stride),
88       mElementSizeHint(elementSizeHint),
89       mMin(min),
90       mMax(max)
91     {}
92
93     /**
94      * @brief Calculates the size of a tightly-packed buffer for the elements from the blob.
95      */
96     uint32_t GetBufferSize() const;
97
98     /**
99      * @brief Convenience method to tell whether a Blob has meaningful data.
100      */
101     bool IsDefined() const
102     {
103       return mOffset != INVALID;
104     }
105
106     /**
107      * @brief Convenience method to tell whether the elements stored in the blob follow each
108      *  other tightly. The opposite would be interleaving.
109      */
110     bool IsConsecutive() const
111     {
112       return mStride == 0 || mStride == mElementSizeHint;
113     }
114
115     /**
116      * @brief Applies the min / max values, if they're defined.
117      */
118     void ApplyMinMax(uint32_t count, float* values) const;
119   };
120
121   /**
122    * @brief A sparse blob describes a change in a reference Blob.
123    * @p indices describe what positions of the reference Blob change and
124    * @p values describe the new values.
125    */
126   struct SparseBlob
127   {
128     SparseBlob() = default;
129
130     SparseBlob(const Blob& indices, const Blob& values, uint32_t count);
131
132     Blob mIndices;
133     Blob mValues;
134     uint32_t mCount = 0u;
135   };
136
137   struct Accessor
138   {
139     Blob mBlob;
140     std::unique_ptr<SparseBlob> mSparse;
141
142     Accessor() = default;
143
144     Accessor(const Accessor&) = delete;
145     Accessor& operator=(const Accessor&) = delete;
146
147     Accessor(Accessor&&) = default;
148     Accessor& operator=(Accessor&&) = default;
149
150     Accessor(const MeshDefinition::Blob& blob,
151       const MeshDefinition::SparseBlob& sparse);
152
153     bool IsDefined() const
154     {
155       return mBlob.IsDefined() || (mSparse && (mSparse->mIndices.IsDefined() && mSparse->mValues.IsDefined()));
156     }
157   };
158
159   /**
160    * @brief Stores a blend shape.
161    */
162   struct BlendShape
163   {
164     std::string name;
165     Accessor deltas;
166     Accessor normals;
167     Accessor tangents;
168     float weight = 0.f;
169   };
170
171   struct RawData
172   {
173     struct Attrib
174     {
175       std::string mName;
176       Property::Type mType;
177       uint32_t mNumElements;
178       std::vector<uint8_t> mData;
179
180       void AttachBuffer(Geometry& g) const;
181     };
182
183     std::vector<uint16_t> mIndices;
184     std::vector<Attrib> mAttribs;
185
186     unsigned int mBlendShapeBufferOffset;
187     Dali::Vector<float> mBlendShapeUnnormalizeFactor;
188     PixelData mBlendShapeData;
189   };
190
191   MeshDefinition() = default;
192
193   MeshDefinition(const MeshDefinition&) = delete;
194   MeshDefinition& operator=(const MeshDefinition&) = delete;
195
196   MeshDefinition(MeshDefinition&&) = default;
197   MeshDefinition& operator=(MeshDefinition&&) = default;
198
199   /**
200    * @brief Determines whether the mesh definition is that of a quad.
201    */
202   bool IsQuad() const;
203
204   /**
205    * @brief Determines whether the mesh is used for skeletal animation.
206    */
207   bool IsSkinned() const;
208
209   /**
210    * @brief Whether the mesh has blend shapes.
211    */
212   bool HasBlendShapes() const;
213
214   /**
215    * @brief Requests normals to be generated.
216    * @note Generation happens in LoadRaw().
217    * @note Must have Vector3 positions defined.
218    */
219   void RequestNormals();
220
221   /**
222    * @brief Requests tangents to be generated.
223    * @note Generation happens in LoadRaw().
224    * @note Must have Vector3 normals defined.
225    */
226   void RequestTangents();
227
228   /**
229    * @brief Loads raw geometry data, which includes index (optional) and
230    *  attribute buffers, as well as blend shape data. This is then returned.
231    * @note This can be done on any thread.
232    */
233   RawData LoadRaw(const std::string& modelsPath) const;
234
235   /**
236    * @brief Creates a MeshGeometry based firstly on the value of the uri member:
237    *  if it is "quad", a textured quad is created; otherwise it uses the
238    *  attribute (and index) buffers and blend shape information (if available)
239    *  from @a raw.
240    *  If mFlipVertical was set, the UVs are flipped in Y, i.e. v = 1.0 - v.
241    */
242   MeshGeometry Load(RawData&& raw) const;
243
244 public: // DATA
245   uint32_t mFlags = 0x0;
246   Geometry::Type mPrimitiveType = Geometry::TRIANGLES;
247   std::string mUri;
248   Accessor mIndices;
249   Accessor mPositions;
250   Accessor mNormals;  // data can be generated based on positions
251   Accessor mTexCoords;
252   Accessor mTangents;  // data can be generated based on normals and texCoords (the latter isn't mandatory; the results will be better if available)
253   Accessor mJoints0;
254   Accessor mWeights0;
255
256   Blob mBlendShapeHeader;
257   std::vector<BlendShape> mBlendShapes;
258   BlendShapes::Version mBlendShapeVersion = BlendShapes::Version::INVALID;
259
260   Index mSkeletonIdx = INVALID_INDEX;
261 };
262
263 }
264 }
265
266 #endif //DALI_SCENE_LOADER_MESH_DEFINITION_H