Model3DView does not need to set IMAGES_URL when changing model
[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     return true;
202   }
203
204   /**
205    * Change shader button signal function
206    */
207   bool OnChangeLightingClicked(Toolkit::Button button)
208   {
209     if( mIlluminationShader == Model3dView::DIFFUSE_WITH_NORMAL_MAP )
210     {
211       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_TEXTURE);
212       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
213     }
214     else if( mIlluminationShader == Model3dView::DIFFUSE_WITH_TEXTURE )
215     {
216       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE);
217       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
218    }
219     else if( mIlluminationShader == Model3dView::DIFFUSE )
220     {
221       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_NORMAL_MAP);
222       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
223    }
224
225     return true;
226   }
227
228   /**
229    * Function to pause resume all animations
230    */
231   void PauseAnimations()
232   {
233     if( mPlaying )
234     {
235       mRotationAnimation.Pause();
236       mLightAnimation.Pause();
237
238       mPlaying = false;
239     }
240     else
241     {
242       mRotationAnimation.Play();
243       mLightAnimation.Play();
244
245       mPlaying = true;
246     }
247   }
248
249   /**
250    * Pause button signal function
251    */
252   bool OnPauseAnimationsClicked(Toolkit::Button button)
253   {
254     PauseAnimations();
255
256     return true;
257   }
258
259   /**
260    * Main key event handler
261    */
262   void OnKeyEvent(const KeyEvent& event)
263   {
264     if(event.state == KeyEvent::Down)
265     {
266       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
267       {
268         mApplication.Quit();
269       }
270       else
271       {
272         PauseAnimations();
273       }
274     }
275   }
276
277
278 private:
279   Application&  mApplication;
280
281   int mModelCounter;
282   Model3dView mModel3dView;
283
284   Layer m3DLayer;
285   Layer mButtonLayer;
286   TapGestureDetector mTapDetector;
287
288   Model3dView::IlluminationType mIlluminationShader;
289
290   Animation mRotationAnimation;
291   Animation mLightAnimation;
292   bool mPlaying;
293
294   bool mScaled;
295 };
296
297 void RunTest( Application& application )
298 {
299   Model3dViewController test( application );
300
301   application.MainLoop();
302 }
303
304 // Entry point for Linux & Tizen applications
305 //
306 int DALI_EXPORT_API main( int argc, char **argv )
307 {
308   Application application = Application::New( &argc, &argv );
309
310   RunTest( application );
311
312   return 0;
313 }