Remove ResourceImage usage from demos
[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     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   {
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     Toolkit::ImageView backView = Toolkit::ImageView::New(BACKGROUND_IMAGE);
80     backView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
81     stage.Add(backView);
82
83     //Add 3D model control
84     m3DLayer = Layer::New();
85     stage.GetRootLayer().Add(m3DLayer);
86
87     //3D models require 3D based rendering method, so it can use depth buffer, etc.
88     m3DLayer.SetBehavior(Layer::LAYER_3D);
89     m3DLayer.SetParentOrigin( ParentOrigin::CENTER );
90     m3DLayer.SetAnchorPoint( AnchorPoint::CENTER );
91
92     mModelCounter = 0;
93
94     mModel3dView = Model3dView::New( MODEL_FILE[0], MATERIAL_FILE[0], IMAGE_PATH );
95     mModel3dView.SetParentOrigin( ParentOrigin::CENTER );
96     mModel3dView.SetAnchorPoint( AnchorPoint::CENTER );
97     mModel3dView.SetName( "model3dViewControl" );
98     mModel3dView.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
99     mModel3dView.SetSize(screenSize);
100
101     mModel3dView.SetProperty(Model3dView::Property::LIGHT_POSITION, Vector3(5,10.,0));
102
103     m3DLayer.Add( mModel3dView );
104
105     mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
106
107     mButtonLayer = Layer::New();
108     mButtonLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
109     mButtonLayer.SetParentOrigin( ParentOrigin::CENTER );
110     mButtonLayer.SetAnchorPoint( AnchorPoint::CENTER );
111     stage.GetRootLayer().Add(mButtonLayer);
112
113     // Create button for model changing
114     Toolkit::PushButton editButton = Toolkit::PushButton::New();
115     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
116     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnChangeModelClicked);
117     editButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
118     editButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
119     editButton.SetLabelText( "Change Model" );
120     mButtonLayer.Add( editButton  );
121
122     // Create button for shader changing
123     editButton = Toolkit::PushButton::New();
124     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
125     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnChangeLightingClicked);
126     editButton.SetParentOrigin( ParentOrigin::TOP_RIGHT );
127     editButton.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
128     editButton.SetLabelText( "Change Shader" );
129     mButtonLayer.Add( editButton  );
130
131     // Create button for pause/resume animation
132     editButton = Toolkit::PushButton::New();
133     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
134     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnPauseAnimationsClicked);
135     editButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
136     editButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
137     editButton.SetLabelText( "Pause Animations" );
138     mButtonLayer.Add( editButton  );
139
140     //Create animations
141     mLightAnimation = Animation::New(6.f);
142     mLightAnimation.AnimateTo(Property(mModel3dView, Model3dView::Property::LIGHT_POSITION), Vector3(-5,10.0,0), TimePeriod( 0.0f, 3.0f ));
143     mLightAnimation.AnimateTo(Property(mModel3dView, Model3dView::Property::LIGHT_POSITION), Vector3(5,10.0,0), TimePeriod( 3.0f, 3.0f ));
144     mLightAnimation.SetLooping(true);
145     mLightAnimation.Play();
146
147     mRotationAnimation = Animation::New(15.f);
148     mRotationAnimation.AnimateBy(Property(mModel3dView, Actor::Property::ORIENTATION), Quaternion(Degree(0.f), Degree(360.f), Degree(0.f)) );
149     mRotationAnimation.SetLooping(true);
150     mRotationAnimation.Play();
151
152     mPlaying = true;
153     mScaled = false;
154
155     // Respond to a click anywhere on the stage
156     stage.KeyEventSignal().Connect(this, &Model3dViewController::OnKeyEvent);
157
158     //Create a tap gesture detector for zoom
159     mTapDetector = TapGestureDetector::New( 2 );
160     mTapDetector.DetectedSignal().Connect(this, &Model3dViewController::OnTap);
161
162     mTapDetector.Attach( backView );
163   }
164
165   /**
166    * Main Tap event handler
167    */
168   void OnTap( Actor actor, const TapGesture& tap )
169   {
170     if (mScaled)
171     {
172       mModel3dView.SetScale(1.0);
173       mModel3dView.SetPosition(0,0,0);
174       mScaled = false;
175     }
176     else
177     {
178       Stage stage = Stage::GetCurrent();
179       Vector2 screenSize = stage.GetSize();
180
181       Vector2 position;
182       position.x = tap.screenPoint.x - screenSize.x * 0.5;
183       position.y = tap.screenPoint.y - screenSize.y * 0.5;
184
185       float size = 2.5;
186
187       mModel3dView.SetScale(size);
188       mModel3dView.SetPosition(-position.x * size,-position.y * size, 0);
189       mScaled = true;
190     }
191   }
192
193   /**
194    * Change models button signal function
195    */
196   bool OnChangeModelClicked(Toolkit::Button button)
197   {
198     mModelCounter = (mModelCounter + 1) % MODEL_NUMBER;
199     mModel3dView.SetProperty(Model3dView::Property::GEOMETRY_URL, MODEL_FILE[mModelCounter]);
200     mModel3dView.SetProperty(Model3dView::Property::MATERIAL_URL, MATERIAL_FILE[mModelCounter]);
201     mModel3dView.SetProperty(Model3dView::Property::IMAGES_URL, IMAGE_PATH);
202
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.state == 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 m3DLayer;
287   Layer mButtonLayer;
288   TapGestureDetector mTapDetector;
289
290   Model3dView::IlluminationType mIlluminationShader;
291
292   Animation mRotationAnimation;
293   Animation mLightAnimation;
294   bool mPlaying;
295
296   bool mScaled;
297 };
298
299 void RunTest( Application& application )
300 {
301   Model3dViewController test( application );
302
303   application.MainLoop();
304 }
305
306 // Entry point for Linux & Tizen applications
307 //
308 int DALI_EXPORT_API main( int argc, char **argv )
309 {
310   Application application = Application::New( &argc, &argv );
311
312   RunTest( application );
313
314   return 0;
315 }