Refactoring Gestures Class
[platform/core/uifw/dali-demo.git] / examples / model3d-view / model3d-view-example.cpp
1 /*
2  * Copyright (c) 2020 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
18 #include <dali-toolkit/dali-toolkit.h>
19
20 using namespace Dali;
21 using Dali::Toolkit::Model3dView;
22
23 namespace
24 {
25 const int MODEL_NUMBER(3);
26
27 const char * const MODEL_FILE[] = {
28     DEMO_MODEL_DIR "Dino.obj",
29     DEMO_MODEL_DIR "ToyRobot-Metal.obj",
30     DEMO_MODEL_DIR "Toyrobot-Plastic.obj"
31 };
32
33 const char * const MATERIAL_FILE[] = {
34     DEMO_MODEL_DIR "Dino.mtl",
35     DEMO_MODEL_DIR "ToyRobot-Metal.mtl",
36     DEMO_MODEL_DIR "Toyrobot-Plastic.mtl"
37 };
38
39 const char * const IMAGE_PATH( DEMO_IMAGE_DIR "" );
40
41 const char * BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-1.jpg");
42
43 }
44
45 /*
46  * This example shows how to create and display a model3d-view control.
47  * The application can cycle between 3 different models, and 3 different shaders.
48  * There are two animations running, one is a rotation for the model, one is a light that
49  * goes from one side of the model to the other.
50  * There are dedicated buttons for changing the models, the shaders and pausing the animations.
51  * The animations can also be paused, resumed with the space key
52  * A double tap in the model3d-view will make zoom-in/out of the zone clicked
53  */
54
55 class Model3dViewController : public ConnectionTracker
56 {
57 public:
58
59   Model3dViewController( Application& application )
60   : mApplication( application ),
61     mModelCounter( 0 ),
62     mModel3dView(),
63     mButtonLayer(),
64     mTapDetector(),
65     mIlluminationShader( Model3dView::DIFFUSE ),
66     mRotationAnimation(),
67     mLightAnimation(),
68     mPlaying( false ),
69     mScaled( false )
70   {
71     // Connect to the Application's Init signal
72     mApplication.InitSignal().Connect( this, &Model3dViewController::Create );
73   }
74
75   ~Model3dViewController()
76   {
77     // Nothing to do here;
78   }
79
80   // The Init signal is received once (only) during the Application lifetime
81   void Create( Application& application )
82   {
83     // Get a handle to the window
84     Window window = application.GetWindow();
85     Vector2 screenSize = window.GetSize();
86
87     //Add background
88     Toolkit::ImageView backView = Toolkit::ImageView::New( BACKGROUND_IMAGE );
89     backView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
90     backView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
91     window.Add( backView );
92
93     mModelCounter = 0;
94
95     mModel3dView = Model3dView::New( MODEL_FILE[0], MATERIAL_FILE[0], IMAGE_PATH );
96     mModel3dView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
97     mModel3dView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
98     mModel3dView.SetProperty( Dali::Actor::Property::NAME, "model3dViewControl" );
99     mModel3dView.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
100     mModel3dView.SetProperty( Actor::Property::SIZE, screenSize);
101
102     mModel3dView.SetProperty(Model3dView::Property::LIGHT_POSITION, Vector3(5,10.,0));
103
104     backView.Add( mModel3dView );
105
106     mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
107
108     mButtonLayer = Layer::New();
109     mButtonLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
110     mButtonLayer.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
111     mButtonLayer.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
112     window.Add(mButtonLayer);
113
114     // Create button for model changing
115     Toolkit::PushButton editButton = Toolkit::PushButton::New();
116     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
117     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnChangeModelClicked);
118     editButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
119     editButton.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
120     editButton.SetProperty( Toolkit::Button::Property::LABEL, "Change Model" );
121     mButtonLayer.Add( editButton  );
122
123     // Create button for shader changing
124     editButton = Toolkit::PushButton::New();
125     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
126     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnChangeLightingClicked);
127     editButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT );
128     editButton.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT );
129     editButton.SetProperty( Toolkit::Button::Property::LABEL, "Change Shader" );
130     mButtonLayer.Add( editButton  );
131
132     // Create button for pause/resume animation
133     editButton = Toolkit::PushButton::New();
134     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
135     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnPauseAnimationsClicked);
136     editButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
137     editButton.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER );
138     editButton.SetProperty( Toolkit::Button::Property::LABEL, "Pause Animations" );
139     mButtonLayer.Add( editButton  );
140
141     //Create animations
142     mLightAnimation = Animation::New(6.f);
143     mLightAnimation.AnimateTo(Property(mModel3dView, Model3dView::Property::LIGHT_POSITION), Vector3(-5,10.0,0), TimePeriod( 0.0f, 3.0f ));
144     mLightAnimation.AnimateTo(Property(mModel3dView, Model3dView::Property::LIGHT_POSITION), Vector3(5,10.0,0), TimePeriod( 3.0f, 3.0f ));
145     mLightAnimation.SetLooping(true);
146     mLightAnimation.Play();
147
148     mRotationAnimation = Animation::New(15.f);
149     mRotationAnimation.AnimateBy(Property(mModel3dView, Actor::Property::ORIENTATION), Quaternion(Degree(0.f), Degree(360.f), Degree(0.f)) );
150     mRotationAnimation.SetLooping(true);
151     mRotationAnimation.Play();
152
153     mPlaying = true;
154     mScaled = false;
155
156     // Respond to a click anywhere on the window
157     window.KeyEventSignal().Connect(this, &Model3dViewController::OnKeyEvent);
158
159     //Create a tap gesture detector for zoom
160     mTapDetector = TapGestureDetector::New( 2 );
161     mTapDetector.DetectedSignal().Connect(this, &Model3dViewController::OnTap);
162
163     mTapDetector.Attach( backView );
164   }
165
166   /**
167    * Main Tap event handler
168    */
169   void OnTap( Actor actor, const TapGesture& tap )
170   {
171     if (mScaled)
172     {
173       mModel3dView.SetProperty( Actor::Property::SCALE, 1.0f );
174       mModel3dView.SetProperty( Actor::Property::POSITION, Vector3( 0, 0, 0 ) );
175       mScaled = false;
176     }
177     else
178     {
179       Window window = mApplication.GetWindow();
180       Vector2 screenSize = window.GetSize();
181
182       const Vector2& screenPoint = tap.GetScreenPoint();
183       Vector2 position;
184       position.x = screenPoint.x - screenSize.x * 0.5;
185       position.y = screenPoint.y - screenSize.y * 0.5;
186
187       float size = 2.5;
188
189       mModel3dView.SetProperty( Actor::Property::SCALE, size );
190       mModel3dView.SetProperty( Actor::Property::POSITION, Vector3( -position.x * size, -position.y * size, 0 ) );
191       mScaled = true;
192     }
193   }
194
195   /**
196    * Change models button signal function
197    */
198   bool OnChangeModelClicked(Toolkit::Button button)
199   {
200     mModelCounter = (mModelCounter + 1) % MODEL_NUMBER;
201     mModel3dView.SetProperty(Model3dView::Property::GEOMETRY_URL, MODEL_FILE[mModelCounter]);
202     mModel3dView.SetProperty(Model3dView::Property::MATERIAL_URL, MATERIAL_FILE[mModelCounter]);
203     return true;
204   }
205
206   /**
207    * Change shader button signal function
208    */
209   bool OnChangeLightingClicked(Toolkit::Button button)
210   {
211     if( mIlluminationShader == Model3dView::DIFFUSE_WITH_NORMAL_MAP )
212     {
213       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_TEXTURE);
214       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
215     }
216     else if( mIlluminationShader == Model3dView::DIFFUSE_WITH_TEXTURE )
217     {
218       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE);
219       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
220    }
221     else if( mIlluminationShader == Model3dView::DIFFUSE )
222     {
223       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_NORMAL_MAP);
224       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
225    }
226
227     return true;
228   }
229
230   /**
231    * Function to pause resume all animations
232    */
233   void PauseAnimations()
234   {
235     if( mPlaying )
236     {
237       mRotationAnimation.Pause();
238       mLightAnimation.Pause();
239
240       mPlaying = false;
241     }
242     else
243     {
244       mRotationAnimation.Play();
245       mLightAnimation.Play();
246
247       mPlaying = true;
248     }
249   }
250
251   /**
252    * Pause button signal function
253    */
254   bool OnPauseAnimationsClicked(Toolkit::Button button)
255   {
256     PauseAnimations();
257
258     return true;
259   }
260
261   /**
262    * Main key event handler
263    */
264   void OnKeyEvent(const KeyEvent& event)
265   {
266     if(event.GetState() == KeyEvent::DOWN)
267     {
268       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
269       {
270         mApplication.Quit();
271       }
272       else
273       {
274         PauseAnimations();
275       }
276     }
277   }
278
279
280 private:
281   Application&  mApplication;
282
283   int mModelCounter;
284   Model3dView mModel3dView;
285
286   Layer mButtonLayer;
287   TapGestureDetector mTapDetector;
288
289   Model3dView::IlluminationType mIlluminationShader;
290
291   Animation mRotationAnimation;
292   Animation mLightAnimation;
293   bool mPlaying;
294
295   bool mScaled;
296 };
297
298 int DALI_EXPORT_API main( int argc, char **argv )
299 {
300   Application application = Application::New( &argc, &argv );
301   Model3dViewController test( application );
302   application.MainLoop();
303   return 0;
304 }