[dali_1.1.9] Merge branch 'devel/master'
[platform/core/uifw/dali-demo.git] / examples / model3d-view / model3d-view-example.cpp
1 /*
2  * Copyright (c) 2015 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     DALI_MODEL_DIR "Dino.obj",
29     DALI_MODEL_DIR "ToyRobot-Metal.obj",
30     DALI_MODEL_DIR "Toyrobot-Plastic.obj"
31 };
32
33 const char * const MATERIAL_FILE[] = {
34     DALI_MODEL_DIR "Dino.mtl",
35     DALI_MODEL_DIR "ToyRobot-Metal.mtl",
36     DALI_MODEL_DIR "Toyrobot-Plastic.mtl"
37 };
38
39 const char * const IMAGE_PATH( DALI_IMAGE_DIR "" );
40
41 const char * BACKGROUND_IMAGE( DALI_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   {
62     // Connect to the Application's Init signal
63     mApplication.InitSignal().Connect( this, &Model3dViewController::Create );
64   }
65
66   ~Model3dViewController()
67   {
68     // Nothing to do here;
69   }
70
71   // The Init signal is received once (only) during the Application lifetime
72   void Create( Application& application )
73   {
74     // Get a handle to the stage
75     Stage stage = Stage::GetCurrent();
76     Vector2 screenSize = stage.GetSize();
77
78     //Add background
79     Image imageBackground = ResourceImage::New( BACKGROUND_IMAGE );
80     Toolkit::ImageView backView = Toolkit::ImageView::New(imageBackground);
81     backView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
82     stage.Add(backView);
83
84     //Add 3D model control
85     m3DLayer = Layer::New();
86     stage.GetRootLayer().Add(m3DLayer);
87
88     //3D models require 3D based rendering method, so it can use depth buffer, etc.
89     m3DLayer.SetBehavior(Layer::LAYER_3D);
90     m3DLayer.SetParentOrigin( ParentOrigin::CENTER );
91     m3DLayer.SetAnchorPoint( AnchorPoint::CENTER );
92
93     mModelCounter = 0;
94
95     mModel3dView = Model3dView::New( MODEL_FILE[0], MATERIAL_FILE[0], IMAGE_PATH );
96     mModel3dView.SetParentOrigin( ParentOrigin::CENTER );
97     mModel3dView.SetAnchorPoint( AnchorPoint::CENTER );
98     mModel3dView.SetName( "model3dViewControl" );
99     mModel3dView.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
100     mModel3dView.SetSize(screenSize);
101
102     mModel3dView.SetProperty(Model3dView::Property::LIGHT_POSITION, Vector3(5,10.,0));
103
104     m3DLayer.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.SetParentOrigin( ParentOrigin::CENTER );
111     mButtonLayer.SetAnchorPoint( AnchorPoint::CENTER );
112     stage.GetRootLayer().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.SetParentOrigin( ParentOrigin::TOP_LEFT );
119     editButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
120     editButton.SetLabelText( "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.SetParentOrigin( ParentOrigin::TOP_RIGHT );
128     editButton.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
129     editButton.SetLabelText( "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.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
137     editButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
138     editButton.SetLabelText( "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 stage
157     stage.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.SetScale(1.0);
174       mModel3dView.SetPosition(0,0,0);
175       mScaled = false;
176     }
177     else
178     {
179       Stage stage = Stage::GetCurrent();
180       Vector2 screenSize = stage.GetSize();
181
182       Vector2 position;
183       position.x = tap.screenPoint.x - screenSize.x * 0.5;
184       position.y = tap.screenPoint.y - screenSize.y * 0.5;
185
186       float size = 2.5;
187
188       mModel3dView.SetScale(size);
189       mModel3dView.SetPosition(-position.x * size,-position.y * size, 0);
190       mScaled = true;
191     }
192   }
193
194   /**
195    * Change models button signal function
196    */
197   bool OnChangeModelClicked(Toolkit::Button button)
198   {
199     mModelCounter = (mModelCounter + 1) % MODEL_NUMBER;
200     mModel3dView.SetProperty(Model3dView::Property::GEOMETRY_URL, MODEL_FILE[mModelCounter]);
201     mModel3dView.SetProperty(Model3dView::Property::MATERIAL_URL, MATERIAL_FILE[mModelCounter]);
202     mModel3dView.SetProperty(Model3dView::Property::IMAGES_URL, IMAGE_PATH);
203
204     return true;
205   }
206
207   /**
208    * Change shader button signal function
209    */
210   bool OnChangeLightingClicked(Toolkit::Button button)
211   {
212     if( mIlluminationShader == Model3dView::DIFFUSE_WITH_NORMAL_MAP )
213     {
214       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_TEXTURE);
215       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
216     }
217     else if( mIlluminationShader == Model3dView::DIFFUSE_WITH_TEXTURE )
218     {
219       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE);
220       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
221    }
222     else if( mIlluminationShader == Model3dView::DIFFUSE )
223     {
224       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_NORMAL_MAP);
225       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
226    }
227
228     return true;
229   }
230
231   /**
232    * Function to pause resume all animations
233    */
234   void PauseAnimations()
235   {
236     if( mPlaying )
237     {
238       mRotationAnimation.Pause();
239       mLightAnimation.Pause();
240
241       mPlaying = false;
242     }
243     else
244     {
245       mRotationAnimation.Play();
246       mLightAnimation.Play();
247
248       mPlaying = true;
249     }
250   }
251
252   /**
253    * Pause button signal function
254    */
255   bool OnPauseAnimationsClicked(Toolkit::Button button)
256   {
257     PauseAnimations();
258
259     return true;
260   }
261
262   /**
263    * Main key event handler
264    */
265   void OnKeyEvent(const KeyEvent& event)
266   {
267     if(event.state == KeyEvent::Down)
268     {
269       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
270       {
271         mApplication.Quit();
272       }
273       else
274       {
275         PauseAnimations();
276       }
277     }
278   }
279
280
281 private:
282   Application&  mApplication;
283
284   int mModelCounter;
285   Model3dView mModel3dView;
286
287   Layer m3DLayer;
288   Layer mButtonLayer;
289   TapGestureDetector mTapDetector;
290
291   Model3dView::IlluminationType mIlluminationShader;
292
293   Animation mRotationAnimation;
294   Animation mLightAnimation;
295   bool mPlaying;
296
297   bool mScaled;
298 };
299
300 void RunTest( Application& application )
301 {
302   Model3dViewController test( application );
303
304   application.MainLoop();
305 }
306
307 // Entry point for Linux & Tizen applications
308 //
309 int main( int argc, char **argv )
310 {
311   Application application = Application::New( &argc, &argv );
312
313   RunTest( application );
314
315   return 0;
316 }