[3.0] Removed 3D layer dependency of Model3dView and Mesh Visual.
[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.SetParentOrigin( ParentOrigin::CENTER );
81     backView.SetAnchorPoint( AnchorPoint::CENTER );
82     stage.Add( backView );
83
84     mModelCounter = 0;
85
86     mModel3dView = Model3dView::New( MODEL_FILE[0], MATERIAL_FILE[0], IMAGE_PATH );
87     mModel3dView.SetParentOrigin( ParentOrigin::CENTER );
88     mModel3dView.SetAnchorPoint( AnchorPoint::CENTER );
89     mModel3dView.SetName( "model3dViewControl" );
90     mModel3dView.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
91     mModel3dView.SetSize(screenSize);
92
93     mModel3dView.SetProperty(Model3dView::Property::LIGHT_POSITION, Vector3(5,10.,0));
94
95     backView.Add( mModel3dView );
96
97     mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
98
99     mButtonLayer = Layer::New();
100     mButtonLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
101     mButtonLayer.SetParentOrigin( ParentOrigin::CENTER );
102     mButtonLayer.SetAnchorPoint( AnchorPoint::CENTER );
103     stage.Add( mButtonLayer );
104
105     // Create button for model changing
106     Toolkit::PushButton editButton = Toolkit::PushButton::New();
107     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
108     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnChangeModelClicked);
109     editButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
110     editButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
111     editButton.SetLabelText( "Change Model" );
112     mButtonLayer.Add( editButton  );
113
114     // Create button for shader changing
115     editButton = Toolkit::PushButton::New();
116     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
117     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnChangeLightingClicked);
118     editButton.SetParentOrigin( ParentOrigin::TOP_RIGHT );
119     editButton.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
120     editButton.SetLabelText( "Change Shader" );
121     mButtonLayer.Add( editButton  );
122
123     // Create button for pause/resume animation
124     editButton = Toolkit::PushButton::New();
125     editButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
126     editButton.ClickedSignal().Connect( this, &Model3dViewController::OnPauseAnimationsClicked);
127     editButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
128     editButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
129     editButton.SetLabelText( "Pause Animations" );
130     mButtonLayer.Add( editButton  );
131
132     //Create animations
133     mLightAnimation = Animation::New(6.f);
134     mLightAnimation.AnimateTo(Property(mModel3dView, Model3dView::Property::LIGHT_POSITION), Vector3(-5,10.0,0), TimePeriod( 0.0f, 3.0f ));
135     mLightAnimation.AnimateTo(Property(mModel3dView, Model3dView::Property::LIGHT_POSITION), Vector3(5,10.0,0), TimePeriod( 3.0f, 3.0f ));
136     mLightAnimation.SetLooping(true);
137     mLightAnimation.Play();
138
139     mRotationAnimation = Animation::New(15.f);
140     mRotationAnimation.AnimateBy(Property(mModel3dView, Actor::Property::ORIENTATION), Quaternion(Degree(0.f), Degree(360.f), Degree(0.f)) );
141     mRotationAnimation.SetLooping(true);
142     mRotationAnimation.Play();
143
144     mPlaying = true;
145     mScaled = false;
146
147     // Respond to a click anywhere on the stage
148     stage.KeyEventSignal().Connect(this, &Model3dViewController::OnKeyEvent);
149
150     //Create a tap gesture detector for zoom
151     mTapDetector = TapGestureDetector::New( 2 );
152     mTapDetector.DetectedSignal().Connect(this, &Model3dViewController::OnTap);
153
154     mTapDetector.Attach( backView );
155   }
156
157   /**
158    * Main Tap event handler
159    */
160   void OnTap( Actor actor, const TapGesture& tap )
161   {
162     if (mScaled)
163     {
164       mModel3dView.SetScale(1.0);
165       mModel3dView.SetPosition(0,0,0);
166       mScaled = false;
167     }
168     else
169     {
170       Stage stage = Stage::GetCurrent();
171       Vector2 screenSize = stage.GetSize();
172
173       Vector2 position;
174       position.x = tap.screenPoint.x - screenSize.x * 0.5;
175       position.y = tap.screenPoint.y - screenSize.y * 0.5;
176
177       float size = 2.5;
178
179       mModel3dView.SetScale(size);
180       mModel3dView.SetPosition(-position.x * size,-position.y * size, 0);
181       mScaled = true;
182     }
183   }
184
185   /**
186    * Change models button signal function
187    */
188   bool OnChangeModelClicked(Toolkit::Button button)
189   {
190     mModelCounter = (mModelCounter + 1) % MODEL_NUMBER;
191     mModel3dView.SetProperty(Model3dView::Property::GEOMETRY_URL, MODEL_FILE[mModelCounter]);
192     mModel3dView.SetProperty(Model3dView::Property::MATERIAL_URL, MATERIAL_FILE[mModelCounter]);
193     return true;
194   }
195
196   /**
197    * Change shader button signal function
198    */
199   bool OnChangeLightingClicked(Toolkit::Button button)
200   {
201     if( mIlluminationShader == Model3dView::DIFFUSE_WITH_NORMAL_MAP )
202     {
203       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_TEXTURE);
204       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
205     }
206     else if( mIlluminationShader == Model3dView::DIFFUSE_WITH_TEXTURE )
207     {
208       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE);
209       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
210    }
211     else if( mIlluminationShader == Model3dView::DIFFUSE )
212     {
213       mModel3dView.SetProperty(Model3dView::Property::ILLUMINATION_TYPE, Model3dView::DIFFUSE_WITH_NORMAL_MAP);
214       mIlluminationShader = Model3dView::IlluminationType(mModel3dView.GetProperty<int>(Model3dView::Property::ILLUMINATION_TYPE));
215    }
216
217     return true;
218   }
219
220   /**
221    * Function to pause resume all animations
222    */
223   void PauseAnimations()
224   {
225     if( mPlaying )
226     {
227       mRotationAnimation.Pause();
228       mLightAnimation.Pause();
229
230       mPlaying = false;
231     }
232     else
233     {
234       mRotationAnimation.Play();
235       mLightAnimation.Play();
236
237       mPlaying = true;
238     }
239   }
240
241   /**
242    * Pause button signal function
243    */
244   bool OnPauseAnimationsClicked(Toolkit::Button button)
245   {
246     PauseAnimations();
247
248     return true;
249   }
250
251   /**
252    * Main key event handler
253    */
254   void OnKeyEvent(const KeyEvent& event)
255   {
256     if(event.state == KeyEvent::Down)
257     {
258       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
259       {
260         mApplication.Quit();
261       }
262       else
263       {
264         PauseAnimations();
265       }
266     }
267   }
268
269
270 private:
271   Application&  mApplication;
272
273   int mModelCounter;
274   Model3dView mModel3dView;
275
276   Layer mButtonLayer;
277   TapGestureDetector mTapDetector;
278
279   Model3dView::IlluminationType mIlluminationShader;
280
281   Animation mRotationAnimation;
282   Animation mLightAnimation;
283   bool mPlaying;
284
285   bool mScaled;
286 };
287
288 void RunTest( Application& application )
289 {
290   Model3dViewController test( application );
291
292   application.MainLoop();
293 }
294
295 // Entry point for Linux & Tizen applications
296 //
297 int DALI_EXPORT_API main( int argc, char **argv )
298 {
299   Application application = Application::New( &argc, &argv );
300
301   RunTest( application );
302
303   return 0;
304 }