1 #include <dali-toolkit/dali-toolkit.h>
2 #include <dali/public-api/object/property-map.h>
5 using namespace Dali::Toolkit;
9 //Keeps information about each model for access.
12 Control control; // Control housing the mesh renderer of the model.
13 Vector2 rotation; // Keeps track of rotation about x and y axis for manual rotation.
14 Animation rotationAnimation; // Automatically rotates when left alone.
18 const char * const MODEL_FILE[] =
20 DEMO_MODEL_DIR "Dino.obj",
21 DEMO_MODEL_DIR "ToyRobot-Metal.obj",
22 DEMO_MODEL_DIR "Toyrobot-Plastic.obj"
25 const char * const MATERIAL_FILE[] =
27 DEMO_MODEL_DIR "Dino.mtl",
28 DEMO_MODEL_DIR "ToyRobot-Metal.mtl",
29 DEMO_MODEL_DIR "Toyrobot-Plastic.mtl"
32 const char * const TEXTURES_PATH( DEMO_IMAGE_DIR "" );
34 //Possible shader options.
35 const char * const SHADER_TYPE[] =
42 //Files for background and toolbar
43 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-1.jpg");
45 const float X_ROTATION_DISPLACEMENT_FACTOR = 60.0f;
46 const float Y_ROTATION_DISPLACEMENT_FACTOR = 60.0f;
47 const float MODEL_SCALE = 0.75f;
48 const int NUM_MESHES = 3;
52 class MeshRendererController : public ConnectionTracker
56 MeshRendererController( Application& application )
57 : mApplication( application ), //Store handle to the application.
58 mModelIndex( 1 ), //Start with metal robot.
59 mShaderIndex( 0 ), //Start with all textures.
60 mSelectedModelIndex( 0 ) //Non-valid default, which will get set to a correct value when used.
62 // Connect to the Application's Init signal
63 mApplication.InitSignal().Connect( this, &MeshRendererController::Create );
66 ~MeshRendererController()
70 // The Init signal is received once (only) during the Application lifetime
71 void Create( Application& application )
73 // Get a handle to the stage
74 Stage stage = Stage::GetCurrent();
77 ImageView backView = ImageView::New( BACKGROUND_IMAGE );
78 backView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
79 stage.Add( backView );
81 //Setup and load the 3D models and buttons
84 //Allow for exiting of the application via key presses.
85 stage.KeyEventSignal().Connect( this, &MeshRendererController::OnKeyEvent );
88 //Sets up the on-screen elements.
91 Stage stage = Stage::GetCurrent();
93 //Set up 3D layer to place objects on.
94 Layer layer = Layer::New();
95 layer.SetParentOrigin( ParentOrigin::CENTER );
96 layer.SetAnchorPoint( AnchorPoint::CENTER );
97 layer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
98 layer.SetBehavior( Layer::LAYER_2D ); //We use a 2D layer as this is closer to UI work than full 3D scene creation.
99 layer.SetDepthTestDisabled( false ); //Enable depth testing, as otherwise the 2D layer would not do so.
102 //Create gesture detector for panning of models.
103 mPanGestureDetector = PanGestureDetector::New();
104 mPanGestureDetector.DetectedSignal().Connect( this, &MeshRendererController::OnPan );
106 //Add containers to house each renderer-holding-actor.
107 for( int i = 0; i < NUM_MESHES; i++ )
109 mContainers[i] = Actor::New();
110 mContainers[i].SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
111 mContainers[i].RegisterProperty( "Tag", Property::Value( i ) ); //Used to identify the actor and index into the model.
113 //Position each container on screen
116 //Main, central model
117 mContainers[i].SetSizeModeFactor( Vector3( MODEL_SCALE, MODEL_SCALE, 0.0f ) );
118 mContainers[i].SetParentOrigin( ParentOrigin::CENTER );
119 mContainers[i].SetAnchorPoint( AnchorPoint::CENTER );
124 mContainers[i].SetSizeModeFactor( Vector3( MODEL_SCALE / 3.0f, MODEL_SCALE / 3.0f, 0.0f ) );
125 mContainers[i].SetParentOrigin( Vector3( 0.05, 0.03, 0.5 ) ); //Offset from top left
126 mContainers[i].SetAnchorPoint( AnchorPoint::TOP_LEFT );
131 mContainers[i].SetSizeModeFactor( Vector3( MODEL_SCALE / 3.0f, MODEL_SCALE / 3.0f, 0.0f ) );
132 mContainers[i].SetParentOrigin( Vector3( 0.95, 0.03, 0.5 ) ); //Offset from top right
133 mContainers[i].SetAnchorPoint( AnchorPoint::TOP_RIGHT );
136 mPanGestureDetector.Attach( mContainers[i] );
137 layer.Add( mContainers[i] );
141 for( int i = 0; i < NUM_MESHES; i++ )
143 //Create control to display model
144 Control control = Control::New();
145 control.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
146 control.SetParentOrigin( ParentOrigin::CENTER );
147 control.SetAnchorPoint( AnchorPoint::CENTER );
148 mContainers[i].Add( control );
150 //Make model spin to demonstrate 3D
151 Animation rotationAnimation = Animation::New( 15.0f );
152 float spin = i % 2 == 0 ? 1.0f : -1.0f; //Make actors spin in different directions to better show independence.
153 rotationAnimation.AnimateBy( Property( control, Actor::Property::ORIENTATION ),
154 Quaternion( Degree( 0.0f ), Degree( spin * 360.0f ), Degree( 0.0f ) ) );
155 rotationAnimation.SetLooping( true );
156 rotationAnimation.Play();
158 //Store model information in corresponding structs.
159 mModels[i].control = control;
160 mModels[i].rotation.x = 0.0f;
161 mModels[i].rotation.y = 0.0f;
162 mModels[i].rotationAnimation = rotationAnimation;
165 //Calling this sets the model in the controls.
168 //Create button for model changing
169 Toolkit::PushButton modelButton = Toolkit::PushButton::New();
170 modelButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
171 modelButton.ClickedSignal().Connect( this, &MeshRendererController::OnChangeModelClicked );
172 modelButton.SetParentOrigin( Vector3( 0.1, 0.95, 0.5 ) ); //Offset from bottom left
173 modelButton.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
174 modelButton.SetLabelText( "Change Model" );
175 layer.Add( modelButton );
177 //Create button for shader changing
178 Toolkit::PushButton shaderButton = Toolkit::PushButton::New();
179 shaderButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
180 shaderButton.ClickedSignal().Connect( this, &MeshRendererController::OnChangeShaderClicked );
181 shaderButton.SetParentOrigin( Vector3( 0.9, 0.95, 0.5 ) ); //Offset from bottom right
182 shaderButton.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT );
183 shaderButton.SetLabelText( "Change Shader" );
184 layer.Add( shaderButton );
187 //Updates the displayed models to account for parameter changes.
190 //Create mesh property map
192 map.Insert( "rendererType", "mesh" );
193 map.Insert( "objectUrl", MODEL_FILE[mModelIndex] );
194 map.Insert( "materialUrl", MATERIAL_FILE[mModelIndex] );
195 map.Insert( "texturesPath", TEXTURES_PATH );
196 map.Insert( "shaderType", SHADER_TYPE[mShaderIndex] );
198 //Set the two controls to use the mesh
199 for( int i = 0; i < NUM_MESHES; i++ )
201 mModels[i].control.SetProperty( Control::Property::BACKGROUND, Property::Value( map ) );
205 //Rotates the panned model based on the gesture.
206 void OnPan( Actor actor, const PanGesture& gesture )
208 switch( gesture.state )
210 case Gesture::Started:
212 //Find out which model has been selected
213 actor.GetProperty( actor.GetPropertyIndex( "Tag" ) ).Get( mSelectedModelIndex );
215 //Pause current animation, as the gesture will be used to manually rotate the model
216 mModels[mSelectedModelIndex].rotationAnimation.Pause();
220 case Gesture::Continuing:
222 //Rotate based off the gesture.
223 mModels[mSelectedModelIndex].rotation.x -= gesture.displacement.y / X_ROTATION_DISPLACEMENT_FACTOR; // Y displacement rotates around X axis
224 mModels[mSelectedModelIndex].rotation.y += gesture.displacement.x / Y_ROTATION_DISPLACEMENT_FACTOR; // X displacement rotates around Y axis
225 Quaternion rotation = Quaternion( Radian( mModels[mSelectedModelIndex].rotation.x ), Vector3::XAXIS) *
226 Quaternion( Radian( mModels[mSelectedModelIndex].rotation.y ), Vector3::YAXIS);
228 mModels[mSelectedModelIndex].control.SetOrientation( rotation );
232 case Gesture::Finished:
234 //Return to automatic animation
235 mModels[mSelectedModelIndex].rotationAnimation.Play();
239 case Gesture::Cancelled:
241 //Return to automatic animation
242 mModels[mSelectedModelIndex].rotationAnimation.Play();
248 //We can ignore other gestures and gesture states.
254 //Cycle through the list of models.
255 bool OnChangeModelClicked( Toolkit::Button button )
264 //Cycle through the list of shaders.
265 bool OnChangeShaderClicked( Toolkit::Button button )
274 //If escape or the back button is pressed, quit the application (and return to the launcher)
275 void OnKeyEvent( const KeyEvent& event )
277 if( event.state == KeyEvent::Down )
279 if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
287 Application& mApplication;
289 //The models displayed on screen, including information about rotation.
290 Model mModels[NUM_MESHES];
291 Actor mContainers[NUM_MESHES];
293 //Used to detect panning to rotate the selected model.
294 PanGestureDetector mPanGestureDetector;
296 int mModelIndex; //Index of model to load.
297 int mShaderIndex; //Index of shader type to use.
298 int mSelectedModelIndex; //Index of model selected on screen.
301 void RunTest( Application& application )
303 MeshRendererController test( application );
305 application.MainLoop();
308 // Entry point for Linux & Tizen applications
310 int main( int argc, char **argv )
312 Application application = Application::New( &argc, &argv );
314 RunTest( application );