Commit b6a28af6b09c10ad5a29a19b57bd8acbb0f8c0a2

Authored by Andrew Poor
1 parent f4122f44

Implemented a mesh renderer to display 3D objects from files.

Change-Id: I0a9992e6750db54c55f0e40c9e9005875aab6366
com.samsung.dali-demo.xml
... ... @@ -160,4 +160,7 @@
160 160 <ui-application appid="video-view.example" exec="/usr/apps/com.samsung.dali-demo/bin/video-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
161 161 <label>Video View</label>
162 162 </ui-application>
  163 + <ui-application appid="mesh-renderer.example" exec="/usr/apps/com.samsung.dali-demo/bin/mesh-renderer.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
  164 + <label>Mesh Renderer</label>
  165 + </ui-application>
163 166 </manifest>
... ...
demo/dali-demo.cpp
... ... @@ -78,6 +78,7 @@ int DALI_EXPORT_API main(int argc, char **argv)
78 78 demo.AddExample(Example("tilt.example", DALI_DEMO_STR_TITLE_TILT_SENSOR));
79 79 demo.AddExample(Example("effects-view.example", DALI_DEMO_STR_TITLE_EFFECTS_VIEW));
80 80 demo.AddExample(Example("native-image-source.example", DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE));
  81 + demo.AddExample(Example("mesh-renderer.example", DALI_DEMO_STR_TITLE_MESH_RENDERER));
