[dali_2.0.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / shader-effects / dissolve-effect.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 // CLASS HEADER
18 #include <dali-toolkit/devel-api/shader-effects/dissolve-effect.h>
19
20 // EXTERNAL INCLUDES
21 #include <dali/public-api/rendering/shader.h>
22
23 // INTERNAL INCLUDES
24 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
25
26 namespace Dali
27 {
28 namespace Toolkit
29 {
30 void DissolveEffectSetCentralLine(Actor& actor, const Vector2& position, const Vector2& displacement, float initialProgress)
31 {
32   // the line passes through 'position' and has the direction of 'displacement'
33   float coefA, coefB, coefC; //line equation: Ax+By+C=0;
34   coefA = displacement.y;
35   coefB = -displacement.x;
36   coefC = -displacement.y * position.x + displacement.x * position.y;
37
38   float inversedAABB     = 1.f / (coefA * coefA + coefB * coefB);
39   float inversedSqrtAABB = sqrtf(inversedAABB);
40   float saddleA;
41
42   //saddle surface(Hyperbolic paraboloid)function, used to calculate the dissolve starting time
43   //z = y*y/a/a - x*x/b/b
44   //with our selection of parameters(a and b), this value for any texture coordinate is between -1.0 and 1.0
45
46   Vector3 saddleParam; // [0]: a*a, [1]: b*b, [2] b
47   Vector2 translation;
48   Vector2 rotation;
49   float   toNext = -1.f;
50   if(displacement.x > 0.f || (EqualsZero(displacement.x) && displacement.y > 0.f))
51   {
52     toNext = 1.f;
53   }
54
55   if((displacement.y * displacement.x < 0.0f))
56   {
57     //distance from (0,0) to the line
58     float distanceTopLeft = fabsf(coefC) * inversedSqrtAABB;
59     //distance from (1, 1 ) to the line
60     float distanceBottomRight = fabsf(coefA + coefB + coefC) * inversedSqrtAABB;
61     saddleA                   = std::max(distanceTopLeft, distanceBottomRight);
62
63     //foot of a perpendicular: (1,0) to the line
64     float footX1 = (coefB * coefB - coefA * coefC) * inversedAABB;
65     float footY1 = (-coefA * coefB - coefB * coefC) * inversedAABB;
66     //foot of a perpendicular: (0,1) to the line
67     float footX2   = (-coefA * coefB - coefA * coefC) * inversedAABB;
68     float footY2   = (coefA * coefA - coefB * coefC) * inversedAABB;
69     saddleParam[1] = (footX1 - footX2) * (footX1 - footX2) + (footY1 - footY2) * (footY1 - footY2);
70     translation    = Vector2(-footX2, -footY2);
71   }
72   else
73   {
74     //distance from(1,0) to the line
75     float distanceTopRight = fabsf(coefA + coefC) * inversedSqrtAABB;
76     //distance from(0,1) to the line
77     float distanceBottomLeft = fabsf(coefB + coefC) * inversedSqrtAABB;
78     saddleA                  = std::max(distanceTopRight, distanceBottomLeft);
79     //foot of a perpendicular: (0,0) to the line
80     float footX3 = (-coefA * coefC) * inversedAABB;
81     float footY3 = (-coefB * coefC) * inversedAABB;
82     //foot of a perpendicular: (1.0,1.0) to the line
83     float footX4   = (coefB * coefB - coefA * coefB - coefA * coefC) * inversedAABB;
84     float footY4   = (-coefA * coefB + coefA * coefA - coefB * coefC) * inversedAABB;
85     saddleParam[1] = (footX3 - footX4) * (footX3 - footX4) + (footY3 - footY4) * (footY3 - footY4);
86     translation    = Vector2(-footX3, -footY3);
87   }
88
89   saddleParam[2] = sqrtf(saddleParam[1]);
90   saddleParam[0] = saddleA * saddleA;
91   rotation       = Vector2(-displacement.x, displacement.y);
92   rotation.Normalize();
93
94   actor.RegisterProperty("uSaddleParam", saddleParam);
95   actor.RegisterProperty("uTranslation", translation);
96   actor.RegisterProperty("uRotation", rotation);
97   actor.RegisterProperty("uToNext", toNext);
98   actor.RegisterProperty("uPercentage", initialProgress, Dali::Property::ANIMATABLE);
99 }
100
101 Property::Map CreateDissolveEffect(bool useHighPrecision)
102 {
103   const char* prefixHighPrecision("precision highp float;\n");
104   const char* prefixMediumPrecision("precision mediump float;\n");
105
106   const char* vertexShader   = SHADER_DISSOLVE_EFFECT_VERT.data();
107   const char* fragmentShader = SHADER_DISSOLVE_EFFECT_FRAG.data();
108
109   Property::Map map;
110
111   Property::Map customShader;
112
113   std::string vertexShaderString;
114   std::string fragmentShaderString;
115   if(useHighPrecision)
116   {
117     vertexShaderString.reserve(strlen(prefixHighPrecision) + strlen(vertexShader));
118     vertexShaderString.append(prefixHighPrecision);
119
120     fragmentShaderString.reserve(strlen(prefixHighPrecision) + strlen(fragmentShader));
121     fragmentShaderString.append(prefixHighPrecision);
122   }
123   else
124   {
125     vertexShaderString.reserve(strlen(prefixMediumPrecision) + strlen(vertexShader));
126     vertexShaderString.append(prefixMediumPrecision);
127
128     fragmentShaderString.reserve(strlen(prefixMediumPrecision) + strlen(fragmentShader));
129     fragmentShaderString.append(prefixMediumPrecision);
130   }
131
132   vertexShaderString.append(vertexShader);
133   fragmentShaderString.append(fragmentShader);
134
135   customShader[Visual::Shader::Property::VERTEX_SHADER]   = vertexShaderString;
136   customShader[Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShaderString;
137
138   customShader[Visual::Shader::Property::SUBDIVIDE_GRID_X] = 20;
139   customShader[Visual::Shader::Property::SUBDIVIDE_GRID_Y] = 20;
140
141   customShader[Visual::Shader::Property::HINTS] = Shader::Hint::OUTPUT_IS_TRANSPARENT;
142
143   map[Toolkit::Visual::Property::SHADER] = customShader;
144   return map;
145 }
146
147 } // namespace Toolkit
148
149 } // namespace Dali