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.45f;
51 class SharedMeshRendererController : public ConnectionTracker
55 SharedMeshRendererController( Application& application )
56 : mApplication( application ), //Store handle to the application.
57 mModelIndex( 1 ), //Start with metal robot.
58 mShaderIndex( 0 ), //Start with all textures.
59 mSelectedModelIndex( 0 ) //Non-valid default, which will get set to a correct value when used.
61 // Connect to the Application's Init signal
62 mApplication.InitSignal().Connect( this, &SharedMeshRendererController::Create );
65 ~SharedMeshRendererController()
69 // The Init signal is received once (only) during the Application lifetime
70 void Create( Application& application )
72 // Get a handle to the stage
73 Stage stage = Stage::GetCurrent();
76 ImageView backView = ImageView::New( BACKGROUND_IMAGE );
77 backView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
78 stage.Add( backView );
80 //Setup and load the 3D models and buttons
84 //Sets up the on-screen elements.
87 Stage stage = Stage::GetCurrent();
89 //Set up 3D layer to place objects on.
90 Layer layer = Layer::New();
91 layer.SetParentOrigin( ParentOrigin::CENTER );
92 layer.SetAnchorPoint( AnchorPoint::CENTER );
93 layer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
94 layer.SetBehavior( Layer::LAYER_3D );
97 //Containers to house each renderer-holding-actor, to provide a constant hitbox for pan detection.
98 Actor container1 = Actor::New();
99 container1.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
100 container1.SetSizeModeFactor( Vector3( MODEL_SCALE, MODEL_SCALE, 0.0f ) );
101 container1.SetParentOrigin( ParentOrigin::CENTER );
102 container1.SetAnchorPoint( AnchorPoint::CENTER );
103 container1.SetPosition( stage.GetSize().width * 0.25, 0.0 ); //Place on right half of screen.
104 container1.RegisterProperty( "Tag", Property::Value( 0 ) ); // Used to identify this actor and index into the model.
105 layer.Add( container1 );
107 Actor container2 = Actor::New();
108 container2.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
109 container2.SetSizeModeFactor( Vector3( MODEL_SCALE / 2, MODEL_SCALE / 2, 0.0f ) );
110 container2.SetParentOrigin( ParentOrigin::CENTER );
111 container2.SetAnchorPoint( AnchorPoint::CENTER );
112 container2.SetPosition( stage.GetSize().width * -0.25, 0.0 ); //Place on left half of screen.
113 container2.RegisterProperty( "Tag", Property::Value( 1 ) ); // Used to identify this actor and index into the model.
114 layer.Add( container2 );
116 //Attach gesture detector to pan models when rotated.
117 mPanGestureDetector = PanGestureDetector::New();
118 mPanGestureDetector.Attach( container1 );
119 mPanGestureDetector.Attach( container2 );
120 mPanGestureDetector.DetectedSignal().Connect( this, &SharedMeshRendererController::OnPan );
122 //Create actors to display meshes.
123 Control control1 = Control::New();
124 control1.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
125 control1.SetParentOrigin( ParentOrigin::CENTER );
126 control1.SetAnchorPoint( AnchorPoint::CENTER );
127 container1.Add( control1 );
129 Control control2 = Control::New();
130 control2.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
131 control2.SetParentOrigin( ParentOrigin::CENTER );
132 control2.SetAnchorPoint( AnchorPoint::CENTER );
133 container2.Add( control2 );
135 //Make actors spin to demonstrate 3D.
136 Animation rotationAnimation1 = Animation::New( 15.0f );
137 rotationAnimation1.AnimateBy( Property( control1, Actor::Property::ORIENTATION ),
138 Quaternion( Degree( 0.0f ), Degree( 360.0f ), Degree( 0.0f ) ) );
139 rotationAnimation1.SetLooping( true );
140 rotationAnimation1.Play();
142 Animation rotationAnimation2 = Animation::New( 15.0f );
143 rotationAnimation2.AnimateBy( Property( control2, Actor::Property::ORIENTATION ),
144 Quaternion( Degree( 0.0f ), Degree( -360.0f ), Degree( 0.0f ) ) );
145 rotationAnimation2.SetLooping( true );
146 rotationAnimation2.Play();
148 //Store model information in corresponding structs.
149 mModels[0].control = control1;
150 mModels[0].rotation.x = 0.0f;
151 mModels[0].rotation.y = 0.0f;
152 mModels[0].rotationAnimation = rotationAnimation1;
154 mModels[1].control = control2;
155 mModels[1].rotation.x = 0.0f;
156 mModels[1].rotation.y = 0.0f;
157 mModels[1].rotationAnimation = rotationAnimation2;
159 //Calling this sets the model in the two actors.
162 //Create button for model changing
163 Toolkit::PushButton modelButton = Toolkit::PushButton::New();
164 modelButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
165 modelButton.ClickedSignal().Connect( this, &SharedMeshRendererController::OnChangeModelClicked );
166 modelButton.SetParentOrigin( Vector3( 0.1, 0.9, 0.5 ) ); //Offset from bottom left
167 modelButton.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
168 modelButton.SetLabelText( "Change Model" );
169 layer.Add( modelButton );
171 //Create button for shader changing
172 Toolkit::PushButton shaderButton = Toolkit::PushButton::New();
173 shaderButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
174 shaderButton.ClickedSignal().Connect( this, &SharedMeshRendererController::OnChangeShaderClicked );
175 shaderButton.SetParentOrigin( Vector3( 0.9, 0.9, 0.5 ) ); //Offset from bottom right
176 shaderButton.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT );
177 shaderButton.SetLabelText( "Change Shader" );
178 layer.Add( shaderButton );
181 //Updates the displayed models to account for parameter changes.
184 //Create mesh property map
186 map.Insert( "rendererType", "mesh" );
187 map.Insert( "objectUrl", MODEL_FILE[mModelIndex] );
188 map.Insert( "materialUrl", MATERIAL_FILE[mModelIndex] );
189 map.Insert( "texturesPath", TEXTURES_PATH );
190 map.Insert( "shaderType", SHADER_TYPE[mShaderIndex] );
192 //Set the two controls to use the mesh
193 mModels[0].control.SetProperty( Control::Property::BACKGROUND, Property::Value( map ) );
194 mModels[1].control.SetProperty( Control::Property::BACKGROUND, Property::Value( map ) );
197 //Rotates the panned model based on the gesture.
198 void OnPan( Actor actor, const PanGesture& gesture )
200 switch( gesture.state )
202 case Gesture::Started:
204 //Find out which model has been selected
205 actor.GetProperty( actor.GetPropertyIndex( "Tag" ) ).Get( mSelectedModelIndex );
207 //Pause current animation, as the gesture will be used to manually rotate the model
208 mModels[mSelectedModelIndex].rotationAnimation.Pause();
212 case Gesture::Continuing:
214 //Rotate based off the gesture.
215 mModels[mSelectedModelIndex].rotation.x -= gesture.displacement.y / X_ROTATION_DISPLACEMENT_FACTOR; // Y displacement rotates around X axis
216 mModels[mSelectedModelIndex].rotation.y += gesture.displacement.x / Y_ROTATION_DISPLACEMENT_FACTOR; // X displacement rotates around Y axis
217 Quaternion rotation = Quaternion( Radian( mModels[mSelectedModelIndex].rotation.x ), Vector3::XAXIS) *
218 Quaternion( Radian( mModels[mSelectedModelIndex].rotation.y ), Vector3::YAXIS);
220 mModels[mSelectedModelIndex].control.SetOrientation( rotation );
224 case Gesture::Finished:
226 //Return to automatic animation
227 mModels[mSelectedModelIndex].rotationAnimation.Play();
231 case Gesture::Cancelled:
233 //Return to automatic animation
234 mModels[mSelectedModelIndex].rotationAnimation.Play();
240 //We can ignore other gestures and gesture states.
246 //Cycle through the list of models.
247 bool OnChangeModelClicked( Toolkit::Button button )
256 //Cycle through the list of shaders.
257 bool OnChangeShaderClicked( Toolkit::Button button )
267 Application& mApplication;
269 //The models displayed on screen, including information about rotation.
272 //Used to detect panning to rotate the selected model.
273 PanGestureDetector mPanGestureDetector;
275 int mModelIndex; //Index of model to load.
276 int mShaderIndex; //Index of shader type to use.
277 int mSelectedModelIndex; //Index of model selected on screen.
280 void RunTest( Application& application )
282 SharedMeshRendererController test( application );
284 application.MainLoop();
287 // Entry point for Linux & Tizen applications
289 int main( int argc, char **argv )
291 Application application = Application::New( &argc, &argv );
293 RunTest( application );