81 82  
82 83 demo.SortAlphabetically( true );
83 84  
... ...
examples/mesh-renderer/mesh-renderer-example.cpp 0 → 100644
  1 +#include <dali-toolkit/dali-toolkit.h>
  2 +#include <dali/public-api/object/property-map.h>
  3 +
  4 +using namespace Dali;
  5 +using namespace Dali::Toolkit;
  6 +
  7 +namespace
  8 +{
  9 + //Keeps information about each model for access.
  10 + struct Model
  11 + {
  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.
  15 + };
  16 +
  17 + //Files for meshes
  18 + const char * const MODEL_FILE[] =
  19 + {
  20 + DEMO_MODEL_DIR "Dino.obj",
  21 + DEMO_MODEL_DIR "ToyRobot-Metal.obj",
  22 + DEMO_MODEL_DIR "Toyrobot-Plastic.obj"
  23 + };
  24 +
  25 + const char * const MATERIAL_FILE[] =
  26 + {
  27 + DEMO_MODEL_DIR "Dino.mtl",
  28 + DEMO_MODEL_DIR "ToyRobot-Metal.mtl",
  29 + DEMO_MODEL_DIR "Toyrobot-Plastic.mtl"
  30 + };
  31 +
  32 + const char * const TEXTURES_PATH( DEMO_IMAGE_DIR "" );
  33 +
  34 + //Possible shader options.
  35 + const char * const SHADER_TYPE[] =
  36 + {
  37 + "allTextures",
  38 + "diffuseTexture",
  39 + "textureless"
  40 + };
  41 +
  42 + //Files for background and toolbar
  43 + const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-1.jpg");
  44 +
  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;
  48 +
  49 +} //End namespace
  50 +
  51 +class SharedMeshRendererController : public ConnectionTracker
  52 +{
  53 +public:
  54 +
  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.
  60 + {
  61 + // Connect to the Application's Init signal
  62 + mApplication.InitSignal().Connect( this, &SharedMeshRendererController::Create );
  63 + }
  64 +
  65 + ~SharedMeshRendererController()
  66 + {
  67 + }
  68 +
  69 + // The Init signal is received once (only) during the Application lifetime
  70 + void Create( Application& application )
  71 + {
  72 + // Get a handle to the stage
  73 + Stage stage = Stage::GetCurrent();
  74 +
  75 + //Add background
  76 + ImageView backView = ImageView::New( BACKGROUND_IMAGE );
  77 + backView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  78 + stage.Add( backView );
  79 +
  80 + //Setup and load the 3D models and buttons
  81 + LoadScene();
  82 + }
  83 +
  84 + //Sets up the on-screen elements.
  85 + void LoadScene()
  86 + {
  87 + Stage stage = Stage::GetCurrent();
  88 +
  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 );
  95 + stage.Add( layer );
  96 +
  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 );
  106 +
  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 );
  115 +
  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 );
  121 +
  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 );
  128 +
  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 );
  134 +
  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();
  141 +
  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();
  147 +
  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;
  153 +
  154 + mModels[1].control = control2;
  155 + mModels[1].rotation.x = 0.0f;
  156 + mModels[1].rotation.y = 0.0f;
  157 + mModels[1].rotationAnimation = rotationAnimation2;
  158 +
  159 + //Calling this sets the model in the two actors.
  160 + ReloadModel();
  161 +
  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 );
  170 +
  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 );
  179 + }
  180 +
  181 + //Updates the displayed models to account for parameter changes.
  182 + void ReloadModel()
  183 + {
  184 + //Create mesh property map
  185 + Property::Map 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] );
  191 +
  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 ) );
  195 + }
  196 +
  197 + //Rotates the panned model based on the gesture.
  198 + void OnPan( Actor actor, const PanGesture& gesture )
  199 + {
  200 + switch( gesture.state )
  201 + {
  202 + case Gesture::Started:
  203 + {
  204 + //Find out which model has been selected
  205 + actor.GetProperty( actor.GetPropertyIndex( "Tag" ) ).Get( mSelectedModelIndex );
  206 +
  207 + //Pause current animation, as the gesture will be used to manually rotate the model
  208 + mModels[mSelectedModelIndex].rotationAnimation.Pause();
  209 +
  210 + break;
  211 + }
  212 + case Gesture::Continuing:
  213 + {
  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);
  219 +
  220 + mModels[mSelectedModelIndex].control.SetOrientation( rotation );
  221 +
  222 + break;
  223 + }
  224 + case Gesture::Finished:
  225 + {
  226 + //Return to automatic animation
  227 + mModels[mSelectedModelIndex].rotationAnimation.Play();
  228 +
  229 + break;
  230 + }
  231 + case Gesture::Cancelled:
  232 + {
  233 + //Return to automatic animation
  234 + mModels[mSelectedModelIndex].rotationAnimation.Play();
  235 +
  236 + break;
  237 + }
  238 + default:
  239 + {
  240 + //We can ignore other gestures and gesture states.
  241 + break;
  242 + }
  243 + }
  244 + }
  245 +
  246 + //Cycle through the list of models.
  247 + bool OnChangeModelClicked( Toolkit::Button button )
  248 + {
  249 + ++mModelIndex %= 3;
  250 +
  251 + ReloadModel();
  252 +
  253 + return true;
  254 + }
  255 +
  256 + //Cycle through the list of shaders.
  257 + bool OnChangeShaderClicked( Toolkit::Button button )
  258 + {
  259 + ++mShaderIndex %= 3;
  260 +
  261 + ReloadModel();
  262 +
  263 + return true;
  264 + }
  265 +
  266 +private:
  267 + Application& mApplication;
  268 +
  269 + //The models displayed on screen, including information about rotation.
  270 + Model mModels[2];
  271 +
  272 + //Used to detect panning to rotate the selected model.
  273 + PanGestureDetector mPanGestureDetector;
  274 +
  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.
  278 +};
  279 +
  280 +void RunTest( Application& application )
  281 +{
  282 + SharedMeshRendererController test( application );
  283 +
  284 + application.MainLoop();
  285 +}
  286 +
  287 +// Entry point for Linux & Tizen applications
  288 +//
  289 +int main( int argc, char **argv )
  290 +{
  291 + Application application = Application::New( &argc, &argv );
  292 +
  293 + RunTest( application );
  294 +
  295 + return 0;
  296 +}
... ...
shared/dali-demo-strings.h
... ... @@ -107,6 +107,7 @@ extern &quot;C&quot;
107 107 #define DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM "Super Blur and Bloom"
108 108 #define DALI_DEMO_STR_TITLE_EFFECTS_VIEW "Effects View"
109 109 #define DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE "Native Image Source"
  110 +#define DALI_DEMO_STR_TITLE_MESH_RENDERER "Mesh Renderer"
110 111  
111 112 #endif
112 113  
... ...