[dali_2.2.4] 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) 2021 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 class ObjLoader;
30
31 namespace Internal
32 {
33 class ObjLoader
34 {
35 public:
36   struct TriIndex
37   {
38     int pointIndex[3];
39     int normalIndex[3];
40     int textureIndex[3];
41   };
42
43   struct Vertex
44   {
45     Vertex()
46     {
47     }
48
49     Vertex(const Vector3& position, const Vector3& normal, const Vector2& textureCoord)
50     : position(position),
51       normal(normal)
52     {
53     }
54
55     Vector3 position;
56     Vector3 normal;
57   };
58
59   struct VertexExt
60   {
61     VertexExt()
62     {
63     }
64
65     VertexExt(const Vector3& tangent, const Vector3& binormal)
66     : tangent(tangent),
67       bitangent(binormal)
68     {
69     }
70
71     Vector3 tangent;
72     Vector3 bitangent;
73   };
74
75   struct BoundingVolume
76   {
77     void Init()
78     {
79       pointMin = Vector3(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
80       pointMax = Vector3(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
81     }
82
83     void ConsiderNewPointInVolume(const Vector3& position)
84     {
85       pointMin.x = std::min(position.x, pointMin.x);
86       pointMin.y = std::min(position.y, pointMin.y);
87       pointMin.z = std::min(position.z, pointMin.z);
88
89       pointMax.x = std::max(position.x, pointMax.x);
90       pointMax.y = std::max(position.y, pointMax.y);
91       pointMax.z = std::max(position.z, pointMax.z);
92     }
93
94     Vector3 pointMin;
95     Vector3 pointMax;
96   };
97
98   //Defines bit masks to declare which properties are needed by anyone requesting a geometry.
99   enum ObjectProperties
100   {
101     TEXTURE_COORDINATES = 1 << 0,
102     TANGENTS            = 1 << 1,
103     BINORMALS           = 1 << 2
104   };
105
106   ObjLoader();
107   virtual ~ObjLoader();
108
109   bool IsSceneLoaded();
110   bool IsMaterialLoaded();
111
112   bool LoadObject(char* objBuffer, std::streampos fileSize);
113
114   void LoadMaterial(char* objBuffer, std::streampos fileSize, std::string& diffuseTextureUrl, std::string& normalTextureUrl, std::string& glossTextureUrl);
115
116   Geometry CreateGeometry(int objectProperties, bool useSoftNormals);
117
118   Vector3 GetCenter();
119   Vector3 GetSize();
120
121   void ClearArrays();
122
123   bool IsTexturePresent();
124   bool IsDiffuseMapPresent();
125   bool IsNormalMapPresent();
126   bool IsSpecularMapPresent();
127
128 private:
129   BoundingVolume mSceneAABB;
130
131   bool mSceneLoaded;
132   bool mMaterialLoaded;
133   bool mHasTexturePoints;
134
135   //Material file properties.
136   bool mHasDiffuseMap;
137   bool mHasNormalMap;
138   bool mHasSpecularMap;
139
140   Dali::Vector<Vector3>  mPoints;
141   Dali::Vector<Vector2>  mTextures;
142   Dali::Vector<Vector2>  mTextures2;
143   Dali::Vector<Vector3>  mNormals;
144   Dali::Vector<Vector3>  mTangents;
145   Dali::Vector<Vector3>  mBiTangents;
146   Dali::Vector<TriIndex> mTriangles;
147
148   /**
149    * @brief Calculates normals for each point on a per-face basis.
150    *
151    * There are multiple normals per point, each corresponding to the normal of a face connecting to the point.
152    *
153    * @param[in] vertices The vertices of the object.
154    * @param[in, out] triangles The triangles that form the faces. The normals of each triangle will be updated.
155    * @param[in, out] normals The normals to be calculated.
156    */
157   void CalculateHardFaceNormals(const Dali::Vector<Vector3>& vertices,
158                                 Dali::Vector<TriIndex>&      triangles,
159                                 Dali::Vector<Vector3>&       normals);
160
161   /**
162    * @brief Calculates smoothed normals for each point.
163    *
164    * There is one normal per point, an average of the connecting faces.
165    *
166    * @param[in] vertices The vertices of the object.
167    * @param[in, out] triangles The triangles that form the faces. The normals of each triangle will be updated.
168    * @param[in, out] normals The normals to be calculated.
169    */
170   void CalculateSoftFaceNormals(const Dali::Vector<Vector3>& vertices,
171                                 Dali::Vector<TriIndex>&      triangles,
172                                 Dali::Vector<Vector3>&       normals);
173
174   /**
175    * @brief Calculates tangents and bitangents for each point of the object.
176    *
177    * These are calculated using the object's points, texture coordinates and normals, so these must be initialised first.
178    */
179   void CalculateTangentFrame();
180
181   void CenterAndScale(bool center, Dali::Vector<Vector3>& points);
182
183   /**
184    * @brief Using the data loaded from the file, create arrays of data to be used in creating the geometry.
185    *
186    * @param[in] vertices The vertices of the object.
187    * @param[in] textures The texture coordinates of the object.
188    * @param[in] verticesExt Extension to vertices, storing tangents and bitangents.
189    * @param[in] indices Indices of corresponding values to match triangles to their respective data.
190    * @param[in] useSoftNormals Indicates whether we should average the normals at each point to smooth the surface or not.
191    */
192   void CreateGeometryArray(Dali::Vector<Vertex>&         vertices,
193                            Dali::Vector<Vector2>&        textures,
194                            Dali::Vector<VertexExt>&      verticesExt,
195                            Dali::Vector<unsigned short>& indices,
196                            bool                          useSoftNormals);
197 };
198
199 } // namespace Internal
200
201 } // namespace Toolkit
202
203 } // namespace Dali
204
205 #endif // DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H