d756e226ddf6793fe8032bc4ae8932f93179bc68
[platform/core/uifw/dali-demo.git] / examples / waves / utils.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #include "utils.h"
18 #include <fstream>
19 #include "dali-toolkit/dali-toolkit.h"
20
21 using namespace Dali;
22 using namespace Dali::Toolkit;
23
24 Vector3 ToHueSaturationLightness(Vector3 rgb)
25 {
26   float min = std::min(rgb.r, std::min(rgb.g, rgb.b));
27   float max = std::max(rgb.r, std::max(rgb.g, rgb.b));
28
29   Vector3 hsl(max - min, 0.f, (max + min) * .5f);
30   if(hsl.x * hsl.x > .0f)
31   {
32     hsl.y = hsl.x / max;
33     if(max == rgb.r)
34     {
35       hsl.x = (rgb.g - rgb.b) / hsl.x;
36     }
37     else if(max == rgb.g)
38     {
39       hsl.x = 2.f + (rgb.b - rgb.r) / hsl.x;
40     }
41     else
42     {
43       hsl.x = 4.f + (rgb.r - rgb.g) / hsl.x;
44     }
45     hsl.x *= 60.f;
46     if(hsl.x < 0.f)
47     {
48       hsl.x += 360.f;
49     }
50   }
51   else
52   {
53     hsl.y = 0.f;
54   }
55
56   return hsl;
57 }
58
59 Vector3 FromHueSaturationLightness(Vector3 hsl)
60 {
61   Vector3 rgb;
62   if(hsl.y * hsl.y > 0.f)
63   {
64     if(hsl.x >= 360.f)
65     {
66       hsl.x -= 360.f;
67     }
68     hsl.x /= 60.f;
69
70     int   i  = FastFloor(hsl.x);
71     float ff = hsl.x - i;
72     float p  = hsl.z * (1.0 - hsl.y);
73     float q  = hsl.z * (1.0 - (hsl.y * ff));
74     float t  = hsl.z * (1.0 - (hsl.y * (1.f - ff)));
75
76     switch(i)
77     {
78       case 0:
79         rgb.r = hsl.z;
80         rgb.g = t;
81         rgb.b = p;
82         break;
83
84       case 1:
85         rgb.r = q;
86         rgb.g = hsl.z;
87         rgb.b = p;
88         break;
89
90       case 2:
91         rgb.r = p;
92         rgb.g = hsl.z;
93         rgb.b = t;
94         break;
95
96       case 3:
97         rgb.r = p;
98         rgb.g = q;
99         rgb.b = hsl.z;
100         break;
101
102       case 4:
103         rgb.r = t;
104         rgb.g = p;
105         rgb.b = hsl.z;
106         break;
107
108       case 5:
109       default:
110         rgb.r = hsl.z;
111         rgb.g = p;
112         rgb.b = q;
113         break;
114     }
115   }
116   else
117   {
118     rgb = Vector3::ONE * hsl.z;
119   }
120
121   return rgb;
122 }
123
124 Geometry CreateTesselatedQuad(unsigned int xVerts, unsigned int yVerts, Vector2 scale, VertexFn positionFn, VertexFn texCoordFn)
125 {
126   DALI_ASSERT_DEBUG(xVerts > 1 && yVerts > 1);
127   int numVerts = xVerts * yVerts;
128   struct Vertex
129   {
130     Vector2 aPosition;
131     Vector2 aTexCoord;
132   };
133   std::vector<Vertex> vertices;
134   vertices.reserve(numVerts);
135
136   float dx = 1.f / (xVerts - 1);
137   float dz = 1.f / (yVerts - 1);
138
139   Vector2 pos{0.f, 0.f};
140   for(unsigned int i = 0; i < yVerts; ++i)
141   {
142     pos.x = float(int((i & 1) * 2) - 1) * dx * .25f;
143     for(unsigned int j = 0; j < xVerts; ++j)
144     {
145       auto vPos = pos + Vector2{-.5f, -.5f};
146       vertices.push_back(Vertex{(positionFn ? positionFn(vPos) : vPos) * scale,
147                                 texCoordFn ? texCoordFn(pos) : pos});
148       pos.x += dx;
149     }
150
151     pos.y += dz;
152   }
153
154   VertexBuffer vertexBuffer = VertexBuffer::New(Property::Map()
155                                                   .Add("aPosition", Property::VECTOR2)
156                                                   .Add("aTexCoord", Property::VECTOR2));
157   vertexBuffer.SetData(vertices.data(), vertices.size());
158
159   int                   numInds = (xVerts - 1) * (yVerts - 1) * 6;
160   std::vector<uint16_t> indices;
161   indices.reserve(numInds);
162
163   for(unsigned int i = 1; i < yVerts; ++i)
164   {
165     if((i & 1) == 0)
166     {
167       for(unsigned int j = 1; j < xVerts; ++j)
168       {
169         int iBase = i * xVerts + j;
170         indices.push_back(iBase);
171         indices.push_back(iBase - 1);
172         indices.push_back(iBase - xVerts - 1);
173         indices.push_back(indices.back());
174         indices.push_back(iBase - xVerts);
175         indices.push_back(iBase);
176       }
177     }
178     else
179     {
180       for(unsigned int j = 1; j < xVerts; ++j)
181       {
182         int iBase = i * xVerts + j;
183         indices.push_back(iBase);
184         indices.push_back(iBase - 1);
185         indices.push_back(iBase - xVerts);
186         indices.push_back(indices.back());
187         indices.push_back(iBase - 1);
188         indices.push_back(iBase - xVerts - 1);
189       }
190     }
191   }
192
193   Geometry geom = Geometry::New();
194   geom.AddVertexBuffer(vertexBuffer);
195   geom.SetIndexBuffer(indices.data(), indices.size());
196   return geom;
197 }
198
199 Texture LoadTexture(const std::string& path)
200 {
201   PixelData pixelData = SyncImageLoader::Load(path);
202
203   Texture texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
204   texture.Upload(pixelData);
205   return texture;
206 }
207
208 Renderer CreateRenderer(TextureSet textures, Geometry geometry, Shader shader, uint32_t options)
209 {
210   Renderer renderer = Renderer::New(geometry, shader);
211   renderer.SetProperty(Renderer::Property::BLEND_MODE,
212                        (options & OPTION_BLEND) ? BlendMode::ON : BlendMode::OFF);
213   renderer.SetProperty(Renderer::Property::DEPTH_TEST_MODE,
214                        (options & OPTION_DEPTH_TEST) ? DepthTestMode::ON : DepthTestMode::OFF);
215   renderer.SetProperty(Renderer::Property::DEPTH_WRITE_MODE,
216                        (options & OPTION_DEPTH_WRITE) ? DepthWriteMode::ON : DepthWriteMode::OFF);
217   renderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
218
219   if(!textures)
220   {
221     textures = TextureSet::New();
222   }
223
224   renderer.SetTextures(textures);
225   return renderer;
226 }
227
228 void CenterActor(Actor actor)
229 {
230   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
231   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
232 }
233
234 Actor CreateActor()
235 {
236   auto actor = Actor::New();
237   CenterActor(actor);
238   return actor;
239 }
240
241 Renderer CloneRenderer(Renderer original)
242 {
243   Geometry geom   = original.GetGeometry();
244   Shader   shader = original.GetShader();
245   Renderer clone  = Renderer::New(geom, shader);
246
247   // Copy properties.
248   Property::IndexContainer indices;
249   original.GetPropertyIndices(indices);
250
251   for(auto& i : indices)
252   {
253     auto actualIndex = Dali::PropertyRanges::DEFAULT_RENDERER_PROPERTY_START_INDEX + i;
254     clone.SetProperty(actualIndex, original.GetProperty(actualIndex));
255   }
256
257   // Copy texture references (and create TextureSet, if there's any textures).
258   TextureSet ts = original.GetTextures();
259   clone.SetTextures(ts);
260
261   return clone;
262 }
263
264 Actor CloneActor(Actor original)
265 {
266   using namespace Dali;
267
268   auto clone = Actor::New();
269   clone.SetProperty(Actor::Property::NAME, original.GetProperty(Actor::Property::NAME));
270
271   // Copy properties.
272   // Don't copy every single one of them.
273   // Definitely don't copy resize policy related things, which will internally enable
274   // relayout, which in turn will result in losing the ability to set Z size.
275   for(auto i : {
276         Actor::Property::PARENT_ORIGIN,
277         Actor::Property::ANCHOR_POINT,
278         Actor::Property::SIZE,
279         Actor::Property::POSITION,
280         Actor::Property::ORIENTATION,
281         Actor::Property::SCALE,
282         Actor::Property::VISIBLE,
283         Actor::Property::COLOR,
284         Actor::Property::NAME,
285       })
286   {
287     clone.SetProperty(i, original.GetProperty(i));
288   }
289
290   // Clone renderers.
291   for(unsigned int i = 0; i < original.GetRendererCount(); ++i)
292   {
293     auto rClone = CloneRenderer(original.GetRendererAt(i));
294     clone.AddRenderer(rClone);
295   }
296
297   // Recurse into children.
298   for(unsigned int i = 0; i < original.GetChildCount(); ++i)
299   {
300     Actor newChild = CloneActor(original.GetChildAt(i));
301     clone.Add(newChild);
302   }
303
304   return clone;
305 }