1 #ifndef DALI_SCENE_LOADER_MESH_DEFINITION_H
2 #define DALI_SCENE_LOADER_MESH_DEFINITION_H
4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
28 #include "dali/public-api/common/vector-wrapper.h"
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.
41 struct DALI_SCENE_LOADER_API MeshDefinition
43 using Vector = std::vector<std::pair<MeshDefinition, MeshGeometry>>;
45 enum : uint32_t { INVALID = std::numeric_limits<uint32_t>::max() };
49 FLIP_UVS_VERTICAL = NthBit(0),
50 U32_INDICES = NthBit(1), // default is unsigned short
51 U16_JOINT_IDS = NthBit(2), // default is floats
57 POSITIONS = NthBit(1),
59 TEX_COORDS = NthBit(3),
61 LEGACY_BITANGENTS = NthBit(5), // these are ignored; we're calculating them in the (PBR) shader.
63 WEIGHTS_0 = NthBit(7),
67 * @brief Describes raw data in terms of its position and size in a buffer.
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;
79 static void ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max, uint32_t count, float* values);
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 = {});
87 * @brief Calculates the size of a tightly-packed buffer for the elements from the blob.
89 uint32_t GetBufferSize() const;
92 * @brief Convenience method to tell whether a Blob has meaningful data.
94 bool IsDefined() const
96 return mOffset != INVALID;
100 * @brief Convenience method to tell whether the elements stored in the blob follow each
101 * other tightly. The opposite would be interleaving.
103 bool IsConsecutive() const
105 return mStride == 0 || mStride == mElementSizeHint;
109 * @brief Applies the min / max values, if they're defined.
111 void ApplyMinMax(uint32_t count, float* values) const;
115 * @brief A sparse blob describes a change in a reference Blob.
116 * @p indices describe what positions of the reference Blob change and
117 * @p values describe the new values.
121 SparseBlob() = default;
123 SparseBlob(const Blob& indices, const Blob& values, uint32_t count);
127 uint32_t mCount = 0u;
133 std::unique_ptr<SparseBlob> mSparse;
135 Accessor() = default;
137 Accessor(const Accessor&) = delete;
138 Accessor& operator=(const Accessor&) = delete;
140 Accessor(Accessor&&) = default;
141 Accessor& operator=(Accessor&&) = default;
143 Accessor(const MeshDefinition::Blob& blob,
144 const MeshDefinition::SparseBlob& sparse);
146 bool IsDefined() const
148 return mBlob.IsDefined() || (mSparse && (mSparse->mIndices.IsDefined() && mSparse->mValues.IsDefined()));
153 * @brief Stores a blend shape.
169 Property::Type mType;
170 uint32_t mNumElements;
171 std::vector<uint8_t> mData;
173 void AttachBuffer(Geometry& g) const;
176 std::vector<uint16_t> mIndices;
177 std::vector<Attrib> mAttribs;
179 unsigned int mBlendShapeBufferOffset;
180 Dali::Vector<float> mBlendShapeUnnormalizeFactor;
181 PixelData mBlendShapeData;
184 MeshDefinition() = default;
186 MeshDefinition(const MeshDefinition&) = delete;
187 MeshDefinition& operator=(const MeshDefinition&) = delete;
189 MeshDefinition(MeshDefinition&&) = default;
190 MeshDefinition& operator=(MeshDefinition&&) = default;
193 * @brief Determines whether the mesh definition is that of a quad.
198 * @brief Determines whether the mesh is used for skeletal animation.
200 bool IsSkinned() const;
203 * @brief Whether the mesh has blend shapes.
205 bool HasBlendShapes() const;
208 * @brief Requests normals to be generated.
209 * @note Generation happens in LoadRaw().
210 * @note Must have Vector3 positions defined.
212 void RequestNormals();
215 * @brief Requests tangents to be generated.
216 * @note Generation happens in LoadRaw().
217 * @note Must have Vector3 normals defined.
219 void RequestTangents();
222 * @brief Loads raw geometry data, which includes index (optional) and
223 * attribute buffers, as well as blend shape data. This is then returned.
224 * @note This can be done on any thread.
226 RawData LoadRaw(const std::string& modelsPath) const;
229 * @brief Creates a MeshGeometry based firstly on the value of the uri member:
230 * if it is "quad", a textured quad is created; otherwise it uses the
231 * attribute (and index) buffers and blend shape information (if available)
233 * If mFlipVertical was set, the UVs are flipped in Y, i.e. v = 1.0 - v.
235 MeshGeometry Load(RawData&& raw) const;
238 uint32_t mFlags = 0x0;
239 Geometry::Type mPrimitiveType = Geometry::TRIANGLES;
243 Accessor mNormals; // data can be generated based on positions
245 Accessor mTangents; // data can be generated based on normals and texCoords (the latter isn't mandatory; the results will be better if available)
249 Blob mBlendShapeHeader;
250 std::vector<BlendShape> mBlendShapes;
251 BlendShapes::Version mBlendShapeVersion = BlendShapes::Version::INVALID;
253 Index mSkeletonIdx = INVALID_INDEX;
259 #endif //DALI_SCENE_LOADER_MESH_DEFINITION_H