2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/public-api/actors/actor.h>
20 #include <dali/public-api/animation/constraint.h>
21 #include <dali/public-api/object/property-map.h>
25 #include <dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h>
26 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
27 #include <dali-toolkit/public-api/visuals/visual-properties.h>
30 using namespace Dali::Toolkit;
34 const char* const PROPERTY_COMMON_PARAMETERS("uCommonParameters");
35 const char* const PROPERTY_ORIGINAL_CENTER("originalCenter");
36 const char* const PROPERTY_CURRENT_CENTER("currentCenter");
40 * This constraint updates the common parameter values used by every vertex.
41 * By using constraint, they are calculate once in CPU then pass into the vertex shader as uniforms
43 struct CommonParametersConstraint
45 CommonParametersConstraint(float pageHeight)
46 : mPageHeight(pageHeight)
50 void operator()(Dali::Matrix& current, const PropertyInputContainer& inputs)
52 const Vector2& originalCenter = inputs[0]->GetVector2();
53 Vector2 currentCenter = inputs[1]->GetVector2();
55 // calculate the curve direction and the vanishing point
56 // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction
57 Vector2 curveDirection(currentCenter - originalCenter);
58 curveDirection.Normalize();
59 if(fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step
61 curveDirection.y = 0.01f;
63 float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y;
65 float curveEndY, cosTheta, sinTheta, translateX, translateY;
66 // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally
67 const float THRESHOLD(20.0);
68 if(fabs(vanishingPointY - mPageHeight * 0.5f) >= mPageHeight * THRESHOLD)
70 curveDirection = Vector2(-1.f, 0.f);
71 currentCenter.y = originalCenter.y;
73 curveEndY = originalCenter.y;
76 translateX = currentCenter.x - originalCenter.x;
77 translateY = vanishingPointY;
81 curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x / curveDirection.x);
82 Vector2 v1(currentCenter.x, currentCenter.y - vanishingPointY);
84 Vector2 v2(originalCenter.x, originalCenter.y - vanishingPointY);
86 cosTheta = v1.x * v2.x + v1.y * v2.y;
87 sinTheta = (vanishingPointY > mPageHeight * 0.5f) ? sqrt(1.0 - cosTheta * cosTheta) : -sqrt(1.0 - cosTheta * cosTheta);
88 translateX = currentCenter.x - cosTheta * originalCenter.x - sinTheta * (originalCenter.y - vanishingPointY);
89 translateY = currentCenter.y + sinTheta * originalCenter.x - cosTheta * (originalCenter.y - vanishingPointY);
92 float originalLength = fabs(originalCenter.x / curveDirection.x);
93 float currentLength = fabs(currentCenter.x / curveDirection.x);
94 float curveHeight = 0.45f * sqrt(originalLength * originalLength - currentLength * currentLength);
96 float* parameterArray = current.AsFloat();
97 parameterArray[0] = cosTheta;
98 parameterArray[1] = -sinTheta;
99 parameterArray[2] = originalCenter.x;
100 parameterArray[3] = originalCenter.y;
101 parameterArray[4] = sinTheta;
102 parameterArray[5] = cosTheta;
103 parameterArray[6] = currentCenter.x;
104 parameterArray[7] = currentCenter.y;
105 parameterArray[8] = translateX;
106 parameterArray[9] = translateY;
107 parameterArray[10] = vanishingPointY;
108 parameterArray[11] = curveEndY;
109 parameterArray[12] = curveDirection.x;
110 parameterArray[13] = curveDirection.y;
111 parameterArray[14] = curveHeight;
112 parameterArray[15] = currentLength;
118 void Dali::Toolkit::Internal::PageTurnApplyInternalConstraint(Actor& actor, float pageHeight)
120 Constraint constraint = Constraint::New<Dali::Matrix>(actor, actor.GetPropertyIndex(PROPERTY_COMMON_PARAMETERS), CommonParametersConstraint(pageHeight));
121 constraint.AddSource(LocalSource(actor.GetPropertyIndex(PROPERTY_ORIGINAL_CENTER)));
122 constraint.AddSource(LocalSource(actor.GetPropertyIndex(PROPERTY_CURRENT_CENTER)));
126 Property::Map Dali::Toolkit::Internal::CreatePageTurnEffect()
130 Property::Map customShader;
132 customShader[Toolkit::Visual::Shader::Property::VERTEX_SHADER] = SHADER_PAGE_TURN_EFFECT_VERT.data();
133 customShader[Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = SHADER_PAGE_TURN_EFFECT_FRAG.data();
134 customShader[Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_X] = 20;
135 customShader[Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_Y] = 20;
137 map[Toolkit::Visual::Property::SHADER] = customShader;