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