[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / model3d-view / obj-loader.h
1 #ifndef DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H
2 #define DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/rendering/renderer.h>
23 #include <limits>
24
25 namespace Dali
26 {
27 namespace Toolkit
28 {
29 namespace Internal
30 {
31 class ObjLoader
32 {
33 public:
34   struct TriIndex
35   {
36     int pointIndex[3];
37     int normalIndex[3];
38     int textureIndex[3];
39   };
40
41   struct Vertex
42   {
43     Vertex()
44     {
45     }
46
47     Vertex(const Vector3& position, const Vector3& normal, const Vector2& textureCoord)
48     : position(position),
49       normal(normal)
50     {
51     }
52
53     Vector3 position;
54     Vector3 normal;
55   };
56
57   struct VertexExt
58   {
59     VertexExt()
60     {
61     }
62
63     VertexExt(const Vector3& tangent, const Vector3& binormal)
64     : tangent(tangent),
65       bitangent(binormal)
66     {
67     }
68
69     Vector3 tangent;
70     Vector3 bitangent;
71   };
72
73   struct BoundingVolume
74   {
75     void Init()
76     {
77       pointMin = Vector3(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
78       pointMax = Vector3(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
79     }
80
81     void ConsiderNewPointInVolume(const Vector3& position)
82     {
83       pointMin.x = std::min(position.x, pointMin.x);
84       pointMin.y = std::min(position.y, pointMin.y);
85       pointMin.z = std::min(position.z, pointMin.z);
86
87       pointMax.x = std::max(position.x, pointMax.x);
88       pointMax.y = std::max(position.y, pointMax.y);
89       pointMax.z = std::max(position.z, pointMax.z);
90     }
91
92     Vector3 pointMin;
93     Vector3 pointMax;
94   };
95
96   //Defines bit masks to declare which properties are needed by anyone requesting a geometry.
97   enum ObjectProperties
98   {
99     TEXTURE_COORDINATES = 1 << 0,
100     TANGENTS            = 1 << 1,
101     BINORMALS           = 1 << 2
102   };
103
104   ObjLoader();
105   virtual ~ObjLoader();
106
107   bool IsSceneLoaded();
108   bool IsMaterialLoaded();
109
110   bool LoadObject(char* objBuffer, std::streampos fileSize);
111
112   void LoadMaterial(char* objBuffer, std::streampos fileSize, std::string& diffuseTextureUrl, std::string& normalTextureUrl, std::string& glossTextureUrl);
113
114   Geometry CreateGeometry(int objectProperties, bool useSoftNormals);
115
116   Vector3 GetCenter();
117   Vector3 GetSize();
118
119   void ClearArrays();
120
121   bool IsTexturePresent();
122   bool IsDiffuseMapPresent();
123   bool IsNormalMapPresent();
124   bool IsSpecularMapPresent();
125
126 private:
127   BoundingVolume mSceneAABB;
128
129   bool mSceneLoaded;
130   bool mMaterialLoaded;
131   bool mHasTexturePoints;
132
133   //Material file properties.
134   bool mHasDiffuseMap;
135   bool mHasNormalMap;
136   bool mHasSpecularMap;
137
138   Dali::Vector<Vector3>  mPoints;
139   Dali::Vector<Vector2>  mTextures;
140   Dali::Vector<Vector2>  mTextures2;
141   Dali::Vector<Vector3>  mNormals;
142   Dali::Vector<Vector3>  mTangents;
143   Dali::Vector<Vector3>  mBiTangents;
144   Dali::Vector<TriIndex> mTriangles;
145
146   /**
147    * @brief Calculates normals for each point on a per-face basis.
148    *
149    * There are multiple normals per point, each corresponding to the normal of a face connecting to the point.
150    *
151    * @param[in] vertices The vertices of the object.
152    * @param[in, out] triangles The triangles that form the faces. The normals of each triangle will be updated.
153    * @param[in, out] normals The normals to be calculated.
154    */
155   void CalculateHardFaceNormals(const Dali::Vector<Vector3>& vertices,
156                                 Dali::Vector<TriIndex>&      triangles,
157                                 Dali::Vector<Vector3>&       normals);
158
159   /**
160    * @brief Calculates smoothed normals for each point.
161    *
162    * There is one normal per point, an average of the connecting faces.
163    *
164    * @param[in] vertices The vertices of the object.
165    * @param[in, out] triangles The triangles that form the faces. The normals of each triangle will be updated.
166    * @param[in, out] normals The normals to be calculated.
167    */
168   void CalculateSoftFaceNormals(const Dali::Vector<Vector3>& vertices,
169                                 Dali::Vector<TriIndex>&      triangles,
170                                 Dali::Vector<Vector3>&       normals);
171
172   /**
173    * @brief Calculates tangents and bitangents for each point of the object.
174    *
175    * These are calculated using the object's points, texture coordinates and normals, so these must be initialised first.
176    */
177   void CalculateTangentFrame();
178
179   void CenterAndScale(bool center, Dali::Vector<Vector3>& points);
180
181   /**
182    * @brief Using the data loaded from the file, create arrays of data to be used in creating the geometry.
183    *
184    * @param[in] vertices The vertices of the object.
185    * @param[in] textures The texture coordinates of the object.
186    * @param[in] verticesExt Extension to vertices, storing tangents and bitangents.
187    * @param[in] indices Indices of corresponding values to match triangles to their respective data.
188    * @param[in] useSoftNormals Indicates whether we should average the normals at each point to smooth the surface or not.
189    */
190   void CreateGeometryArray(Dali::Vector<Vertex>&         vertices,
191                            Dali::Vector<Vector2>&        textures,
192                            Dali::Vector<VertexExt>&      verticesExt,
193                            Dali::Vector<unsigned short>& indices,
194                            bool                          useSoftNormals);
195 };
196
197 } // namespace Internal
198
199 } // namespace Toolkit
200
201 } // namespace Dali
202
203 #endif // DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H