Merge "Tizen Directory Migration" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 22 Jul 2016 16:14:17 +0000 (09:14 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 22 Jul 2016 16:14:17 +0000 (09:14 -0700)
61 files changed:
automated-tests/resources/Cube-Points-Only.obj [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-DebugRenderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp
automated-tests/src/dali-toolkit/utc-Dali-Slider.cpp
automated-tests/src/dali-toolkit/utc-Dali-ToolBar.cpp
build/tizen/Makefile.am
build/tizen/docs/dali.doxy.in
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp
dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp
dali-toolkit/internal/controls/model3d-view/obj-loader.cpp
dali-toolkit/internal/controls/model3d-view/obj-loader.h
dali-toolkit/internal/controls/renderers/debug/debug-renderer.cpp
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h
dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.cpp
dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.h
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h
dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp
dali-toolkit/internal/controls/renderers/renderer-factory-impl.h
dali-toolkit/internal/controls/renderers/renderer-string-constants.cpp
dali-toolkit/internal/controls/renderers/renderer-string-constants.h
dali-toolkit/internal/controls/renderers/svg/svg-renderer.h
dali-toolkit/internal/file.list
dali-toolkit/internal/filters/emboss-filter.cpp
dali-toolkit/internal/text/cursor-helper-functions.cpp
dali-toolkit/internal/text/cursor-helper-functions.h
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/styles/480x800/dali-toolkit-default-theme.json
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json
doc/dali-toolkit-doc.h
docs/content/example-code/properties.cpp
docs/content/images/renderers/bevelled-cube-high.png [new file with mode: 0644]
docs/content/images/renderers/bevelled-cube-low.png [new file with mode: 0644]
docs/content/images/renderers/cone.png [new file with mode: 0644]
docs/content/images/renderers/conical-frustrum.png [new file with mode: 0644]
docs/content/images/renderers/cube.png [new file with mode: 0644]
docs/content/images/renderers/cylinder.png [new file with mode: 0644]
docs/content/images/renderers/octahedron.png [new file with mode: 0644]
docs/content/images/renderers/slices.png [new file with mode: 0644]
docs/content/images/renderers/sphere.png [new file with mode: 0644]
docs/content/images/renderers/stacks.png [new file with mode: 0644]
docs/content/programming-guide/background.h
docs/content/programming-guide/image-view.h
docs/content/programming-guide/properties.h
docs/content/shared-javascript-and-cpp-documentation/control-renderers.md
node-addon/examples/scripts/item-template.json
node-addon/item-template.json
packaging/dali-toolkit.spec
plugins/dali-script-v8/docs/content/animation.js
plugins/dali-script-v8/docs/content/image-view.js
plugins/dali-script-v8/docs/content/item-factory.js

diff --git a/automated-tests/resources/Cube-Points-Only.obj b/automated-tests/resources/Cube-Points-Only.obj
new file mode 100644 (file)
index 0000000..b5fd755
--- /dev/null
@@ -0,0 +1,23 @@
+g cube
+
+v  0.0  0.0  0.0
+v  0.0  0.0  1.0
+v  0.0  1.0  0.0
+v  0.0  1.0  1.0
+v  1.0  0.0  0.0
+v  1.0  0.0  1.0
+v  1.0  1.0  0.0
+v  1.0  1.0  1.0
+
+f  1  7  5
+f  1  3  7
+f  1  4  3
+f  1  2  4
+f  3  8  7
+f  3  4  8
+f  5  7  8
+f  5  8  6
+f  1  5  6
+f  1  6  2
+f  2  6  8
+f  2  8  4
index 1ecf233..fdf25e7 100644 (file)
@@ -396,7 +396,7 @@ int UtcDaliControlBackgroundColor(void)
   Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
   Property::Map* resultMap = propValue.GetMap();
   DALI_TEST_CHECK( resultMap->Find( "rendererType" ) );
-  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "color" );
+  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "COLOR" );
   DALI_TEST_CHECK( resultMap->Find( "mixColor" ) );
   DALI_TEST_CHECK( resultMap->Find( "mixColor" )->Get<Vector4>() == Color::RED );
 
@@ -427,7 +427,7 @@ int UtcDaliControlBackgroundImage(void)
   Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
   Property::Map* resultMap = propValue.GetMap();
   DALI_TEST_CHECK( resultMap->Find( "rendererType" ) );
-  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "IMAGE" );
   DALI_TEST_CHECK( resultMap->Find( "url" ) );
   DALI_TEST_CHECK( resultMap->Find( "url" )->Get<std::string>() == "TestImage" );
 
@@ -451,24 +451,24 @@ int UtcDaliControlBackgroundProperties(void)
   DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() );
 
   Property::Map imageMap;
-  imageMap[ "rendererType" ] = "image";
+  imageMap[ "rendererType" ] = "IMAGE";
   imageMap[ "url" ] = "TestImage";
   control.SetProperty( Control::Property::BACKGROUND, imageMap );
   Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
   Property::Map* resultMap = propValue.GetMap();
   DALI_TEST_CHECK( resultMap->Find( "rendererType" ) );
-  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "IMAGE" );
   DALI_TEST_CHECK( resultMap->Find( "url" ) );
   DALI_TEST_CHECK( resultMap->Find( "url" )->Get<std::string>() == "TestImage" );
 
   Property::Map rendererMap;
-  rendererMap["rendererType"] = "color";
+  rendererMap["rendererType"] = "COLOR";
   rendererMap["mixColor"] = Color::CYAN;
   control.SetProperty( Control::Property::BACKGROUND, rendererMap );
   propValue = control.GetProperty( Control::Property::BACKGROUND );
   resultMap = propValue.GetMap();
   DALI_TEST_CHECK( resultMap->Find( "rendererType" ) );
-  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "color" );
+  DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get<std::string>() == "COLOR" );
   DALI_TEST_CHECK( resultMap->Find( "mixColor" ) );
   DALI_TEST_CHECK( resultMap->Find( "mixColor" )->Get<Vector4>() == Color::CYAN );
 
index 3518778..0fd96ce 100644 (file)
@@ -52,7 +52,7 @@ int UtcDaliControlRendererCopyAndAssignment(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "color");
+  propertyMap.Insert("rendererType",  "COLOR");
   propertyMap.Insert("mixColor",  Color::BLUE);
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
 
@@ -85,7 +85,7 @@ int UtcDaliControlRendererSetGetDepthIndex(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "color");
+  propertyMap.Insert("rendererType",  "COLOR");
   propertyMap.Insert("mixColor",  Color::BLUE);
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
 
@@ -119,7 +119,7 @@ int UtcDaliControlRendererSize(void)
 
   // color renderer
   Dali::Property::Map map;
-  map[ "rendererType" ] = "color";
+  map[ "rendererType" ] = "COLOR";
   map[ "mixColor" ] = Color::MAGENTA;
   ControlRenderer colorRenderer = factory.CreateControlRenderer( map );
   colorRenderer.SetSize( rendererSize );
@@ -149,7 +149,7 @@ int UtcDaliControlRendererSize(void)
   // border renderer
   float borderSize = 5.f;
   map.Clear();
-  map[ "rendererType" ] = "border";
+  map[ "rendererType" ] = "BORDER";
   map[ "borderColor"  ] = Color::RED;
   map[ "borderSize"   ] = borderSize;
   ControlRenderer borderRenderer = factory.CreateControlRenderer( map );
@@ -160,7 +160,7 @@ int UtcDaliControlRendererSize(void)
 
   // gradient renderer
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "gradient");
+  propertyMap.Insert("rendererType",  "GRADIENT");
   Vector2 start(-1.f, -1.f);
   Vector2 end(1.f, 1.f);
   propertyMap.Insert("startPosition",   start);
@@ -196,7 +196,7 @@ int UtcDaliControlRendererSetOnOffStage(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "color");
+  propertyMap.Insert("rendererType",  "COLOR");
   propertyMap.Insert("mixColor",  Color::BLUE);
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
 
@@ -269,7 +269,7 @@ int UtcDaliControlRendererGetPropertyMap1(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "color");
+  propertyMap.Insert("rendererType",  "COLOR");
   propertyMap.Insert("mixColor",  Color::BLUE);
   ControlRenderer colorRenderer = factory.CreateControlRenderer( propertyMap );
 
@@ -278,7 +278,7 @@ int UtcDaliControlRendererGetPropertyMap1(void)
 
   Property::Value* typeValue = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( typeValue );
-  DALI_TEST_CHECK( typeValue->Get<std::string>() == "color" );
+  DALI_TEST_CHECK( typeValue->Get<std::string>() == "COLOR" );
 
   Property::Value* colorValue = resultMap.Find( "mixColor",  Property::VECTOR4 );
   DALI_TEST_CHECK( colorValue );
@@ -305,7 +305,7 @@ int UtcDaliControlRendererGetPropertyMap2(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "border");
+  propertyMap.Insert("rendererType",  "BORDER");
   propertyMap.Insert("borderColor",  Color::BLUE);
   propertyMap.Insert("borderSize",  5.f);
   ControlRenderer borderRenderer = factory.CreateControlRenderer( propertyMap );
@@ -316,7 +316,7 @@ int UtcDaliControlRendererGetPropertyMap2(void)
   // check the property values from the returned map from control renderer
   Property::Value* typeValue = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( typeValue );
-  DALI_TEST_CHECK( typeValue->Get<std::string>() == "border" );
+  DALI_TEST_CHECK( typeValue->Get<std::string>() == "BORDER" );
 
   Property::Value* colorValue = resultMap.Find( "borderColor",  Property::VECTOR4 );
   DALI_TEST_CHECK( colorValue );
@@ -327,7 +327,7 @@ int UtcDaliControlRendererGetPropertyMap2(void)
   DALI_TEST_CHECK( sizeValue->Get<float>() == 5.f );
 
   Property::Map propertyMap1;
-  propertyMap1[ "rendererType" ] = "border";
+  propertyMap1[ "rendererType" ] = "BORDER";
   propertyMap1[ "borderColor"  ] = Color::CYAN;
   propertyMap1[ "borderSize"   ] = 10.0f;
   borderRenderer = factory.CreateControlRenderer( propertyMap1 );
@@ -335,7 +335,7 @@ int UtcDaliControlRendererGetPropertyMap2(void)
 
   typeValue = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( typeValue );
-  DALI_TEST_CHECK( typeValue->Get<std::string>() == "border" );
+  DALI_TEST_CHECK( typeValue->Get<std::string>() == "BORDER" );
 
   colorValue = resultMap.Find( "borderColor",  Property::VECTOR4 );
   DALI_TEST_CHECK( colorValue );
@@ -357,13 +357,13 @@ int UtcDaliControlRendererGetPropertyMap3(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "gradient");
+  propertyMap.Insert("rendererType",  "GRADIENT");
 
   Vector2 start(-1.f, -1.f);
   Vector2 end(1.f, 1.f);
-  propertyMap.Insert("startPosition",   start);
-  propertyMap.Insert("endPosition",   end);
-  propertyMap.Insert("spreadMethod",   "repeat");
+  propertyMap.Insert("startPosition", start);
+  propertyMap.Insert("endPosition", end);
+  propertyMap.Insert("spreadMethod", "REPEAT");
 
   propertyMap.Insert("stopOffset",   Vector2(0.2f, 0.8f));
 
@@ -380,15 +380,15 @@ int UtcDaliControlRendererGetPropertyMap3(void)
   // check the property values from the returned map from control renderer
   Property::Value* value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "gradient" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "GRADIENT" );
 
   value = resultMap.Find( "units",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "objectBoundingBox" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "OBJECT_BOUNDING_BOX" );
 
   value = resultMap.Find( "spreadMethod",   Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "repeat" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "REPEAT" );
 
   value = resultMap.Find( "startPosition",   Property::VECTOR2 );
   DALI_TEST_CHECK( value );
@@ -424,11 +424,11 @@ int UtcDaliControlRendererGetPropertyMap4(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "gradient");
+  propertyMap.Insert("rendererType",  "GRADIENT");
 
   Vector2 center(100.f, 100.f);
   float radius = 100.f;
-  propertyMap.Insert("units",  "userSpace");
+  propertyMap.Insert("units",  "USER_SPACE");
   propertyMap.Insert("center",  center);
   propertyMap.Insert("radius",  radius);
   propertyMap.Insert("stopOffset",   Vector3(0.1f, 0.3f, 1.1f));
@@ -448,15 +448,15 @@ int UtcDaliControlRendererGetPropertyMap4(void)
   // check the property values from the returned map from control renderer
   Property::Value* value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "gradient" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "GRADIENT" );
 
   value = resultMap.Find( "units",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "userSpace" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "USER_SPACE" );
 
   value = resultMap.Find( "spreadMethod",   Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "pad" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "PAD" );
 
   value = resultMap.Find( "center",  Property::VECTOR2 );
   DALI_TEST_CHECK( value );
@@ -493,7 +493,7 @@ int UtcDaliControlRendererGetPropertyMap5(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "image" );
+  propertyMap.Insert( "rendererType",  "IMAGE" );
   propertyMap.Insert( "url",  TEST_IMAGE_FILE_NAME );
   propertyMap.Insert( "desiredWidth",   20 );
   propertyMap.Insert( "desiredHeight",   30 );
@@ -510,7 +510,7 @@ int UtcDaliControlRendererGetPropertyMap5(void)
   // check the property values from the returned map from control renderer
   Property::Value* value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "IMAGE" );
 
   value = resultMap.Find( "url",  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -543,7 +543,7 @@ int UtcDaliControlRendererGetPropertyMap5(void)
 
   value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "IMAGE" );
 
   value = resultMap.Find( "url",  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -579,7 +579,7 @@ int UtcDaliControlRendererGetPropertyMap6(void)
 
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "image" );
+  propertyMap.Insert( "rendererType",  "IMAGE" );
   propertyMap.Insert( "url",  TEST_NPATCH_FILE_NAME );
   propertyMap.Insert( "borderOnly",  true );
   ControlRenderer nPatchRenderer = factory.CreateControlRenderer( propertyMap );
@@ -590,7 +590,7 @@ int UtcDaliControlRendererGetPropertyMap6(void)
   // check the property values from the returned map from control renderer
   Property::Value* value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "IMAGE" );
 
   value = resultMap.Find( "url",  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -611,7 +611,7 @@ int UtcDaliControlRendererGetPropertyMap7(void)
   // request SvgRenderer with a property map
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "image" );
+  propertyMap.Insert( "rendererType",  "IMAGE" );
   propertyMap.Insert( "url",  TEST_SVG_FILE_NAME );
   ControlRenderer svgRenderer = factory.CreateControlRenderer( propertyMap );
 
@@ -620,7 +620,7 @@ int UtcDaliControlRendererGetPropertyMap7(void)
   // check the property values from the returned map from control renderer
   Property::Value* value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "IMAGE" );
 
   value = resultMap.Find( "url",  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -633,7 +633,7 @@ int UtcDaliControlRendererGetPropertyMap7(void)
   // check the property values from the returned map from control renderer
   value = resultMap.Find( "rendererType",  Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "image" );
+  DALI_TEST_CHECK( value->Get<std::string>() == "IMAGE" );
 
   value = resultMap.Find( "url",  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -651,11 +651,12 @@ int UtcDaliControlRendererGetPropertyMap8(void)
   //Request MeshRenderer using a property map.
   RendererFactory factory = RendererFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType", "mesh" );
+  propertyMap.Insert( "rendererType", "MESH" );
   propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
   propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
   propertyMap.Insert( "texturesPath", TEST_RESOURCE_LOCATION );
-  propertyMap.Insert( "shaderType", "textureless" );
+  propertyMap.Insert( "shaderType", "TEXTURELESS" );
+  propertyMap.Insert( "lightPosition", Vector3( 5.0f, 10.0f, 15.0f) );
   ControlRenderer meshRenderer = factory.CreateControlRenderer( propertyMap );
 
   Property::Map resultMap;
@@ -664,23 +665,114 @@ int UtcDaliControlRendererGetPropertyMap8(void)
   //Check values in the result map are identical to the initial map's values.
   Property::Value* value = resultMap.Find( "rendererType", Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "mesh" );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "MESH", TEST_LOCATION );
 
   value = resultMap.Find( "objectUrl", Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == TEST_OBJ_FILE_NAME );
+  DALI_TEST_EQUALS( value->Get<std::string>(), TEST_OBJ_FILE_NAME, TEST_LOCATION );
 
   value = resultMap.Find( "materialUrl", Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == TEST_MTL_FILE_NAME );
+  DALI_TEST_EQUALS( value->Get<std::string>(), TEST_MTL_FILE_NAME, TEST_LOCATION );
 
   value = resultMap.Find( "texturesPath", Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == TEST_RESOURCE_LOCATION );
+  DALI_TEST_EQUALS( value->Get<std::string>(), TEST_RESOURCE_LOCATION, TEST_LOCATION );
 
   value = resultMap.Find( "shaderType", Property::STRING );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<std::string>() == "textureless" );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "TEXTURELESS", TEST_LOCATION );
+
+  value = resultMap.Find( "lightPosition", Property::VECTOR3 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector3>(), Vector3( 5.0f, 10.0f, 15.0f), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  END_TEST;
+}
+
+//Primitive shape renderer
+int UtcDaliControlRendererGetPropertyMap9(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliControlRendererGetPropertyMap9: PrimitiveRenderer" );
+
+  Vector4 color = Vector4( 1.0, 0.8, 0.6, 1.0);
+  Vector3 dimensions = Vector3( 1.0, 2.0, 3.0 );
+
+  //Request PrimitiveRenderer using a property map.
+  RendererFactory factory = RendererFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "CUBE" );
+  propertyMap.Insert( "shapeColor", color );
+  propertyMap.Insert( "slices", 10 );
+  propertyMap.Insert( "stacks", 20 );
+  propertyMap.Insert( "scaleTopRadius", 30.0f );
+  propertyMap.Insert( "scaleBottomRadius", 40.0f );
+  propertyMap.Insert( "scaleHeight", 50.0f );
+  propertyMap.Insert( "scaleRadius", 60.0f );
+  propertyMap.Insert( "scaleDimensions", dimensions );
+  propertyMap.Insert( "bevelPercentage", 0.3f );
+  propertyMap.Insert( "bevelSmoothness", 0.6f );
+  propertyMap.Insert( "lightPosition", Vector3( 5.0f, 10.0f, 15.0f) );
+  ControlRenderer primitiveRenderer = factory.CreateControlRenderer( propertyMap );
+
+  Property::Map resultMap;
+  primitiveRenderer.CreatePropertyMap( resultMap );
+
+  //Check values in the result map are identical to the initial map's values.
+  Property::Value* value = resultMap.Find( "rendererType", Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "PRIMITIVE", TEST_LOCATION );
+
+  value = resultMap.Find( "shape", Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "CUBE", TEST_LOCATION );
+
+  value = resultMap.Find( "shapeColor", Property::VECTOR4 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<Vector4>() == color );
+  DALI_TEST_EQUALS( value->Get<Vector4>(), color, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "slices", Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<int>(), 10, TEST_LOCATION );
+
+  value = resultMap.Find( "stacks", Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<int>(), 20, TEST_LOCATION );
+
+  value = resultMap.Find( "scaleTopRadius", Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 30.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "scaleBottomRadius", Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 40.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "scaleHeight", Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 50.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "scaleRadius", Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 60.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "scaleDimensions", Property::VECTOR3 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector3>(), dimensions, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "bevelPercentage", Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 0.3f, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "bevelSmoothness", Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 0.6f, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( "lightPosition", Property::VECTOR3 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector3>(), Vector3( 5.0f, 10.0f, 15.0f), Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
   END_TEST;
 }
index 3092aff..57543d0 100644 (file)
@@ -40,7 +40,7 @@ bool IsDebugRenderer( ControlRenderer& renderer )
   Property::Value* typeValue = propertyMap.Find( "rendererType",  Property::STRING );
   if ( typeValue )
   {
-    isDebugRendererType = ( typeValue->Get<std::string>() == "debug" );
+    isDebugRendererType = ( typeValue->Get<std::string>() == "DEBUG" );
   }
 
   Actor actor = Actor::New();
@@ -73,7 +73,7 @@ int UtcDaliDebugRendererGetRenderer1(void)
 
   // Test that color renderer is replaced with debug renderer
   Property::Map propertyMap1;
-  propertyMap1.Insert("rendererType",  "color");
+  propertyMap1.Insert("rendererType",  "COLOR");
   propertyMap1.Insert("mixColor",  Color::BLUE);
   ControlRenderer colorRenderer = factory.CreateControlRenderer(propertyMap1);
   DALI_TEST_CHECK( colorRenderer );
@@ -81,7 +81,7 @@ int UtcDaliDebugRendererGetRenderer1(void)
 
   // Test that border renderer is replaced with debug renderer
   Property::Map propertyMap2;
-  propertyMap2.Insert("rendererType",  "border");
+  propertyMap2.Insert("rendererType",  "BORDER");
   propertyMap2.Insert("borderColor",  Color::BLUE);
   propertyMap2.Insert("borderSize",  2.f);
   ControlRenderer borderRenderer = factory.CreateControlRenderer(propertyMap2);
@@ -90,27 +90,27 @@ int UtcDaliDebugRendererGetRenderer1(void)
 
   // Test that gradient renderer is replaced with debug renderer
   Property::Map propertyMap3;
-  propertyMap3.Insert("rendererType",  "gradient");
+  propertyMap3.Insert("rendererType",  "GRADIENT");
   Vector2 start(-1.f, -1.f);
   Vector2 end(1.f, 1.f);
-  propertyMap3.Insert("gradientStartPosition",   start);
-  propertyMap3.Insert("gradientEndPosition",   end);
-  propertyMap3.Insert("gradientSpreadMethod",   "repeat");
+  propertyMap3.Insert("startPosition", start);
+  propertyMap3.Insert("endPosition", end);
+  propertyMap3.Insert("spreadMethod", "REPEAT");
   Property::Array stopOffsets;
   stopOffsets.PushBack( 0.2f );
   stopOffsets.PushBack( 0.8f );
-  propertyMap3.Insert("gradientStopOffset",   stopOffsets);
+  propertyMap3.Insert("stopOffset", stopOffsets);
   Property::Array stopColors;
   stopColors.PushBack( Color::RED );
   stopColors.PushBack( Color::GREEN );
-  propertyMap3.Insert("gradientStopColor",   stopColors);
+  propertyMap3.Insert("stopColor", stopColors);
   ControlRenderer gradientRenderer = factory.CreateControlRenderer(propertyMap3);
   DALI_TEST_CHECK( gradientRenderer );
   DALI_TEST_CHECK( IsDebugRenderer( gradientRenderer ) );
 
   // Test that image renderer is replaced with debug renderer
   Property::Map propertyMap4;
-  propertyMap4.Insert( "rendererType",  "image" );
+  propertyMap4.Insert( "rendererType",  "IMAGE" );
   propertyMap4.Insert( "url",  TEST_IMAGE_FILE_NAME );
   ControlRenderer imageRenderer = factory.CreateControlRenderer( propertyMap4 );
   DALI_TEST_CHECK( imageRenderer );
@@ -118,7 +118,7 @@ int UtcDaliDebugRendererGetRenderer1(void)
 
   // Test that n patch renderer is replaced with debug renderer
   Property::Map propertyMap5;
-  propertyMap5.Insert( "rendererType",  "image" );
+  propertyMap5.Insert( "rendererType",  "IMAGE" );
   propertyMap5.Insert( "url",  TEST_NPATCH_FILE_NAME );
   ControlRenderer nPatchRenderer = factory.CreateControlRenderer( propertyMap4 );
   DALI_TEST_CHECK( nPatchRenderer );
@@ -139,7 +139,7 @@ int UtcDaliDebugRendererGetRenderer2(void)
 
   // Test that color renderer is replaced with debug renderer
   Dali::Property::Map map;
-  map[ "rendererType" ] = "color";
+  map[ "rendererType" ] = "COLOR";
   map[ "mixColor" ] = Color::CYAN;
 
   ControlRenderer colorRenderer = factory.CreateControlRenderer( map);
@@ -148,7 +148,7 @@ int UtcDaliDebugRendererGetRenderer2(void)
 
   // Test that border renderer is replaced with debug renderer
   map.Clear();
-  map[ "rendererType" ] = "border";
+  map[ "rendererType" ] = "BORDER";
   map[ "borderColor"  ] = Color::GREEN;
   map[ "borderSize"   ] = 2.f;
   ControlRenderer borderRenderer = factory.CreateControlRenderer( map );
index aef0a65..2f331b1 100644 (file)
@@ -36,6 +36,7 @@ const char* TEST_NPATCH_FILE_NAME =  "gallery_image_01.9.png";
 const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
 const char* TEST_OBJ_FILE_NAME = TEST_RESOURCE_DIR "/Cube.obj";
 const char* TEST_MTL_FILE_NAME = TEST_RESOURCE_DIR "/ToyRobot-Metal.mtl";
+const char* TEST_SIMPLE_OBJ_FILE_NAME = TEST_RESOURCE_DIR "/Cube-Points-Only.obj";
 const char* TEST_SIMPLE_MTL_FILE_NAME = TEST_RESOURCE_DIR "/ToyRobot-Metal-Simple.mtl";
 
 Integration::Bitmap* CreateBitmap( unsigned int imageWidth, unsigned int imageHeight, unsigned int initialColor, Pixel::Format pixelFormat )
@@ -293,7 +294,7 @@ int UtcDaliRendererFactoryGetColorRenderer1(void)
 
   Property::Map propertyMap;
   Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f );
-  propertyMap.Insert("rendererType",  "color");
+  propertyMap.Insert("rendererType",  "COLOR");
   propertyMap.Insert("mixColor",  testColor);
 
   ControlRenderer controlRenderer = factory.CreateControlRenderer(propertyMap);
@@ -320,7 +321,7 @@ int UtcDaliRendererFactoryGetColorRenderer2(void)
 
   Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f );
   Dali::Property::Map map;
-  map[ "rendererType" ] = "color";
+  map[ "rendererType" ] = "COLOR";
   map[ "mixColor" ] = testColor;
   ControlRenderer controlRenderer = factory.CreateControlRenderer( map );
   DALI_TEST_CHECK( controlRenderer );
@@ -350,7 +351,7 @@ int UtcDaliRendererFactoryGetBorderRenderer1(void)
   Property::Map propertyMap;
   Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f );
   float testSize = 5.f;
-  propertyMap.Insert("rendererType",  "border");
+  propertyMap.Insert("rendererType",  "BORDER");
   propertyMap.Insert("borderColor",  testColor);
   propertyMap.Insert("borderSize",  testSize);
 
@@ -398,7 +399,7 @@ int UtcDaliRendererFactoryGetBorderRenderer2(void)
   float testSize = 5.f;
 
   Dali::Property::Map propertyMap;
-  propertyMap[ "rendererType" ] = "border";
+  propertyMap[ "rendererType" ] = "BORDER";
   propertyMap[ "borderColor"  ] = testColor;
   propertyMap[ "borderSize"   ] = testSize;
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
@@ -432,7 +433,7 @@ int UtcDaliRendererFactoryGetBorderRenderer2(void)
 
   // enable the anti-aliasing
   Dali::Property::Map map;
-  map[ "rendererType" ] = "border";
+  map[ "rendererType" ] = "BORDER";
   map[ "borderColor"  ] = testColor;
   map[ "borderSize"   ] = testSize;
   map[ "antiAliasing"   ] = true;
@@ -456,23 +457,23 @@ int UtcDaliRendererFactoryGetLinearGradientRenderer(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "gradient");
+  propertyMap.Insert("rendererType",  "GRADIENT");
 
   Vector2 start(-1.f, -1.f);
   Vector2 end(1.f, 1.f);
-  propertyMap.Insert("startPosition",   start);
-  propertyMap.Insert("endPosition",   end);
-  propertyMap.Insert("spreadMethod",   "repeat");
+  propertyMap.Insert("startPosition", start);
+  propertyMap.Insert("endPosition", end);
+  propertyMap.Insert("spreadMethod", "REPEAT");
 
   Property::Array stopOffsets;
   stopOffsets.PushBack( 0.2f );
   stopOffsets.PushBack( 0.8f );
-  propertyMap.Insert("stopOffset",   stopOffsets);
+  propertyMap.Insert("stopOffset", stopOffsets);
 
   Property::Array stopColors;
   stopColors.PushBack( Color::RED );
   stopColors.PushBack( Color::GREEN );
-  propertyMap.Insert("stopColor",   stopColors);
+  propertyMap.Insert("stopColor", stopColors);
 
   ControlRenderer controlRenderer = factory.CreateControlRenderer(propertyMap);
   DALI_TEST_CHECK( controlRenderer );
@@ -496,11 +497,11 @@ int UtcDaliRendererFactoryGetRadialGradientRenderer(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "gradient");
+  propertyMap.Insert("rendererType",  "GRADIENT");
 
   Vector2 center(100.f, 100.f);
   float radius = 100.f;
-  propertyMap.Insert("units",  "userSpace");
+  propertyMap.Insert("units",  "USER_SPACE");
   propertyMap.Insert("center",  center);
   propertyMap.Insert("radius",  radius);
 
@@ -541,18 +542,18 @@ int UtcDaliRendererFactoryDefaultOffsetsGradientRenderer(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert("rendererType",  "gradient");
+  propertyMap.Insert("rendererType",  "GRADIENT");
 
   Vector2 start(-1.f, -1.f);
   Vector2 end(1.f, 1.f);
-  propertyMap.Insert("startPosition",   start);
-  propertyMap.Insert("endPosition",   end);
-  propertyMap.Insert("spreadMethod",   "repeat");
+  propertyMap.Insert("startPosition", start);
+  propertyMap.Insert("endPosition", end);
+  propertyMap.Insert("spreadMethod", "REPEAT");
 
   Property::Array stopColors;
   stopColors.PushBack( Color::RED );
   stopColors.PushBack( Color::GREEN );
-  propertyMap.Insert("stopColor",   stopColors);
+  propertyMap.Insert("stopColor", stopColors);
 
   ControlRenderer controlRenderer = factory.CreateControlRenderer(propertyMap);
   DALI_TEST_CHECK( controlRenderer );
@@ -576,7 +577,7 @@ int UtcDaliRendererFactoryGetImageRenderer1(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "image" );
+  propertyMap.Insert( "rendererType",  "IMAGE" );
   propertyMap.Insert( "url",  TEST_IMAGE_FILE_NAME );
 
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
@@ -658,7 +659,7 @@ int UtcDaliRendererFactoryGetNPatchRenderer1(void)
   Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "image" );
+  propertyMap.Insert( "rendererType",  "IMAGE" );
   propertyMap.Insert( "url",  TEST_NPATCH_FILE_NAME );
   {
     tet_infoline( "whole grid" );
@@ -722,7 +723,7 @@ int UtcDaliRendererFactoryGetNPatchRenderer2(void)
   Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "image" );
+  propertyMap.Insert( "rendererType",  "IMAGE" );
   propertyMap.Insert( "url",  TEST_NPATCH_FILE_NAME );
   {
     ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
@@ -949,34 +950,31 @@ int UtcDaliRendererFactoryGetSvgRenderer(void)
   END_TEST;
 }
 
-//Test if mesh loads correctly when supplied with only the bare minimum requirements, an object file.
-int UtcDaliRendererFactoryGetMeshRenderer1(void)
+//Creates a mesh renderer from the given propertyMap and tries to load it on stage in the given application.
+//This is expected to succeed, which will then pass the test.
+void MeshRendererLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplication& application )
 {
-  ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer1:  Request mesh renderer with a valid object file only" );
-
   RendererFactory factory = RendererFactory::Get();
   DALI_TEST_CHECK( factory );
 
-  //Set up renderer properties.
-  Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
-  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
-
+  //Create a mesh renderer.
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
   DALI_TEST_CHECK( controlRenderer );
 
+  //Create an actor on stage to house the renderer.
   Actor actor = Actor::New();
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
   controlRenderer.SetOnStage( actor );
 
+  //Ensure set on stage.
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+
+  //Attempt to render to queue resource load requests.
   application.SendNotification();
   application.Render( 0 );
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-
   //Tell the platform abstraction that the required resources have been loaded.
   TestPlatformAbstraction& platform = application.GetPlatform();
   platform.SetAllResourceRequestsAsLoaded();
@@ -985,49 +983,39 @@ int UtcDaliRendererFactoryGetMeshRenderer1(void)
   application.SendNotification();
   application.Render( 0 );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-
   Matrix testScaleMatrix;
   testScaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
   Matrix actualScaleMatrix;
 
   //Test to see if the object has been successfully loaded.
-  DALI_TEST_CHECK( gl.GetUniformValue<Matrix>( "uObjectMatrix", actualScaleMatrix ) );
+  DALI_TEST_CHECK( application.GetGlAbstraction().GetUniformValue<Matrix>( "uObjectMatrix", actualScaleMatrix ) );
   DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
+  //Finish by setting off stage, and ensuring this was successful.
   controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
-
-  END_TEST;
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
 }
 
-//Test if mesh loads correctly when supplied with an object file as well as a blank material file and images directory.
-int UtcDaliRendererFactoryGetMeshRenderer2(void)
+//Creates a mesh renderer from the given propertyMap and tries to load it on stage in the given application.
+//This is expected to fail, which will then pass the test.
+void MeshRendererDoesNotLoadCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplication& application )
 {
-  ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer2:  Request mesh renderer with blank material file and images directory" );
-
   RendererFactory factory = RendererFactory::Get();
   DALI_TEST_CHECK( factory );
 
-  //Set up renderer properties.
-  Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
-  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
-  propertyMap.Insert( "materialUrl", "" );
-  propertyMap.Insert( "texturesPath", "" );
-
+  //Create a mesh renderer.
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
   DALI_TEST_CHECK( controlRenderer );
 
-  //Add renderer to an actor on stage.
+  //Create an actor on stage to house the renderer.
   Actor actor = Actor::New();
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
   controlRenderer.SetOnStage( actor );
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  //Ensure set on stage.
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
 
   //Attempt to render to queue resource load requests.
   application.SendNotification();
@@ -1041,130 +1029,180 @@ int UtcDaliRendererFactoryGetMeshRenderer2(void)
   application.SendNotification();
   application.Render( 0 );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
+  //Test to see if the object has not been loaded, as expected.
+  Matrix scaleMatrix;
+  DALI_TEST_CHECK( !application.GetGlAbstraction().GetUniformValue<Matrix>( "uObjectMatrix", scaleMatrix ) );
 
-  Matrix testScaleMatrix;
-  testScaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
-  Matrix actualScaleMatrix;
+  //Finish by setting off stage, and ensuring this was successful.
+  controlRenderer.SetOffStage( actor );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+}
 
-  //Test to see if the object has been successfully loaded.
-  DALI_TEST_CHECK( gl.GetUniformValue<Matrix>( "uObjectMatrix", actualScaleMatrix ) );
-  DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+//Test if mesh loads correctly when supplied with only the bare minimum requirements, an object file.
+int UtcDaliRendererFactoryGetMeshRenderer1(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer1:  Request mesh renderer with a valid object file only" );
+
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType",  "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
+
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
+
+  END_TEST;
+}
+
+//Test if mesh loads correctly when supplied with an object file as well as a blank material file and images directory.
+int UtcDaliRendererFactoryGetMeshRenderer2(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
+
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer2:  Request mesh renderer with blank material file and images directory" );
+
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
+  propertyMap.Insert( "materialUrl", "" );
+  propertyMap.Insert( "texturesPath", "" );
+
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
   END_TEST;
 }
 
-//Test if mesh loads correctly when supplied with all parameters, an object file, a material file and a directory location.
+//Test if mesh loads correctly when supplied with all main parameters, an object file, a material file and a directory location.
 int UtcDaliRendererFactoryGetMeshRenderer3(void)
 {
+  //Set up test application first, so everything else can be handled.
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer3:  Request mesh renderer with all parameters correct" );
 
-  RendererFactory factory = RendererFactory::Get();
-  DALI_TEST_CHECK( factory );
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer3:  Request mesh renderer with all parameters correct" );
 
   //Set up renderer properties.
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
+  propertyMap.Insert( "rendererType", "MESH" );
   propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
   propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
   propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
 
-  ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
-  DALI_TEST_CHECK( controlRenderer );
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
-  //Add renderer to an actor on stage.
-  Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
-  controlRenderer.SetOnStage( actor );
+  END_TEST;
+}
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+//Test if mesh renderer can load a correctly supplied mesh without a normal map or gloss map in the material file.
+int UtcDaliRendererFactoryGetMeshRenderer4(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  //Attempt to render to queue resource load requests.
-  application.SendNotification();
-  application.Render( 0 );
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer4:  Request mesh renderer with diffuse texture but not normal or gloss." );
 
-  //Tell the platform abstraction that the required resources have been loaded.
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetAllResourceRequestsAsLoaded();
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
+  propertyMap.Insert( "materialUrl", TEST_SIMPLE_MTL_FILE_NAME );
+  propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
 
-  //Render again to upload the now-loaded textures.
-  application.SendNotification();
-  application.Render( 0 );
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
+  END_TEST;
+}
 
-  Matrix testScaleMatrix;
-  testScaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
-  Matrix actualScaleMatrix;
+//Test if mesh renderer can load when made to use diffuse textures only.
+int UtcDaliRendererFactoryGetMeshRenderer5(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  //Test to see if the object has been successfully loaded.
-  DALI_TEST_CHECK( gl.GetUniformValue<Matrix>( "uObjectMatrix", actualScaleMatrix ) );
-  DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer5:  Request mesh renderer and make it only use diffuse textures." );
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
+  propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
+  propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
+  propertyMap.Insert( "shaderType", "DIFFUSE_TEXTURE" );
+
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
   END_TEST;
 }
 
-//Test if mesh renderer can load a correctly supplied mesh without a normal map or gloss map in the material file.
-int UtcDaliRendererFactoryGetMeshRenderer4(void)
+//Test if mesh renderer can load when made to not use the supplied textures.
+int UtcDaliRendererFactoryGetMeshRenderer6(void)
 {
+  //Set up test application first, so everything else can be handled.
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer4:  Request mesh renderer with diffuse texture but not normal or gloss." );
 
-  RendererFactory factory = RendererFactory::Get();
-  DALI_TEST_CHECK( factory );
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer6:  Request mesh renderer and make it not use any textures." );
 
   //Set up renderer properties.
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
+  propertyMap.Insert( "rendererType", "MESH" );
   propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
-  propertyMap.Insert( "materialUrl", TEST_SIMPLE_MTL_FILE_NAME );
+  propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
   propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
+  propertyMap.Insert( "shaderType", "TEXTURELESS" );
 
-  ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
-  DALI_TEST_CHECK( controlRenderer );
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
-  //Add renderer to an actor on stage.
-  Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
-  controlRenderer.SetOnStage( actor );
+  END_TEST;
+}
+//Test if mesh renderer loads correctly when light position is manually set.
+int UtcDaliRendererFactoryGetMeshRenderer7(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer7:  Request mesh renderer with custom light position." );
 
-  //Attempt to render to queue resource load requests.
-  application.SendNotification();
-  application.Render( 0 );
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
+  propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
+  propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
+  propertyMap.Insert( "lightPosition", Vector3( 0.0, 1.0, 2.0 ) );
 
-  //Tell the platform abstraction that the required resources have been loaded.
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetAllResourceRequestsAsLoaded();
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
-  //Render again to upload the now-loaded textures.
-  application.SendNotification();
-  application.Render( 0 );
+  END_TEST;
+}
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
+//Test if mesh renderer loads correctly when supplied an object file without face normals or texture points.
+//Note that this notably tests object loader functionality.
+int UtcDaliRendererFactoryGetMeshRenderer8(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  Matrix testScaleMatrix;
-  testScaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
-  Matrix actualScaleMatrix;
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRenderer5:  Request mesh renderer with normal-less object file." );
 
-  //Test to see if the object has been successfully loaded.
-  DALI_TEST_CHECK( gl.GetUniformValue<Matrix>( "uObjectMatrix", actualScaleMatrix ) );
-  DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_SIMPLE_OBJ_FILE_NAME );
+  propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
+  propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  //Test to see if mesh loads correctly.
+  MeshRendererLoadsCorrectlyTest( propertyMap, application );
 
   END_TEST;
 }
@@ -1172,154 +1210,295 @@ int UtcDaliRendererFactoryGetMeshRenderer4(void)
 //Test if mesh renderer handles the case of lacking an object file.
 int UtcDaliRendererFactoryGetMeshRendererN1(void)
 {
+  //Set up test application first, so everything else can be handled.
   ToolkitTestApplication application;
+
   tet_infoline( "UtcDaliRendererFactoryGetMeshRendererN1:  Request mesh renderer without object file" );
 
-  RendererFactory factory = RendererFactory::Get();
-  DALI_TEST_CHECK( factory );
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
+  propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
+
+  //Test to see if mesh doesn't load with these properties, as expected.
+  MeshRendererDoesNotLoadCorrectlyTest( propertyMap, application );
+
+  END_TEST;
+}
+
+//Test if mesh renderer handles the case of being passed invalid material and images urls.
+int UtcDaliRendererFactoryGetMeshRendererN2(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
+
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRendererN2:  Request mesh renderer with invalid material and images urls" );
+
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
+  propertyMap.Insert( "materialUrl", "invalid" );
+  propertyMap.Insert( "texturesPath", "also invalid" );
+
+  //Test to see if mesh doesn't load with these properties, as expected.
+  MeshRendererDoesNotLoadCorrectlyTest( propertyMap, application );
+
+  END_TEST;
+}
+
+//Test if mesh renderer handles the case of being passed an invalid object url
+int UtcDaliRendererFactoryGetMeshRendererN3(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
+
+  tet_infoline( "UtcDaliRendererFactoryGetMeshRendererN3:  Request mesh renderer with invalid object url" );
 
   //Set up renderer properties.
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
+  propertyMap.Insert( "rendererType", "MESH" );
+  propertyMap.Insert( "objectUrl", "invalid" );
   propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
   propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
 
+  //Test to see if mesh doesn't load with these properties, as expected.
+  MeshRendererDoesNotLoadCorrectlyTest( propertyMap, application );
+
+  END_TEST;
+}
+
+//Creates a primitive renderer with the given property map and tests to see if it correctly loads in the given application.
+void TestPrimitiveRendererWithProperties( Property::Map& propertyMap, ToolkitTestApplication& application )
+{
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  //Create a primitive renderer.
   ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
   DALI_TEST_CHECK( controlRenderer );
 
-  //Add renderer to an actor on stage.
+  //Create an actor on stage to house the renderer.
   Actor actor = Actor::New();
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
   controlRenderer.SetOnStage( actor );
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  //Ensure set on stage.
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
 
-  //Attempt to render to queue resource load requests.
+  //Tell test application to load the renderer.
   application.SendNotification();
-  application.Render( 0 );
+  application.Render(0);
 
-  //Tell the platform abstraction that the required resources have been loaded.
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetAllResourceRequestsAsLoaded();
+  Matrix testScaleMatrix;
+  testScaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
+  Matrix actualScaleMatrix;
 
-  //Render again to upload the now-loaded textures.
-  application.SendNotification();
-  application.Render( 0 );
+  //Test to see if the object has been successfully loaded.
+  DALI_TEST_CHECK( application.GetGlAbstraction().GetUniformValue<Matrix>( "uObjectMatrix", actualScaleMatrix ) );
+  DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
+  //Finish by setting off stage, and ensuring this was successful.
+  controlRenderer.SetOffStage( actor );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+}
 
-  //Test to see if the object has not been loaded, as expected.
-  Matrix scaleMatrix;
-  DALI_TEST_CHECK( ! gl.GetUniformValue<Matrix>( "uObjectMatrix", scaleMatrix ) );
+//Test if primitive shape loads correctly when supplied with only the bare minimum requirements, the shape to use.
+int UtcDaliRendererFactoryGetPrimitiveRenderer1(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer1:  Request primitive renderer with a shape only" );
+
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "CUBE" );
+
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
   END_TEST;
 }
 
-//Test if mesh renderer handles the case of being passed invalid material and images urls.
-int UtcDaliRendererFactoryGetMeshRendererN2(void)
+//Test if primitive shape loads correctly when supplied with all possible parameters
+int UtcDaliRendererFactoryGetPrimitiveRenderer2(void)
 {
+  //Set up test application first, so everything else can be handled.
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetMeshRendererN2:  Request mesh renderer with invalid material and images urls" );
 
-  RendererFactory factory = RendererFactory::Get();
-  DALI_TEST_CHECK( factory );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer2:  Request primitive renderer with everything" );
 
   //Set up renderer properties.
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
-  propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME );
-  propertyMap.Insert( "materialUrl", "invalid" );
-  propertyMap.Insert( "texturesPath", "also invalid" );
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "CUBE" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
+  propertyMap.Insert( "slices", 10 );
+  propertyMap.Insert( "stacks", 20 );
+  propertyMap.Insert( "scaleTopRadius", 30.0f );
+  propertyMap.Insert( "scaleBottomRadius", 40.0f );
+  propertyMap.Insert( "scaleHeight", 50.0f );
+  propertyMap.Insert( "scaleRadius", 60.0f );
+  propertyMap.Insert( "bevelPercentage", 0.7f );
+  propertyMap.Insert( "bevelSmoothness", 0.8f );
+  propertyMap.Insert( "lightPosition", Vector3( 0.9, 1.0, 1.1 ) );
+
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
-  ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
-  DALI_TEST_CHECK( controlRenderer );
+  END_TEST;
+}
 
-  //Add renderer to an actor on stage.
-  Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
-  controlRenderer.SetOnStage( actor );
+//Test if primitive shape loads a sphere correctly.
+int UtcDaliRendererFactoryGetPrimitiveRenderer3(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer3:  Request primitive renderer to display a sphere" );
 
-  //Attempt to render to queue resource load requests.
-  application.SendNotification();
-  application.Render( 0 );
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "SPHERE" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
+  propertyMap.Insert( "slices", 10 );
+  propertyMap.Insert( "stacks", 20 );
 
-  //Tell the platform abstraction that the required resources have been loaded.
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetAllResourceRequestsAsLoaded();
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
-  //Render again to upload the now-loaded textures.
-  application.SendNotification();
-  application.Render( 0 );
+  END_TEST;
+}
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
+//Test if primitive shape loads a conic section correctly.
+int UtcDaliRendererFactoryGetPrimitiveRenderer4(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  //Test to see if the object has not been loaded, as expected.
-  Matrix scaleMatrix;
-  DALI_TEST_CHECK( ! gl.GetUniformValue<Matrix>( "uObjectMatrix", scaleMatrix ) );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer4:  Request primitive renderer to display a conic section" );
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "CONICAL_FRUSTRUM" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
+  propertyMap.Insert( "slices", 10 );
+  propertyMap.Insert( "scaleTopRadius", 30.0f );
+  propertyMap.Insert( "scaleBottomRadius", 40.0f );
+  propertyMap.Insert( "scaleHeight", 50.0f );
+
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
   END_TEST;
 }
 
-//Test if mesh renderer handles the case of being passed an invalid object url
-int UtcDaliRendererFactoryGetMeshRendererN3(void)
+//Test if primitive shape loads a bevelled cube correctly.
+int UtcDaliRendererFactoryGetPrimitiveRenderer5(void)
 {
+  //Set up test application first, so everything else can be handled.
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetMeshRendererN3:  Request mesh renderer with invalid object url" );
 
-  RendererFactory factory = RendererFactory::Get();
-  DALI_TEST_CHECK( factory );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer5:  Request primitive renderer to display a bevelled cube" );
 
   //Set up renderer properties.
   Property::Map propertyMap;
-  propertyMap.Insert( "rendererType",  "mesh" );
-  propertyMap.Insert( "objectUrl", "invalid" );
-  propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME );
-  propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" );
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "BEVELLED_CUBE" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
+  propertyMap.Insert( "bevelPercentage", 0.7f );
 
-  ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap );
-  DALI_TEST_CHECK( controlRenderer );
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
-  //Add renderer to an actor on stage.
-  Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2( 200.f, 200.f ) );
-  controlRenderer.SetOnStage( actor );
+  END_TEST;
+}
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+//Test if primitive shape loads an octahedron correctly.
+int UtcDaliRendererFactoryGetPrimitiveRenderer6(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  //Attempt to render to queue resource load requests.
-  application.SendNotification();
-  application.Render( 0 );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer6:  Request primitive renderer to display an octahedron" );
 
-  //Tell the platform abstraction that the required resources have been loaded.
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetAllResourceRequestsAsLoaded();
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "OCTAHEDRON" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
 
-  //Render again to upload the now-loaded textures.
-  application.SendNotification();
-  application.Render( 0 );
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
+  END_TEST;
+}
 
-  //Test to see if the object has not been loaded, as expected.
-  Matrix scaleMatrix;
-  DALI_TEST_CHECK( ! gl.GetUniformValue<Matrix>( "uObjectMatrix", scaleMatrix ) );
+//Test if primitive shape loads a cone correctly.
+int UtcDaliRendererFactoryGetPrimitiveRenderer7(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer7:  Request primitive renderer to display a cone" );
+
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "CONE" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
+  propertyMap.Insert( "slices", 10 );
+  propertyMap.Insert( "scaleTopRadius", 30.0f );
+  propertyMap.Insert( "scaleHeight", 50.0f );
+
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
+
+  END_TEST;
+}
+
+//Test if primitive shape loads correctly when light position is manually set.
+int UtcDaliRendererFactoryGetPrimitiveRenderer8(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
+
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer8:  Request primitive renderer with set light position" );
+
+  //Set up renderer properties.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+  propertyMap.Insert( "shape", "SPHERE" );
+  propertyMap.Insert( "shapeColor", Vector4( 0.5, 0.5, 0.5, 1.0 ) );
+  propertyMap.Insert( "lightPosition", Vector3( 0.0, 1.0, 2.0 ) );
+
+  //Test to see if shape loads correctly.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
+
+  END_TEST;
+}
+
+//Test if primitive shape renderer handles the case of not being passed a specific shape to use.
+int UtcDaliRendererFactoryGetPrimitiveRendererN1(void)
+{
+  //Set up test application first, so everything else can be handled.
+  ToolkitTestApplication application;
+
+  tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRendererN1:  Request primitive renderer without shape" );
+
+  //Set up renderer properties, without supplying shape.
+  Property::Map propertyMap;
+  propertyMap.Insert( "rendererType", "PRIMITIVE" );
+
+  //Test to see if shape loads regardless of missing input.
+  TestPrimitiveRendererWithProperties( propertyMap, application );
 
   END_TEST;
 }
index fcfc821..4f1e000 100644 (file)
@@ -333,7 +333,7 @@ int UtcDaliSetPropertyP(void)
 
   {
     Property::Map map;
-    map["rendererType"] = "image";
+    map["rendererType"] = "IMAGE";
     map["size"] = Vector2(200, 200);
     map["url"] = "track2.png";
     slider.SetProperty(Slider::Property::TRACK_VISUAL,       map);
index 9adf9cd..db745a4 100644 (file)
@@ -41,7 +41,7 @@ Actor CreateColorActor( const Vector4& color )
 
   RendererFactory factory = RendererFactory::Get();
   Dali::Property::Map map;
-  map[ "rendererType" ] = "color";
+  map[ "rendererType" ] = "COLOR";
   map[ "mixColor" ] = color;
   ControlRenderer colorRenderer = factory.CreateControlRenderer( map );
   colorRenderer.SetOnStage( solidColorActor );
index a86b976..0d0e733 100644 (file)
@@ -55,7 +55,7 @@ rename_cov_data:
        @for i in `find $(COVERAGE_DIR) -name "libdali_toolkit_la-*.gcda" -o -name "libdali_toolkit_la-*.gcno"` ;\
                do mv $$i `echo $$i | sed s/libdali_toolkit_la-//` ; echo $$i ; done
 
-cov_data:
+cov_data: rename_cov_data
        @cd $(COVERAGE_DIR) ; lcov $(LCOV_OPTS) --base-directory . --directory . -c -o dali.info
        @cd $(COVERAGE_DIR) ; lcov $(LCOV_OPTS) --remove dali.info "/usr/include/*" "*/dali-env/*" "*solid-color-actor*" "*/dali-toolkit/third-party/*"  -o dali.info
        @test -z $(COVERAGE_OUTPUT_DIR) || mkdir -p $(COVERAGE_OUTPUT_DIR)
index f6d268b..d2e0cae 100644 (file)
@@ -751,7 +751,7 @@ GENERATE_DEPRECATEDLIST= YES
 # sections, marked by \if <section_label> ... \endif and \cond <section_label>
 # ... \endcond blocks.
 
-ENABLED_SECTIONS       =
+ENABLED_SECTIONS       = show_tizen_feature
 
 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
 # initial value of a variable or macro / define can have for it to appear in the
index af8cd5c..5e99442 100644 (file)
@@ -566,7 +566,7 @@ void Button::SetColor( const Vector4& color, Button::PaintState selectedState )
       Toolkit::ControlRenderer colorRenderer;
 
       Property::Map map;
-      map["rendererType"] = "color";
+      map["rendererType"] = "COLOR";
       map["mixColor"] = color;
 
       colorRenderer = rendererFactory.CreateControlRenderer( map );
index 9d4d089..4fb7e85 100644 (file)
@@ -161,7 +161,7 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type )
 
     Actor self = Self();
     Property::Map rendererMap;
-    rendererMap.Insert( "rendererType", "image" );
+    rendererMap.Insert( "rendererType", "IMAGE" );
 
     switch( type )
     {
index 2d75ede..e1e4b6f 100644 (file)
@@ -434,7 +434,7 @@ void Model3dView::OnStageConnection( int depth )
 
   if( mObjLoader.IsSceneLoaded() )
   {
-    mMesh = mObjLoader.CreateGeometry( GetShaderProperties( mIlluminationType ) );
+    mMesh = mObjLoader.CreateGeometry( GetShaderProperties( mIlluminationType ), true );
 
     CreateMaterial();
     LoadTextures();
@@ -529,7 +529,7 @@ void Model3dView::CreateGeometry()
 {
   if( mObjLoader.IsSceneLoaded() )
   {
-    mMesh = mObjLoader.CreateGeometry( GetShaderProperties( mIlluminationType ) );
+    mMesh = mObjLoader.CreateGeometry( GetShaderProperties( mIlluminationType ), true );
 
     if( mRenderer )
     {
index 2a34f59..6717bab 100644 (file)
@@ -65,34 +65,103 @@ bool ObjLoader::IsMaterialLoaded()
   return mMaterialLoaded;
 }
 
-//TODO: Use a function that can generate more than one normal/tangent per vertex (using angle)
-void ObjLoader::CalculateTangentArray(const Dali::Vector<Vector3>& vertex,
-                                      const Dali::Vector<Vector2>& texcoord,
-                                      Dali::Vector<TriIndex>& triangle,
-                                      Dali::Vector<Vector3>& normal,
-                                      Dali::Vector<Vector3>& tangent)
+void ObjLoader::CalculateHardFaceNormals( const Dali::Vector<Vector3>& vertices, Dali::Vector<TriIndex>& triangles,
+                                          Dali::Vector<Vector3>& normals )
 {
-  Dali::Vector<Vector3> tangents;
-  tangents.Resize( vertex.Size() );
+  int numFaceVertices = 3 * triangles.Size();  //Vertex per face, as each point has different normals for each face.
+  int normalIndex = 0;  //Tracks progress through the array of normals.
 
-  // Resize of a vector of Vector3 will initialise with the default constructor, setting to all zeros.
+  normals.Clear();
+  normals.Resize( numFaceVertices );
 
-  for ( unsigned long a = 0; a < triangle.Size(); a++ )
+  //For each triangle, calculate the normal by crossing two vectors on the triangle's plane.
+  for( unsigned long i = 0; i < triangles.Size(); i++ )
   {
-    Vector3 tangentVector, normalVector;
+    //Triangle vertices.
+    const Vector3& v0 = vertices[triangles[i].pointIndex[0]];
+    const Vector3& v1 = vertices[triangles[i].pointIndex[1]];
+    const Vector3& v2 = vertices[triangles[i].pointIndex[2]];
+
+    //Triangle edges.
+    Vector3 edge1 = v1 - v0;
+    Vector3 edge2 = v2 - v0;
+
+    //Using edges as vectors on the plane, cross to get the normal.
+    Vector3 normalVector = edge1.Cross(edge2);
+    normalVector.Normalize();
+
+    //Assign normals to points.
+    for( unsigned long j = 0; j < 3; j++, normalIndex++ )
+    {
+      triangles[i].normalIndex[j] = normalIndex;
+      normals[normalIndex] = normalVector;
+    }
+  }
+}
 
-    const Vector3& v0 = vertex[triangle[a].pntIndex[0]];
-    const Vector3& v1 = vertex[triangle[a].pntIndex[1]];
-    const Vector3& v2 = vertex[triangle[a].pntIndex[2]];
+void ObjLoader::CalculateSoftFaceNormals( const Dali::Vector<Vector3>& vertices, Dali::Vector<TriIndex>& triangles,
+                                          Dali::Vector<Vector3>& normals )
+{
+  int normalIndex = 0;  //Tracks progress through the array of normals.
+
+  normals.Clear();
+  normals.Resize( vertices.Size() );  //One (averaged) normal per point.
+
+  //For each triangle, calculate the normal by crossing two vectors on the triangle's plane
+  //We then add the triangle's normal to the cumulative normals at each point of it
+  for( unsigned long i = 0; i < triangles.Size(); i++ )
+  {
+    //Triangle vertices.
+    const Vector3& v0 = vertices[triangles[i].pointIndex[0]];
+    const Vector3& v1 = vertices[triangles[i].pointIndex[1]];
+    const Vector3& v2 = vertices[triangles[i].pointIndex[2]];
 
+    //Triangle edges.
     Vector3 edge1 = v1 - v0;
     Vector3 edge2 = v2 - v0;
 
-    normalVector = edge1.Cross(edge2);
+    //Using edges as vectors on the plane, cross to get the normal.
+    Vector3 normalVector = edge1.Cross(edge2);
+
+    //Add this triangle's normal to the cumulative normal of each constituent point and set the index of the normal accordingly.
+    for( unsigned long j = 0; j < 3; j++, normalIndex++ )
+    {
+      triangles[i].normalIndex[j] = triangles[i].pointIndex[j]; //Normal index matches up to vertex index, as one normal per vertex.
+      normals[triangles[i].normalIndex[j]] += normalVector;
+    }
+  }
+
+  //Normalise the normals.
+  for( unsigned long i = 0; i < normals.Size(); i++ )
+  {
+    normals[i].Normalize();
+  }
+}
+
+//TODO: Use a function that can generate more than one normal/tangent per vertex (using angle)
+void ObjLoader::CalculateTangentFrame()
+{
+  //Reset tangent and bitangent vectors to hold new values.
+  mTangents.Clear();
+  mBiTangents.Clear();
+  mTangents.Resize( mPoints.Size() );
+  mBiTangents.Resize( mPoints.Size() );
+
+  //For each triangle, calculate the tangent vector and then add it to the total tangent vector of each point.
+  for ( unsigned long a = 0; a < mTriangles.Size(); a++ )
+  {
+    Vector3 tangentVector;
 
-    const Vector2& w0 = texcoord[triangle[a].texIndex[0]];
-    const Vector2& w1 = texcoord[triangle[a].texIndex[1]];
-    const Vector2& w2 = texcoord[triangle[a].texIndex[2]];
+    const Vector3& v0 = mPoints[mTriangles[a].pointIndex[0]];
+    const Vector3& v1 = mPoints[mTriangles[a].pointIndex[1]];
+    const Vector3& v2 = mPoints[mTriangles[a].pointIndex[2]];
+
+    Vector3 edge1 = v1 - v0;
+    Vector3 edge2 = v2 - v0;
+
+    const Vector2& w0 = mTextures[mTriangles[a].textureIndex[0]];
+    const Vector2& w1 = mTextures[mTriangles[a].textureIndex[1]];
+    const Vector2& w2 = mTextures[mTriangles[a].textureIndex[2]];
 
     float deltaU1 = w1.x - w0.x;
     float deltaV1 = w1.y - w0.y;
@@ -105,38 +174,25 @@ void ObjLoader::CalculateTangentArray(const Dali::Vector<Vector3>& vertex,
     tangentVector.y = f * ( deltaV2 * edge1.y - deltaV1 * edge2.y );
     tangentVector.z = f * ( deltaV2 * edge1.z - deltaV1 * edge2.z );
 
-    tangents[triangle[a].pntIndex[0]] += tangentVector;
-    tangents[triangle[a].pntIndex[1]] += tangentVector;
-    tangents[triangle[a].pntIndex[2]] += tangentVector;
-
-    normal[triangle[a].pntIndex[0]] += normalVector;
-    normal[triangle[a].pntIndex[1]] += normalVector;
-    normal[triangle[a].pntIndex[2]] += normalVector;
+    mTangents[mTriangles[a].pointIndex[0]] += tangentVector;
+    mTangents[mTriangles[a].pointIndex[1]] += tangentVector;
+    mTangents[mTriangles[a].pointIndex[2]] += tangentVector;
   }
 
-  for ( unsigned long a = 0; a < triangle.Size(); a++ )
+  //Orthogonalize tangents and set binormals.
+  for ( unsigned long a = 0; a < mTangents.Size(); a++ )
   {
-    for ( unsigned long j = 0; j < 3; j++ )
-    {
-      triangle[a].nrmIndex[j] = triangle[a].pntIndex[j];
-    }
-  }
-
-  for ( unsigned long a = 0; a < normal.Size(); a++ )
-  {
-    normal[a].Normalize();
-
-    const Vector3& n = normal[a];
-    const Vector3& t = tangents[a];
+    const Vector3& n = mNormals[a];
+    const Vector3& t = mTangents[a];
 
     // Gram-Schmidt orthogonalize
-    Vector3 calc = t - n * n.Dot(t);
-    calc.Normalize();
-    tangent[a] = Vector3( calc.x,calc.y,calc.z );
+    mTangents[a] = t - n * n.Dot(t);
+    mTangents[a].Normalize();
+
+    mBiTangents[a] = mNormals[a].Cross( mTangents[a] );
   }
 }
 
-
 void ObjLoader::CenterAndScale( bool center, Dali::Vector<Vector3>& points )
 {
   BoundingVolume newAABB;
@@ -153,7 +209,6 @@ void ObjLoader::CenterAndScale( bool center, Dali::Vector<Vector3>& points )
     biggestDimension = sceneSize.z;
   }
 
-
   newAABB.Init();
   for( unsigned int ui = 0; ui < points.Size(); ++ui )
   {
@@ -165,29 +220,39 @@ void ObjLoader::CenterAndScale( bool center, Dali::Vector<Vector3>& points )
   mSceneAABB = newAABB;
 }
 
-void ObjLoader::CreateGeometryArray(Dali::Vector<Vertex> & vertices,
-                                    Dali::Vector<Vector2> & textures,
-                                    Dali::Vector<VertexExt> & verticesExt,
-                                    Dali::Vector<unsigned short> & indices)
+void ObjLoader::CreateGeometryArray( Dali::Vector<Vertex> & vertices,
+                                     Dali::Vector<Vector2> & textures,
+                                     Dali::Vector<VertexExt> & verticesExt,
+                                     Dali::Vector<unsigned short> & indices,
+                                     bool useSoftNormals )
 {
-  //If we don't have tangents, calculate them
-  //we need to recalculate the normals too, because we need just one normal,tangent, bitangent per vertex
-  //In the case of a textureless object, we don't need tangents for our shader and so we skip this step
-  //TODO: Use a better function to calculate tangents
-  if( mTangents.Size() == 0 && mHasTexturePoints )
+  //We must calculate the tangents and bitangents if they weren't supplied, or if they don't match up.
+  bool mustCalculateTangents = mTangents.Size() == 0 || mBiTangents.Size() == 0 ||
+                               mTangents.Size() != mBiTangents.Size() || mTangents.Size() != mNormals.Size() ||
+                               mBiTangents.Size() != mNormals.Size();
+
+  //However, we don't need to do this if the object doesn't use textures to begin with.
+  mustCalculateTangents &= mHasTexturePoints;
+
+  //We also have to recalculate the normals if we need to calculate tangents,
+  // as we need just one normal, tangent and bitangent per vertex, rather than the supplied per-face vertices.
+  //Alternatively, we need to calculate the normals if there weren't any to begin with.
+  if( mNormals.Size() == 0 || mustCalculateTangents )
   {
-    mNormals.Clear();
-
-    mNormals.Resize( mPoints.Size() );
-    mTangents.Resize( mPoints.Size() );
-    mBiTangents.Resize( mPoints.Size() );
-
-    CalculateTangentArray( mPoints, mTextures, mTriangles, mNormals, mTangents );
-
-    for ( unsigned int ui = 0 ; ui < mNormals.Size() ; ++ui )
+    if( useSoftNormals || mustCalculateTangents )
     {
-      mBiTangents[ui] = mNormals[ui].Cross(mTangents[ui]);
+      CalculateSoftFaceNormals( mPoints, mTriangles, mNormals );
     }
+    else
+    {
+      CalculateHardFaceNormals( mPoints, mTriangles, mNormals );
+    }
+  }
+
+  //TODO: Use a better function to calculate tangents
+  if( mHasTexturePoints && mustCalculateTangents )
+  {
+    CalculateTangentFrame();
   }
 
   bool mapsCorrespond; //True if the sizes of the arrays necessary for the object agree.
@@ -232,16 +297,16 @@ void ObjLoader::CreateGeometryArray(Dali::Vector<Vertex> & vertices,
     {
       for ( int j = 0 ; j < 3 ; ++j )
       {
-        indices[indiceIndex] = mTriangles[ui].pntIndex[j];
+        indices[indiceIndex] = mTriangles[ui].pointIndex[j];
         indiceIndex++;
 
-        vertices[mTriangles[ui].pntIndex[j]].normal = mNormals[mTriangles[ui].nrmIndex[j]];
+        vertices[mTriangles[ui].pointIndex[j]].normal = mNormals[mTriangles[ui].normalIndex[j]];
 
         if ( mHasTexturePoints )
         {
-          textures[mTriangles[ui].pntIndex[j]] = mTextures[mTriangles[ui].texIndex[j]];
-          verticesExt[mTriangles[ui].pntIndex[j]].tangent = mTangents[mTriangles[ui].nrmIndex[j]];
-          verticesExt[mTriangles[ui].pntIndex[j]].bitangent = mBiTangents[mTriangles[ui].nrmIndex[j]];
+          textures[mTriangles[ui].pointIndex[j]] = mTextures[mTriangles[ui].textureIndex[j]];
+          verticesExt[mTriangles[ui].pointIndex[j]].tangent = mTangents[mTriangles[ui].normalIndex[j]];
+          verticesExt[mTriangles[ui].pointIndex[j]].bitangent = mBiTangents[mTriangles[ui].normalIndex[j]];
         }
       }
     }
@@ -261,18 +326,17 @@ void ObjLoader::CreateGeometryArray(Dali::Vector<Vertex> & vertices,
       for ( int j = 0 ; j < 3 ; ++j )
       {
         Vertex vertex;
-        vertex.position = mPoints[mTriangles[ui].pntIndex[j]];
-        vertex.normal = mNormals[mTriangles[ui].nrmIndex[j]];
+        vertex.position = mPoints[mTriangles[ui].pointIndex[j]];
+        vertex.normal = mNormals[mTriangles[ui].normalIndex[j]];
         vertices[index] = vertex;
 
         if ( mHasTexturePoints )
         {
-          textures[index] = mTextures[mTriangles[ui].texIndex[j]];
+          textures[index] = mTextures[mTriangles[ui].textureIndex[j]];
           VertexExt vertexExt;
-          vertexExt.tangent = mTangents[mTriangles[ui].nrmIndex[j]];
-          vertexExt.bitangent = mBiTangents[mTriangles[ui].nrmIndex[j]];
+          vertexExt.tangent = mTangents[mTriangles[ui].normalIndex[j]];
+          vertexExt.bitangent = mBiTangents[mTriangles[ui].normalIndex[j]];
           verticesExt[index] = vertexExt;
-
         }
 
         index++;
@@ -440,9 +504,9 @@ bool ObjLoader::LoadObject( char* objBuffer, std::streampos fileSize )
       {
         for( int i = 0 ; i < 3; i++ )
         {
-          triangle.pntIndex[i] = ptIdx[i] - 1 - pntAcum;
-          triangle.nrmIndex[i] = nrmIdx[i] - 1 - nrmAcum;
-          triangle.texIndex[i] = texIdx[i] - 1 - texAcum;
+          triangle.pointIndex[i] = ptIdx[i] - 1 - pntAcum;
+          triangle.normalIndex[i] = nrmIdx[i] - 1 - nrmAcum;
+          triangle.textureIndex[i] = texIdx[i] - 1 - texAcum;
         }
         mTriangles.PushBack( triangle );
         face++;
@@ -452,9 +516,9 @@ bool ObjLoader::LoadObject( char* objBuffer, std::streampos fileSize )
       {
         for( int i = 0 ; i < 3; i++ )
         {
-          triangle.pntIndex[i] = ptIdx[i] - 1 - pntAcum;
-          triangle.nrmIndex[i] = nrmIdx[i] - 1 - nrmAcum;
-          triangle.texIndex[i] = texIdx[i] - 1 - texAcum;
+          triangle.pointIndex[i] = ptIdx[i] - 1 - pntAcum;
+          triangle.normalIndex[i] = nrmIdx[i] - 1 - nrmAcum;
+          triangle.textureIndex[i] = texIdx[i] - 1 - texAcum;
         }
         mTriangles.PushBack( triangle );
         face++;
@@ -462,9 +526,9 @@ bool ObjLoader::LoadObject( char* objBuffer, std::streampos fileSize )
         for( int i = 0 ; i < 3; i++ )
         {
           int idx = ( i + 2 ) % numIndices;
-          triangle2.pntIndex[i] = ptIdx[idx] - 1 - pntAcum;
-          triangle2.nrmIndex[i] = nrmIdx[idx] - 1 - nrmAcum;
-          triangle2.texIndex[i] = texIdx[idx] - 1 - texAcum;
+          triangle2.pointIndex[i] = ptIdx[idx] - 1 - pntAcum;
+          triangle2.normalIndex[i] = nrmIdx[idx] - 1 - nrmAcum;
+          triangle2.textureIndex[i] = texIdx[idx] - 1 - texAcum;
         }
         mTriangles.PushBack( triangle2 );
         face++;
@@ -561,7 +625,7 @@ void ObjLoader::LoadMaterial( char* objBuffer, std::streampos fileSize, std::str
   mMaterialLoaded = true;
 }
 
-Geometry ObjLoader::CreateGeometry( int objectProperties )
+Geometry ObjLoader::CreateGeometry( int objectProperties, bool useSoftNormals )
 {
   Geometry surface = Geometry::New();
 
@@ -570,7 +634,7 @@ Geometry ObjLoader::CreateGeometry( int objectProperties )
   Dali::Vector<VertexExt> verticesExt;
   Dali::Vector<unsigned short> indices;
 
-  CreateGeometryArray( vertices, textures, verticesExt, indices );
+  CreateGeometryArray( vertices, textures, verticesExt, indices, useSoftNormals );
 
   //All vertices need at least Position and Normal
   Property::Map vertexFormat;
index 5f4662d..78de233 100644 (file)
@@ -38,9 +38,9 @@ public:
 
   struct TriIndex
   {
-    int pntIndex[3];
-    int nrmIndex[3];
-    int texIndex[3];
+    int pointIndex[3];
+    int normalIndex[3];
+    int textureIndex[3];
   };
 
   struct Vertex
@@ -111,7 +111,7 @@ public:
   void      LoadMaterial( char* objBuffer, std::streampos fileSize, std::string& diffuseTextureUrl,
                           std::string& normalTextureUrl, std::string& glossTextureUrl );
 
-  Geometry  CreateGeometry( int objectProperties );
+  Geometry  CreateGeometry( int objectProperties, bool useSoftNormals );
 
   Vector3   GetCenter();
   Vector3   GetSize();
@@ -136,27 +136,63 @@ private:
   bool mHasNormalMap;
   bool mHasSpecularMap;
 
-  Dali::Vector<Vector3> mPoints;
-  Dali::Vector<Vector2> mTextures;
-  Dali::Vector<Vector2> mTextures2;
-  Dali::Vector<Vector3> mNormals;
-  Dali::Vector<Vector3> mTangents;
-  Dali::Vector<Vector3> mBiTangents;
+  Dali::Vector<Vector3>  mPoints;
+  Dali::Vector<Vector2>  mTextures;
+  Dali::Vector<Vector2>  mTextures2;
+  Dali::Vector<Vector3>  mNormals;
+  Dali::Vector<Vector3>  mTangents;
+  Dali::Vector<Vector3>  mBiTangents;
   Dali::Vector<TriIndex> mTriangles;
 
-  void CalculateTangentArray( const Dali::Vector<Vector3>& vertex,
-                              const Dali::Vector<Vector2>& texcoord,
-                              Dali::Vector<TriIndex>& triangle,
-                              Dali::Vector<Vector3>& normal,
-                              Dali::Vector<Vector3>& tangent );
+  /**
+   * @brief Calculates normals for each point on a per-face basis.
+   *
+   * There are multiple normals per point, each corresponding to the normal of a face connecting to the point.
+   *
+   * @param[in] vertices The vertices of the object.
+   * @param[in, out] triangles The triangles that form the faces. The normals of each triangle will be updated.
+   * @param[in, out] normals The normals to be calculated.
+   */
+  void CalculateHardFaceNormals( const Dali::Vector<Vector3>& vertices,
+                                 Dali::Vector<TriIndex>& triangles,
+                                 Dali::Vector<Vector3>& normals );
+
+  /**
+   * @brief Calculates smoothed normals for each point.
+   *
+   * There is one normal per point, an average of the connecting faces.
+   *
+   * @param[in] vertices The vertices of the object.
+   * @param[in, out] triangles The triangles that form the faces. The normals of each triangle will be updated.
+   * @param[in, out] normals The normals to be calculated.
+   */
+  void CalculateSoftFaceNormals( const Dali::Vector<Vector3>& vertices,
+                                 Dali::Vector<TriIndex>& triangles,
+                                 Dali::Vector<Vector3>& normals );
+
+  /**
+   * @brief Calculates tangents and bitangents for each point of the object.
+   *
+   * These are calculated using the object's points, texture coordinates and normals, so these must be initialised first.
+   */
+  void CalculateTangentFrame();
 
   void CenterAndScale( bool center, Dali::Vector<Vector3>& points );
 
-
+  /**
+   * @brief Using the data loaded from the file, create arrays of data to be used in creating the geometry.
+   *
+   * @param[in] vertices The vertices of the object.
+   * @param[in] textures The texture coordinates of the object.
+   * @param[in] verticesExt Extension to vertices, storing tangents and bitangents.
+   * @param[in] indices Indices of corresponding values to match triangles to their respective data.
+   * @param[in] useSoftNormals Indicates whether we should average the normals at each point to smooth the surface or not.
+   */
   void CreateGeometryArray( Dali::Vector<Vertex> & vertices,
                             Dali::Vector<Vector2> & textures,
                             Dali::Vector<VertexExt> & verticesExt,
-                            Dali::Vector<unsigned short> & indices );
+                            Dali::Vector<unsigned short> & indices,
+                            bool useSoftNormals );
 
 };
 
index 1fc45ca..68dd38e 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
+#include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
 
 namespace Dali
 {
@@ -35,9 +36,6 @@ namespace Internal
 
 namespace
 {
-const char * const RENDERER_TYPE("rendererType");
-const char * const RENDERER_TYPE_VALUE("debug");
-
 const char * const POSITION_ATTRIBUTE_NAME("aPosition");
 const char * const INDEX_NAME("indices");
 
@@ -82,7 +80,7 @@ void DebugRenderer::DoSetOnStage( Actor& actor )
 void DebugRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
-  map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+  map.Insert( RENDERER_TYPE, DEBUG_RENDERER );
 }
 
 void DebugRenderer::InitializeRenderer()
index 952bd3b..5923bb5 100644 (file)
@@ -59,11 +59,11 @@ const char * const UNITS_NAME("units"); // Property::String  "userSpaceOnUse | o
 const char * const SPREAD_METHOD_NAME("spreadMethod"); // Property::String  "pad | reflect | repeat"
 
 // string values
-const char * const UNIT_USER_SPACE("userSpace");
-const char * const UNIT_BOUNDING_BOX("objectBoundingBox");
-const char * const SPREAD_PAD("pad");
-const char * const SPREAD_REFLECT("reflect");
-const char * const SPREAD_REPEAT("repeat");
+const char * const UNIT_USER_SPACE("USER_SPACE");
+const char * const UNIT_BOUNDING_BOX("OBJECT_BOUNDING_BOX");
+const char * const SPREAD_PAD("PAD");
+const char * const SPREAD_REFLECT("REFLECT");
+const char * const SPREAD_REPEAT("REPEAT");
 
 // uniform names
 const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" );
@@ -196,7 +196,7 @@ void GradientRenderer::DoInitialize( Actor& actor, const Property::Map& property
   Property::Value* unitsValue = propertyMap.Find( UNITS_NAME );
   std::string units;
   // The default unit is OBJECT_BOUNDING_BOX.
-  // Only need to set new units if 'user-space'
+  // Only need to set new units if 'USER_SPACE'
   if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE )
   {
     gradientUnits = Gradient::USER_SPACE_ON_USE;
index f0079f8..3a68519 100644 (file)
@@ -58,6 +58,7 @@ class Gradient;
  *
  * | %Property Name          | Type             |
  * |-------------------------|------------------|
+ * | stopOffset              | ARRAY of FLOAT   |
  * | units                   | STRING           |
  * | spreadMethod            | STRING           |
  *
index dd52948..c2316af 100644 (file)
@@ -20,7 +20,6 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
-#include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/devel-api/adaptor-framework/bitmap-loader.h>
 #include <dali/devel-api/adaptor-framework/file-loader.h>
@@ -28,8 +27,6 @@
 
 //INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
-#include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
-#include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
 
 namespace Dali
@@ -83,9 +80,13 @@ enum TextureIndex
   GLOSS_INDEX = 2u
 };
 
-const char * const RENDERER_TYPE_VALUE( "mesh" ); //String label for which type of control renderer this is.
-const char * const LIGHT_POSITION( "uLightPosition" ); //Shader property
-const char * const OBJECT_MATRIX( "uObjectMatrix" ); //Shader property
+//Shader properties
+const char * const OBJECT_MATRIX_UNIFORM_NAME( "uObjectMatrix" );
+const char * const STAGE_OFFSET_UNIFORM_NAME( "uStageOffset" );
+
+const char * const SHADER_TYPE_TEXTURELESS( "TEXTURELESS" );
+const char * const SHADER_TYPE_DIFFUSE_TEXTURE( "DIFFUSE_TEXTURE" );
+const char * const SHADER_TYPE_ALL_TEXTURES( "ALL_TEXTURES" );
 
 //Shaders
 //If a shader requires certain textures, they must be listed in order,
@@ -99,24 +100,27 @@ const char* SIMPLE_VERTEX_SHADER = DALI_COMPOSE_SHADER(
   uniform mediump vec3 uSize;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump mat4 uModelView;\n
+  uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat3 uNormalMatrix;
   uniform mediump mat4 uObjectMatrix;\n
-  uniform mediump vec3 uLightPosition;\n
+  uniform mediump vec3 lightPosition;\n
+  uniform mediump vec2 uStageOffset;\n
 
   void main()\n
   {\n
-    vec4 vertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
-    vertexPosition = uObjectMatrix * vertexPosition;\n
+    vec4 normalisedVertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
+    vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
     vertexPosition = uMvpMatrix * vertexPosition;\n
 
     //Illumination in Model-View space - Transform attributes and uniforms\n
-    vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n
+    vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
     vec3 normal = uNormalMatrix * mat3( uObjectMatrix ) * aNormal;\n
-    vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n
-    vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n
-    vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
 
-    float lightDiffuse = max( dot( vecToLight, normal ), 0.0 );\n
+    vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+    mvLightPosition = uViewMatrix * mvLightPosition;\n
+    vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
+
+    float lightDiffuse = max( dot( vectorToLight, normal ), 0.0 );\n
     vIllumination = vec3( lightDiffuse * 0.5 + 0.5 );\n
 
     gl_Position = vertexPosition;\n
@@ -146,33 +150,34 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   uniform mediump vec3 uSize;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump mat4 uModelView;
+  uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat3 uNormalMatrix;
   uniform mediump mat4 uObjectMatrix;\n
-  uniform mediump vec3 uLightPosition;\n
+  uniform mediump vec3 lightPosition;\n
+  uniform mediump vec2 uStageOffset;\n
 
   void main()
   {\n
-    vec4 vertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
-    vertexPosition = uObjectMatrix * vertexPosition;\n
+    vec4 normalisedVertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
+    vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
     vertexPosition = uMvpMatrix * vertexPosition;\n
 
     //Illumination in Model-View space - Transform attributes and uniforms\n
-    vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n
-    vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n
-    vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n
+    vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
     vec3 normal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aNormal );\n
 
-    vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
-    vec3 viewDir = normalize( -vertPos.xyz );
+    vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+    mvLightPosition = uViewMatrix * mvLightPosition;\n
+    vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
 
-    vec3 halfVector = normalize( viewDir + vecToLight );
+    vec3 viewDirection = normalize( -mvVertexPosition.xyz );
 
-    float lightDiffuse = dot( vecToLight, normal );\n
+    float lightDiffuse = dot( vectorToLight, normal );\n
     lightDiffuse = max( 0.0,lightDiffuse );\n
     vIllumination = vec3( lightDiffuse * 0.5 + 0.5 );\n
 
-    vec3 reflectDir = reflect( -vecToLight, normal );
-    vSpecular = pow( max( dot( reflectDir, viewDir ), 0.0 ), 4.0 );
+    vec3 reflectDirection = reflect( -vectorToLight, normal );
+    vSpecular = pow( max( dot( reflectDirection, viewDirection ), 0.0 ), 4.0 );
 
     vTexCoord = aTexCoord;\n
     gl_Position = vertexPosition;\n
@@ -209,31 +214,32 @@ const char* NORMAL_MAP_VERTEX_SHADER = DALI_COMPOSE_SHADER(
   uniform mediump vec3 uSize;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump mat4 uModelView;
+  uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat3 uNormalMatrix;
   uniform mediump mat4 uObjectMatrix;\n
-  uniform mediump vec3 uLightPosition;\n
-
+  uniform mediump vec3 lightPosition;\n
+  uniform mediump vec2 uStageOffset;\n
   void main()
   {\n
-    vec4 vertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
-    vertexPosition = uObjectMatrix * vertexPosition;\n
+    vec4 normalisedVertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
+    vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
     vertexPosition = uMvpMatrix * vertexPosition;\n
 
-    vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n
-    vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n
-    vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n
+    vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
 
-    vec3 tangent = normalize( uNormalMatrix * aTangent );
-    vec3 binormal = normalize( uNormalMatrix * aBiNormal );
+    vec3 tangent = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aTangent );
+    vec3 binormal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aBiNormal );
     vec3 normal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aNormal );
 
-    vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
-    vLightDirection.x = dot( vecToLight, tangent );
-    vLightDirection.y = dot( vecToLight, binormal );
-    vLightDirection.z = dot( vecToLight, normal );
+    vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+    mvLightPosition = uViewMatrix * mvLightPosition;\n
+    vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
+    vLightDirection.x = dot( vectorToLight, tangent );
+    vLightDirection.y = dot( vectorToLight, binormal );
+    vLightDirection.z = dot( vectorToLight, normal );
 
-    vec3 viewDir = normalize( -vertPos.xyz );
-    vec3 halfVector = normalize( viewDir + vecToLight );
+    vec3 viewDirection = normalize( -mvVertexPosition.xyz );
+    vec3 halfVector = normalize( viewDirection + vectorToLight );
     vHalfVector.x = dot( halfVector, tangent );
     vHalfVector.y = dot( halfVector, binormal );
     vHalfVector.z = dot( halfVector, normal );
@@ -275,7 +281,8 @@ MeshRenderer::MeshRenderer( RendererFactoryCache& factoryCache )
 : ControlRenderer( factoryCache ),
   mShaderType( ALL_TEXTURES ),
   mUseTexture( true ),
-  mUseMipmapping( true )
+  mUseMipmapping( true ),
+  mUseSoftNormals( true )
 {
 }
 
@@ -292,7 +299,6 @@ void MeshRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap
   }
 
   Property::Value* materialUrl = propertyMap.Find( MATERIAL_URL );
-
   if( !materialUrl || !materialUrl->Get( mMaterialUrl ) || mMaterialUrl.empty() )
   {
     mUseTexture = false;
@@ -306,32 +312,60 @@ void MeshRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap
     mTexturesPath.clear();
   }
 
+  Property::Value* shaderType = propertyMap.Find( SHADER_TYPE );
+  if( shaderType )
+  {
+    std::string shaderTypeString;
+    if( shaderType->Get( shaderTypeString ) )
+    {
+      if( shaderTypeString == SHADER_TYPE_TEXTURELESS )
+      {
+        mShaderType = TEXTURELESS;
+      }
+      else if( shaderTypeString == SHADER_TYPE_DIFFUSE_TEXTURE )
+      {
+        mShaderType = DIFFUSE_TEXTURE;
+      }
+      else if( shaderTypeString == SHADER_TYPE_ALL_TEXTURES )
+      {
+        mShaderType = ALL_TEXTURES;
+      }
+      else
+      {
+        DALI_LOG_ERROR( "Unknown shader type provided to the MeshRenderer object.\n");
+      }
+    }
+  }
+
   Property::Value* useMipmapping = propertyMap.Find( USE_MIPMAPPING );
   if( useMipmapping )
   {
     useMipmapping->Get( mUseMipmapping );
   }
 
-  Property::Value* shaderType = propertyMap.Find( SHADER_TYPE );
-  if( shaderType && shaderType->Get( mShaderTypeString ) )
+  Property::Value* useSoftNormals = propertyMap.Find( USE_SOFT_NORMALS );
+  if( useSoftNormals )
   {
-    if( mShaderTypeString == "textureless" )
-    {
-      mShaderType = TEXTURELESS;
-    }
-    else if( mShaderTypeString == "diffuseTexture" )
-    {
-      mShaderType = DIFFUSE_TEXTURE;
-    }
-    else if( mShaderTypeString == "allTextures" )
-    {
-      mShaderType = ALL_TEXTURES;
-    }
-    else
+    useSoftNormals->Get( mUseSoftNormals );
+  }
+
+  Property::Value* lightPosition = propertyMap.Find( LIGHT_POSITION_UNIFORM_NAME );
+  if( lightPosition )
+  {
+    if( !lightPosition->Get( mLightPosition ) )
     {
-      DALI_LOG_ERROR( "Unknown shader type provided to the MeshRenderer object.\n");
+      DALI_LOG_ERROR( "Invalid value passed for light position in MeshRenderer object.\n" );
+      mLightPosition = Vector3::ZERO;
     }
   }
+  else
+  {
+    //Default behaviour is to place the light directly in front of the object,
+    // at a reasonable distance to light everything on screen.
+    Stage stage = Stage::GetCurrent();
+
+    mLightPosition = Vector3( stage.GetSize().width / 2, stage.GetSize().height / 2, stage.GetSize().width * 5 );
+  }
 }
 
 void MeshRenderer::SetSize( const Vector2& size )
@@ -361,11 +395,37 @@ void MeshRenderer::DoSetOnStage( Actor& actor )
 void MeshRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
-  map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+  map.Insert( RENDERER_TYPE, MESH_RENDERER );
   map.Insert( OBJECT_URL, mObjectUrl );
   map.Insert( MATERIAL_URL, mMaterialUrl );
   map.Insert( TEXTURES_PATH, mTexturesPath );
-  map.Insert( SHADER_TYPE, mShaderTypeString );
+
+  std::string shaderTypeString;
+  switch( mShaderType )
+  {
+    case ALL_TEXTURES:
+    {
+      shaderTypeString = SHADER_TYPE_ALL_TEXTURES;
+      break;
+    }
+
+    case DIFFUSE_TEXTURE:
+    {
+      shaderTypeString = SHADER_TYPE_DIFFUSE_TEXTURE;
+      break;
+    }
+
+    case TEXTURELESS:
+    {
+      shaderTypeString = SHADER_TYPE_TEXTURELESS;
+      break;
+    }
+  }
+  map.Insert( SHADER_TYPE, shaderTypeString );
+
+  map.Insert( USE_MIPMAPPING, mUseMipmapping );
+  map.Insert( USE_SOFT_NORMALS, mUseSoftNormals );
+  map.Insert( LIGHT_POSITION_UNIFORM_NAME, mLightPosition );
 }
 
 void MeshRenderer::InitializeRenderer()
@@ -420,13 +480,15 @@ void MeshRenderer::SupplyEmptyGeometry()
 void MeshRenderer::UpdateShaderUniforms()
 {
   Stage stage = Stage::GetCurrent();
-
-  Vector3 lightPosition( 0, 0, stage.GetSize().width );
-  mShader.RegisterProperty( LIGHT_POSITION, lightPosition );
+  float width = stage.GetSize().width;
+  float height = stage.GetSize().height;
 
   Matrix scaleMatrix;
   scaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
-  mShader.RegisterProperty( OBJECT_MATRIX, scaleMatrix );
+
+  mShader.RegisterProperty( STAGE_OFFSET_UNIFORM_NAME, Vector2( width, height ) / 2.0f );
+  mShader.RegisterProperty( LIGHT_POSITION_UNIFORM_NAME, mLightPosition );
+  mShader.RegisterProperty( OBJECT_MATRIX_UNIFORM_NAME, scaleMatrix );
 }
 
 void MeshRenderer::CreateShader()
@@ -473,7 +535,7 @@ bool MeshRenderer::CreateGeometry()
   }
 
   //Create geometry with attributes required by shader.
-  mGeometry = mObjLoader.CreateGeometry( objectProperties );
+  mGeometry = mObjLoader.CreateGeometry( objectProperties, mUseSoftNormals );
 
   if( mGeometry )
   {
index e5aaee5..2407a09 100644 (file)
@@ -40,12 +40,15 @@ namespace Internal
  *
  * The following Property::Map keys are required to create a MeshRender
  *
- * | %Property Name  | Type        | Representing                            |
- * |-----------------|-------------|-----------------------------------------|
- * | objectUrl       | STRING      | A URL to the .obj file                  |
- * | materialUrl     | STRING      | A URL to the .mtl file                  |
- * | texturesPath    | STRING      | A URL of the path to the texture images |
- * | shaderType      | STRING      | An enum of shader types                 |
+ * | %Property Name  | Type        | Representing                                                          |
+ * |-----------------|-------------|-----------------------------------------------------------------------|
+ * | objectUrl       | STRING      | A URL to the .obj file                                                |
+ * | materialUrl     | STRING      | A URL to the .mtl file                                                |
+ * | texturesPath    | STRING      | A URL of the path to the texture images                               |
+ * | shaderType      | STRING      | An enum of shader types                                               |
+ * | useMipmapping   | BOOLEAN     | If true, use mipmaps for textures. Default true.                      |
+ * | useSoftNormals  | BOOLEAN     | If true, average normals at points for smooth textures. Default true. |
+ * | lightPosition   | VECTOR3     | The position (on stage) of the light                                  |
  */
 class MeshRenderer: public ControlRenderer
 {
@@ -184,8 +187,6 @@ private:
   std::string mGlossTextureUrl;
   std::string mTexturesPath;
 
-  std::string mShaderTypeString;
-
   Shader mShader;
   Geometry mGeometry;
   TextureSet mTextureSet;
@@ -193,10 +194,13 @@ private:
   ObjLoader mObjLoader;
   Vector3 mSceneCenter;
   Vector3 mSceneSize;
+
+  Vector3 mLightPosition;
   ShaderType mShaderType;
 
   bool mUseTexture;
   bool mUseMipmapping;
+  bool mUseSoftNormals;
 };
 
 } // namespace Internal
index 1832e61..c131a84 100644 (file)
@@ -45,7 +45,7 @@ namespace Internal
  *
  * | %Property Name           | Type             |
  * |--------------------------|------------------|
- * | imageUrl                 | STRING           |
+ * | url                      | STRING           |
  * | borderOnly               | BOOLEAN
  *
  */
diff --git a/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.cpp b/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.cpp
new file mode 100644 (file)
index 0000000..33aa60c
--- /dev/null
@@ -0,0 +1,1463 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "primitive-renderer.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/common/constants.h>
+
+//INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
+#include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+//Primitive property defaults
+const int     DEFAULT_SLICES =              128; ///< For spheres and conics
+const int     DEFAULT_STACKS =              128; ///< For spheres and conics
+const float   DEFAULT_SCALE_TOP_RADIUS =    1.0; ///< For conical frustrums
+const float   DEFAULT_SCALE_BOTTOM_RADIUS = 1.5; ///< For cones and conical frustrums
+const float   DEFAULT_SCALE_HEIGHT =        3.0; ///< For all conics
+const float   DEFAULT_SCALE_RADIUS =        1.0; ///< For cylinders
+const float   DEFAULT_BEVEL_PERCENTAGE =    0.0; ///< For bevelled cubes
+const float   DEFAULT_BEVEL_SMOOTHNESS =    0.0; ///< For bevelled cubes
+const Vector4 DEFAULT_COLOR =               Vector4( 0.5, 0.5, 0.5, 0.0 ); ///< Grey, for all.
+
+//Property limits
+const int   MIN_SLICES =           1;   ///< Minimum number of slices for spheres and conics
+const int   MIN_STACKS =           1;   ///< Minimum number of stacks for spheres and conics
+const int   MAX_PARTITIONS =       255; ///< Maximum number of slices or stacks for spheres and conics
+const float MIN_BEVEL_PERCENTAGE = 0.0; ///< Minimum bevel percentage for bevelled cubes
+const float MAX_BEVEL_PERCENTAGE = 1.0; ///< Maximum bevel percentage for bevelled cubes
+const float MIN_SMOOTHNESS =       0.0; ///< Minimum bevel smoothness for bevelled cubes
+const float MAX_SMOOTHNESS =       1.0; ///< Maximum bevel smoothness for bevelled cubes
+
+const char * const RENDERER_TYPE_VALUE( "PRIMITIVE" );
+
+//Specific shape labels.
+const char * const SPHERE_LABEL( "SPHERE" );
+const char * const CONE_LABEL( "CONE" );
+const char * const CONICAL_FRUSTRUM_LABEL( "CONICAL_FRUSTRUM" );
+const char * const CYLINDER_LABEL( "CYLINDER" );
+const char * const CUBE_LABEL( "CUBE" );
+const char * const OCTAHEDRON_LABEL( "OCTAHEDRON" );
+const char * const BEVELLED_CUBE_LABEL( "BEVELLED_CUBE" );
+
+//Shader properties
+const char * const OBJECT_MATRIX_UNIFORM_NAME( "uObjectMatrix" );
+const char * const COLOR_UNIFORM_NAME( "uColor" );
+const char * const OBJECT_DIMENSIONS_UNIFORM_NAME( "uObjectDimensions" );
+const char * const STAGE_OFFSET_UNIFORM_NAME( "uStageOffset" );
+
+//Vertex properties
+const char * const POSITION( "aPosition");
+const char * const NORMAL( "aNormal" );
+const char * const INDICES( "aIndices" );
+
+//A simple shader that applies diffuse lighting to a mono-coloured object.
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute highp   vec3 aPosition;\n
+  attribute highp   vec2 aTexCoord;\n
+  attribute highp   vec3 aNormal;\n
+  varying   mediump vec3 vIllumination;\n
+  uniform   mediump vec3 uSize;\n
+  uniform   mediump vec3 uObjectDimensions;\n
+  uniform   mediump mat4 uMvpMatrix;\n
+  uniform   mediump mat4 uModelView;\n
+  uniform   mediump mat4 uViewMatrix;\n
+  uniform   mediump mat3 uNormalMatrix;\n
+  uniform   mediump mat4 uObjectMatrix;\n
+  uniform   mediump vec3 lightPosition;\n
+  uniform   mediump vec2 uStageOffset;\n
+
+  void main()\n
+  {\n
+    float xRatio = uSize.x / uObjectDimensions.x;\n
+    float yRatio = uSize.y / uObjectDimensions.y;\n
+    float scaleFactor = min( xRatio, yRatio );\n
+
+    vec4 normalisedVertexPosition = vec4( aPosition * scaleFactor, 1.0 );\n
+    vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+
+    //Illumination in Model-View space - Transform attributes and uniforms\n
+    vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
+    vec3 normal = uNormalMatrix * mat3( uObjectMatrix ) * aNormal;\n
+
+    vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+    mvLightPosition = uViewMatrix * mvLightPosition;\n
+    vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
+
+    float lightDiffuse = max( dot( vectorToLight, normal ), 0.0 );\n
+    vIllumination = vec3( lightDiffuse * 0.5 + 0.5 );\n
+
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
+//Very simple fragment shader that merely applies the vertex shading to the color at each fragment.
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+  precision mediump float;\n
+  varying   mediump vec3  vIllumination;\n
+  uniform   lowp    vec4  uColor;\n
+
+  void main()\n
+  {\n
+    gl_FragColor = vec4( vIllumination.rgb * uColor.rgb, uColor.a );\n
+  }\n
+);
+
+} // namespace
+
+PrimitiveRenderer::PrimitiveRenderer( RendererFactoryCache& factoryCache )
+: ControlRenderer( factoryCache ),
+  mColor( DEFAULT_COLOR ),
+  mScaleDimensions( Vector3::ONE ),
+  mScaleTopRadius( DEFAULT_SCALE_TOP_RADIUS ),
+  mScaleBottomRadius( DEFAULT_SCALE_BOTTOM_RADIUS ),
+  mScaleHeight( DEFAULT_SCALE_HEIGHT ),
+  mScaleRadius( DEFAULT_SCALE_RADIUS ),
+  mBevelPercentage( DEFAULT_BEVEL_PERCENTAGE ),
+  mBevelSmoothness( DEFAULT_BEVEL_SMOOTHNESS ),
+  mSlices( DEFAULT_SLICES ),
+  mStacks( DEFAULT_STACKS ),
+  mPrimitiveType( SPHERE )
+{
+}
+
+PrimitiveRenderer::~PrimitiveRenderer()
+{
+}
+
+void PrimitiveRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+{
+  //Find out which shape to renderer.
+  Property::Value* primitiveType = propertyMap.Find( PRIMITIVE_SHAPE );
+  if( primitiveType )
+  {
+    if( primitiveType->Get( mShape ) )
+    {
+      //Set property type as an enum.
+      if( mShape == SPHERE_LABEL )
+      {
+        mPrimitiveType = SPHERE;
+      }
+      else if( mShape == CONE_LABEL )
+      {
+        mPrimitiveType = CONE;
+      }
+      else if( mShape == CONICAL_FRUSTRUM_LABEL )
+      {
+        mPrimitiveType = CONICAL_FRUSTRUM;
+      }
+      else if( mShape == CYLINDER_LABEL )
+      {
+        mPrimitiveType = CYLINDER;
+      }
+      else if( mShape == CUBE_LABEL )
+      {
+        mPrimitiveType = CUBE;
+      }
+      else if( mShape == OCTAHEDRON_LABEL )
+      {
+        mPrimitiveType = OCTAHEDRON;
+      }
+      else if( mShape == BEVELLED_CUBE_LABEL )
+      {
+        mPrimitiveType = BEVELLED_CUBE;
+      }
+      else
+      {
+        DALI_LOG_ERROR( "No known shape in PrimitiveRenderer.\n" );
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Invalid type for shape in PrimitiveRenderer.\n" );
+    }
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Fail to provide shape to the PrimitiveRenderer object.\n" );
+  }
+
+  //Read in other potential properties.
+
+  Property::Value* color = propertyMap.Find( SHAPE_COLOR );
+  if( color && !color->Get( mColor ) )
+  {
+    DALI_LOG_ERROR( "Invalid type for color in PrimitiveRenderer.\n" );
+  }
+
+  Property::Value* slices = propertyMap.Find( SLICES );
+  if( slices )
+  {
+    if( slices->Get( mSlices ) )
+    {
+      //Clamp value.
+      if( mSlices > MAX_PARTITIONS )
+      {
+        mSlices = MAX_PARTITIONS;
+      }
+      else if ( mSlices < MIN_SLICES )
+      {
+        mSlices = MIN_SLICES;
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Invalid type for slices in PrimitiveRenderer.\n" );
+    }
+  }
+
+  Property::Value* stacks = propertyMap.Find( STACKS );
+  if( stacks )
+  {
+    if( stacks->Get( mStacks ) )
+    {
+      //Clamp value.
+      if( mStacks > MAX_PARTITIONS )
+      {
+        mStacks = MAX_PARTITIONS;
+      }
+      else if ( mStacks < MIN_STACKS )
+      {
+        mStacks = MIN_STACKS;
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Invalid type for stacks in PrimitiveRenderer.\n" );
+    }
+  }
+
+  Property::Value* scaleTop = propertyMap.Find( SCALE_TOP_RADIUS );
+  if( scaleTop && !scaleTop->Get( mScaleTopRadius ) )
+  {
+    DALI_LOG_ERROR( "Invalid type for scale top radius in PrimitiveRenderer.\n" );
+  }
+
+  Property::Value* scaleBottom = propertyMap.Find( SCALE_BOTTOM_RADIUS );
+  if( scaleBottom && !scaleBottom->Get( mScaleBottomRadius ) )
+  {
+    DALI_LOG_ERROR( "Invalid type for scale bottom radius in PrimitiveRenderer.\n" );
+  }
+
+  Property::Value* scaleHeight = propertyMap.Find( SCALE_HEIGHT );
+  if( scaleHeight && !scaleHeight->Get( mScaleHeight ) )
+  {
+    DALI_LOG_ERROR( "Invalid type for scale height in PrimitiveRenderer.\n" );
+  }
+
+  Property::Value* scaleRadius = propertyMap.Find( SCALE_RADIUS );
+  if( scaleRadius && !scaleRadius->Get( mScaleRadius ) )
+  {
+    DALI_LOG_ERROR( "Invalid type for scale radius in PrimitiveRenderer.\n" );
+  }
+
+  Property::Value* dimensions = propertyMap.Find( SCALE_DIMENSIONS );
+  if( dimensions )
+  {
+    if( dimensions->Get( mScaleDimensions ) )
+    {
+      //If any dimension is invalid, set it to a sensible default.
+      if( mScaleDimensions.x <= 0.0 )
+      {
+        mScaleDimensions.x = 1.0;
+      }
+      if( mScaleDimensions.y <= 0.0 )
+      {
+        mScaleDimensions.y = 1.0;
+      }
+      if( mScaleDimensions.z <= 0.0 )
+      {
+        mScaleDimensions.z = 1.0;
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Invalid type for scale dimensions in PrimitiveRenderer.\n" );
+    }
+  }
+
+  Property::Value* bevel = propertyMap.Find( BEVEL_PERCENTAGE );
+  if( bevel )
+  {
+    if( bevel->Get( mBevelPercentage ) )
+    {
+      //Clamp value.
+      if( mBevelPercentage < MIN_BEVEL_PERCENTAGE )
+      {
+        mBevelPercentage = MIN_BEVEL_PERCENTAGE;
+      }
+      else if( mBevelPercentage > MAX_BEVEL_PERCENTAGE )
+      {
+        mBevelPercentage = MAX_BEVEL_PERCENTAGE;
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Invalid type for bevel percentage in PrimitiveRenderer.\n" );
+    }
+  }
+
+  Property::Value* smoothness = propertyMap.Find( BEVEL_SMOOTHNESS );
+  if( smoothness )
+  {
+    if( smoothness->Get( mBevelSmoothness ) )
+    {
+      //Clamp value.
+      if( mBevelSmoothness < MIN_SMOOTHNESS )
+      {
+        mBevelSmoothness = MIN_SMOOTHNESS;
+      }
+      else if( mBevelSmoothness > MAX_SMOOTHNESS )
+      {
+        mBevelSmoothness = MAX_SMOOTHNESS;
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Invalid type for bevel smoothness in PrimitiveRenderer.\n" );
+    }
+  }
+
+  //Read in light position.
+  Property::Value* lightPosition = propertyMap.Find( LIGHT_POSITION_UNIFORM_NAME );
+  if( lightPosition )
+  {
+    if( !lightPosition->Get( mLightPosition ) )
+    {
+      DALI_LOG_ERROR( "Invalid value passed for light position in MeshRenderer object.\n" );
+      mLightPosition = Vector3::ZERO;
+    }
+  }
+  else
+  {
+    //Default behaviour is to place the light directly in front of the object,
+    // at a reasonable distance to light everything on screen.
+    Stage stage = Stage::GetCurrent();
+
+    mLightPosition = Vector3( stage.GetSize().width / 2, stage.GetSize().height / 2, stage.GetSize().width * 5 );
+  }
+}
+
+void PrimitiveRenderer::SetSize( const Vector2& size )
+{
+  ControlRenderer::SetSize( size );
+
+  // ToDo: renderer responds to the size change
+}
+
+void PrimitiveRenderer::SetClipRect( const Rect<int>& clipRect )
+{
+  ControlRenderer::SetClipRect( clipRect );
+
+  //ToDo: renderer responds to the clipRect change
+}
+
+void PrimitiveRenderer::SetOffset( const Vector2& offset )
+{
+  //ToDo: renderer applies the offset
+}
+
+void PrimitiveRenderer::DoSetOnStage( Actor& actor )
+{
+  InitializeRenderer();
+}
+
+void PrimitiveRenderer::DoCreatePropertyMap( Property::Map& map ) const
+{
+  map.Clear();
+  map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+  map.Insert( PRIMITIVE_SHAPE, mShape );
+  map.Insert( SHAPE_COLOR, mColor );
+  map.Insert( SLICES, mSlices );
+  map.Insert( STACKS, mStacks );
+  map.Insert( SCALE_TOP_RADIUS, mScaleTopRadius );
+  map.Insert( SCALE_BOTTOM_RADIUS, mScaleBottomRadius );
+  map.Insert( SCALE_HEIGHT, mScaleHeight );
+  map.Insert( SCALE_RADIUS, mScaleRadius );
+  map.Insert( SCALE_DIMENSIONS, mScaleDimensions );
+  map.Insert( BEVEL_PERCENTAGE, mBevelPercentage );
+  map.Insert( BEVEL_SMOOTHNESS, mBevelSmoothness );
+  map.Insert( LIGHT_POSITION_UNIFORM_NAME, mLightPosition );
+}
+
+void PrimitiveRenderer::InitializeRenderer()
+{
+  if( !mGeometry )
+  {
+    CreateGeometry();
+  }
+
+  if( !mShader )
+  {
+    CreateShader();
+  }
+
+  mImpl->mRenderer = Renderer::New( mGeometry, mShader );
+}
+
+void PrimitiveRenderer::UpdateShaderUniforms()
+{
+  Stage stage = Stage::GetCurrent();
+  float width = stage.GetSize().width;
+  float height = stage.GetSize().height;
+
+  //Flip model to account for DALi starting with (0, 0) at the top left.
+  Matrix scaleMatrix;
+  scaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
+
+  mShader.RegisterProperty( STAGE_OFFSET_UNIFORM_NAME, Vector2( width, height ) / 2.0f );
+  mShader.RegisterProperty( LIGHT_POSITION_UNIFORM_NAME, mLightPosition );
+  mShader.RegisterProperty( OBJECT_MATRIX_UNIFORM_NAME, scaleMatrix );
+  mShader.RegisterProperty( COLOR_UNIFORM_NAME, mColor );
+  mShader.RegisterProperty( OBJECT_DIMENSIONS_UNIFORM_NAME, mObjectDimensions );
+}
+
+void PrimitiveRenderer::CreateShader()
+{
+  mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+  UpdateShaderUniforms();
+}
+
+void PrimitiveRenderer::CreateGeometry()
+{
+  Dali::Vector<Vertex> vertices;
+  Dali::Vector<unsigned short> indices;
+
+  switch( mPrimitiveType )
+  {
+    case SPHERE:
+    {
+      CreateSphere( vertices, indices, mSlices, mStacks );
+      break;
+    }
+    case CONE:
+    {
+      //Create a conic with zero top radius.
+      CreateConic( vertices, indices, 0, mScaleBottomRadius, mScaleHeight, mSlices );
+      break;
+    }
+    case CONICAL_FRUSTRUM:
+    {
+      CreateConic( vertices, indices, mScaleTopRadius, mScaleBottomRadius, mScaleHeight, mSlices );
+      break;
+    }
+    case CYLINDER:
+    {
+      //Create a conic with equal radii on the top and bottom.
+      CreateConic( vertices, indices, mScaleRadius, mScaleRadius, mScaleHeight, mSlices );
+      break;
+    }
+    case CUBE:
+    {
+      //Create a cube by creating a bevelled cube with minimum bevel.
+      CreateBevelledCube( vertices, indices, mScaleDimensions, 0.0, 0.0 );
+      break;
+    }
+    case OCTAHEDRON:
+    {
+      //Create an octahedron by creating a bevelled cube with maximum bevel.
+      CreateBevelledCube( vertices, indices, mScaleDimensions, 1.0, mBevelSmoothness );
+      break;
+    }
+    case BEVELLED_CUBE:
+    {
+      CreateBevelledCube( vertices, indices, mScaleDimensions, mBevelPercentage, mBevelSmoothness );
+      break;
+    }
+  }
+
+  mGeometry = Geometry::New();
+
+  //Vertices
+  Property::Map vertexFormat;
+  vertexFormat[POSITION] = Property::VECTOR3;
+  vertexFormat[NORMAL] = Property::VECTOR3;
+  PropertyBuffer surfaceVertices = PropertyBuffer::New( vertexFormat );
+  surfaceVertices.SetData( &vertices[0], vertices.Size() );
+
+  mGeometry.AddVertexBuffer( surfaceVertices );
+
+  //Indices for triangle formulation
+  mGeometry.SetIndexBuffer( &indices[0], indices.Size() );
+}
+
+void PrimitiveRenderer::CreateSphere( Vector<Vertex>& vertices, Vector<unsigned short>& indices, int slices, int stacks )
+{
+  ComputeSphereVertices( vertices, slices, stacks );
+  FormSphereTriangles( indices, slices, stacks );
+
+  mObjectDimensions = Vector3::ONE;
+}
+
+void PrimitiveRenderer::CreateConic( Vector<Vertex>& vertices, Vector<unsigned short>& indices, float scaleTopRadius,
+                                     float scaleBottomRadius, float scaleHeight, int slices )
+{
+  ComputeConicVertices( vertices, scaleTopRadius, scaleBottomRadius, scaleHeight, slices );
+  FormConicTriangles( indices, scaleTopRadius, scaleBottomRadius, slices );
+
+  //Determine object dimensions, and scale them to be between 0.0 and 1.0.
+  float xDimension = std::max( scaleTopRadius, scaleBottomRadius ) * 2.0f;
+  float yDimension = scaleHeight;
+  float largestDimension = std::max( xDimension, yDimension );
+
+  mObjectDimensions = Vector3( xDimension / largestDimension, yDimension / largestDimension,
+                               xDimension / largestDimension );
+}
+
+void PrimitiveRenderer::CreateBevelledCube( Vector<Vertex>& vertices, Vector<unsigned short>& indices,
+                                            Vector3 dimensions, float bevelPercentage, float bevelSmoothness )
+{
+  dimensions.Normalize();
+
+  if( bevelPercentage <= MIN_BEVEL_PERCENTAGE ) //No bevel, form a cube.
+  {
+    ComputeCubeVertices( vertices, dimensions );
+    FormCubeTriangles( indices );
+  }
+  else if( bevelPercentage >= MAX_BEVEL_PERCENTAGE ) //Max bevel, form an octahedron.
+  {
+    ComputeOctahedronVertices( vertices, dimensions, bevelSmoothness );
+    FormOctahedronTriangles( indices );
+  }
+  else //In between, form a bevelled cube.
+  {
+    ComputeBevelledCubeVertices( vertices, dimensions, bevelPercentage, bevelSmoothness );
+    FormBevelledCubeTriangles( indices );
+  }
+
+  mObjectDimensions = dimensions;
+}
+
+void PrimitiveRenderer::ComputeCircleTables( Vector<float>& sinTable, Vector<float>& cosTable, int divisions,
+                                             bool halfCircle )
+{
+  if( divisions < 0 )
+  {
+    return;
+  }
+
+  const float angleDivision = ( halfCircle ? 1.0f : 2.0f ) * Dali::Math::PI / ( float ) divisions;
+
+  sinTable.Resize( divisions );
+  cosTable.Resize( divisions );
+
+  for( int i = 0; i < divisions; i++ )
+  {
+    sinTable[i] = sin( angleDivision * i );
+    cosTable[i] = cos( angleDivision * i );
+  }
+}
+
+void PrimitiveRenderer::ComputeSphereVertices( Vector<Vertex>& vertices, int slices, int stacks )
+{
+  //Tables for calculating slices angles and stacks angles, respectively.
+  Vector<float> sinTable1;
+  Vector<float> cosTable1;
+  Vector<float> sinTable2;
+  Vector<float> cosTable2;
+
+  ComputeCircleTables( sinTable1, cosTable1, slices, false );
+  ComputeCircleTables( sinTable2, cosTable2, stacks, true );
+
+  int numVertices = slices * ( stacks - 1 ) + 2;
+  vertices.Resize( numVertices );
+
+  int vertexIndex = 0;  //Track progress through vertices.
+  float x;
+  float y;
+  float z;
+
+  //Top stack.
+  vertices[vertexIndex].position = Vector3( 0.0, 0.5, 0.0 );
+  vertices[vertexIndex].normal =   Vector3( 0.0, 1.0, 0.0 );
+  vertexIndex++;
+
+  //Middle stacks.
+  for( int i = 1; i < stacks; i++ )
+  {
+    for( int j = 0; j < slices; j++, vertexIndex++ )
+    {
+      x = cosTable1[j] * sinTable2[i];
+      y = cosTable2[i];
+      z = sinTable1[j] * sinTable2[i];
+
+      vertices[vertexIndex].position = Vector3( x / 2.0f, y / 2.0f, z / 2.0f );
+      vertices[vertexIndex].normal = Vector3( x, y, z );
+    }
+  }
+
+  //Bottom stack.
+  vertices[vertexIndex].position = Vector3( 0.0, -0.5, 0.0 );
+  vertices[vertexIndex].normal =   Vector3( 0.0, -1.0, 0.0 );
+}
+
+void PrimitiveRenderer::FormSphereTriangles( Vector<unsigned short>& indices, int slices, int stacks )
+{
+  if( stacks <= 1 )
+  {
+    //Set indices to placeholder "error" values.
+    //This will display nothing, which is the expected behaviour for this edge case.
+    indices.Resize( 3 );
+    return;
+  }
+
+  int numTriangles = 2 * slices * ( stacks - 1 );
+
+  indices.Resize( 3 * numTriangles );
+
+  int indiceIndex = 0;  //Used to keep track of progress through indices.
+  int previousCycleBeginning = 1;  //Stores the index of the vertex that started the cycle of the previous stack.
+  int currentCycleBeginning = 1 + slices;
+
+  //Top stack. Loop from index 1 to index slices, as not counting the very first vertex.
+  for( int i = 1; i <= slices; i++, indiceIndex += 3 )
+  {
+    indices[indiceIndex] = 0;
+    indices[indiceIndex + 1] = i;
+    if( i == slices )
+    {
+      //End, so loop around.
+      indices[indiceIndex + 2] = 1;
+    }
+    else
+    {
+      indices[indiceIndex + 2] = i + 1;
+    }
+  }
+
+  //Middle Stacks. Want to form triangles between the top and bottom stacks, so loop up to the number of stacks - 2.
+  for( int i = 0; i < stacks - 2; i++, previousCycleBeginning += slices, currentCycleBeginning += slices )
+  {
+    for( int j = 0; j < slices; j++, indiceIndex += 6 )
+    {
+      if( j == slices - 1 )
+      {
+        //End, so loop around.
+        indices[indiceIndex] =     previousCycleBeginning + j;
+        indices[indiceIndex + 1] = currentCycleBeginning + j;
+        indices[indiceIndex + 2] = previousCycleBeginning;
+        indices[indiceIndex + 3] = currentCycleBeginning + j;
+        indices[indiceIndex + 4] = currentCycleBeginning;
+        indices[indiceIndex + 5] = previousCycleBeginning;
+      }
+      else
+      {
+        indices[indiceIndex] =     previousCycleBeginning + j;
+        indices[indiceIndex + 1] = currentCycleBeginning + j;
+        indices[indiceIndex + 2] = previousCycleBeginning + 1 + j;
+        indices[indiceIndex + 3] = currentCycleBeginning + j;
+        indices[indiceIndex + 4] = currentCycleBeginning + 1 + j;
+        indices[indiceIndex + 5] = previousCycleBeginning + 1 + j;
+      }
+    }
+  }
+
+  //Bottom stack. Loop around the last stack from the previous loop, and go up to the penultimate vertex.
+  for( int i = 0; i < slices; i++, indiceIndex += 3 )
+  {
+    indices[indiceIndex] = previousCycleBeginning + slices;
+    indices[indiceIndex + 1] = previousCycleBeginning + i;
+    if( i == slices - 1 )
+    {
+      //End, so loop around.
+      indices[indiceIndex + 2] = previousCycleBeginning;
+    }
+    else
+    {
+      indices[indiceIndex + 2] = previousCycleBeginning + i + 1;
+    }
+  }
+}
+
+void PrimitiveRenderer::ComputeConicVertices( Vector<Vertex>& vertices, float scaleTopRadius,
+                                                     float scaleBottomRadius, float scaleHeight, int slices )
+{
+  int vertexIndex = 0;  //Track progress through vertices.
+  Vector<float> sinTable;
+  Vector<float> cosTable;
+
+  ComputeCircleTables( sinTable, cosTable, slices, false );
+
+  int numVertices = 2;  //Always will have one at the top and one at the bottom.
+
+  //Add vertices for each circle. Need two per point for different face normals.
+  if( scaleTopRadius > 0.0 )
+  {
+    numVertices += 2 * slices;
+  }
+  if( scaleBottomRadius > 0.0 )
+  {
+    numVertices += 2 * slices;
+  }
+
+  vertices.Resize( numVertices );
+
+
+  //Scale to bounding region of -0.5 to 0.5 (i.e range of 1).
+  float biggestObjectDimension = std::max( std::max( scaleTopRadius * 2.0f, scaleBottomRadius * 2.0f ), scaleHeight );
+  scaleTopRadius = scaleTopRadius / biggestObjectDimension;
+  scaleBottomRadius = scaleBottomRadius / biggestObjectDimension;
+
+  //Dimensions for vertex coordinates. Y is constant, and so can be initialised now.
+  float x;
+  float y = scaleHeight / biggestObjectDimension / 2.0f;
+  float z;
+
+  //Top center.
+  vertices[0].position = Vector3( 0, y, 0 );
+  vertices[0].normal = Vector3( 0, 1, 0 );
+  vertexIndex++;
+
+  //Top circle.
+  if( scaleTopRadius > 0.0 )
+  {
+    //Loop around the circle.
+    for( int i = 0; i < slices; i++, vertexIndex++ )
+    {
+      x = sinTable[i] * scaleTopRadius;
+      z = cosTable[i] * scaleTopRadius;
+
+      //Upward-facing normal.
+      vertices[vertexIndex].position = Vector3( x, y, z );
+      vertices[vertexIndex].normal = Vector3( 0, 1, 0 );
+
+      //Outward-facing normal.
+      vertices[vertexIndex + slices].position = Vector3( x, y, z );
+      vertices[vertexIndex + slices].normal = Vector3( x, 0, z );
+    }
+
+    vertexIndex += slices;
+  }
+
+  //Bottom circle.
+  if( scaleBottomRadius > 0.0 )
+  {
+    //Loop around the circle.
+    for( int i = 0; i < slices; i++, vertexIndex++ )
+    {
+      x = sinTable[i] * scaleBottomRadius;
+      z = cosTable[i] * scaleBottomRadius;
+
+      //Outward-facing normal.
+      vertices[vertexIndex].position = Vector3( x, -y, z );
+      vertices[vertexIndex].normal = Vector3( x, 0, z );
+
+      //Downward-facing normal.
+      vertices[vertexIndex + slices].position = Vector3( x, -y, z );
+      vertices[vertexIndex + slices].normal = Vector3( 0, -1, 0 );
+    }
+
+    vertexIndex += slices;
+  }
+
+  //Bottom center.
+  vertices[vertexIndex].position = Vector3( 0, -y, 0 );
+  vertices[vertexIndex].normal = Vector3( 0, -1, 0 );
+  vertexIndex++;
+}
+
+void PrimitiveRenderer::FormConicTriangles( Vector<unsigned short>& indices, float scaleTopRadius,
+                                                   float scaleBottomRadius, int slices )
+{
+  int  indiceIndex = 0;  //Track progress through indices.
+  int  numTriangles = 0;
+  bool coneTop = scaleTopRadius <= 0.0;
+  bool coneBottom = scaleBottomRadius <= 0.0;
+
+  if( coneTop && coneBottom )
+  {
+    //Set indices to placeholder "error" values.
+    //This will display nothing, which is the expected behaviour for this edge case.
+    indices.Resize( 3 );
+    return;
+  }
+
+  if( !coneTop )
+  {
+    numTriangles += 2 * slices;
+  }
+  if( !coneBottom )
+  {
+    numTriangles += 2 * slices;
+  }
+
+  indices.Resize( 3 * numTriangles );
+
+  //Switch on the type of conic we have.
+  if( !coneTop && !coneBottom )
+  {
+    //Top circle. Start at index of first outer point and go around.
+    for( int i = 1; i <= slices; i++, indiceIndex += 3 )
+    {
+      indices[indiceIndex] = 0;
+      indices[indiceIndex + 1] = i;
+      if( i == slices )
+      {
+        //End, so loop around.
+        indices[indiceIndex + 2] = 1;
+      }
+      else
+      {
+        indices[indiceIndex + 2] = i + 1;
+      }
+    }
+
+    int topCycleBeginning = slices + 1;
+    int bottomCycleBeginning = topCycleBeginning + slices;
+
+    //Vertical edges.
+    for( int i = 0; i < slices; i++, indiceIndex += 6 )
+    {
+      if( i == slices - 1 )
+      {
+        //End, so loop around.
+        indices[indiceIndex] =     topCycleBeginning + i;
+        indices[indiceIndex + 1] = bottomCycleBeginning + i;
+        indices[indiceIndex + 2] = topCycleBeginning;
+        indices[indiceIndex + 3] = bottomCycleBeginning + i;
+        indices[indiceIndex + 4] = bottomCycleBeginning;
+        indices[indiceIndex + 5] = topCycleBeginning;
+      }
+      else
+      {
+        indices[indiceIndex] =     topCycleBeginning + i;
+        indices[indiceIndex + 1] = bottomCycleBeginning + i;
+        indices[indiceIndex + 2] = topCycleBeginning + 1 + i;
+        indices[indiceIndex + 3] = bottomCycleBeginning + i;
+        indices[indiceIndex + 4] = bottomCycleBeginning + 1 + i;
+        indices[indiceIndex + 5] = topCycleBeginning + 1 + i;
+      }
+    }
+
+    int bottomFaceCycleBeginning = bottomCycleBeginning + slices;
+
+    //Bottom circle.
+    for( int i = 0; i < slices; i++, indiceIndex += 3 )
+    {
+      indices[indiceIndex] = bottomFaceCycleBeginning;
+      indices[indiceIndex + 1] = bottomFaceCycleBeginning + i;
+      if( i == slices - 1 )
+      {
+        //End, so loop around.
+        indices[indiceIndex + 2] = bottomFaceCycleBeginning;
+      }
+      else
+      {
+        indices[indiceIndex + 2] = bottomFaceCycleBeginning + i + 1;
+      }
+    }
+  }
+  else if( !coneTop || !coneBottom )
+  {
+    //Top circle/edges. Start at index of first outer point and go around.
+    for( int i = 1; i <= slices; i++, indiceIndex += 3 )
+    {
+      indices[indiceIndex] = 0;
+      indices[indiceIndex + 1] = i;
+      if( i == slices )
+      {
+        //End, so loop around.
+        indices[indiceIndex + 2] = 1;
+      }
+      else
+      {
+        indices[indiceIndex + 2] = i + 1;
+      }
+    }
+
+    //Bottom circle/edges. Start at index of first outer point and go around.
+    for( int i = 1; i <= slices; i++, indiceIndex += 3 )
+    {
+      indices[indiceIndex] = 2 * slices + 1;
+      indices[indiceIndex + 1] = slices + i;
+      if( i == slices )
+      {
+        //End, so loop around.
+        indices[indiceIndex + 2] = slices + 1;
+      }
+      else
+      {
+        indices[indiceIndex + 2] = slices + i + 1;
+      }
+    }
+  }
+}
+
+void PrimitiveRenderer::ComputeCubeVertices( Vector<Vertex>& vertices, Vector3 dimensions )
+{
+  int numVertices = 4 * 6; //Four per face.
+  int vertexIndex = 0; //Tracks progress through vertices.
+  float scaledX = 0.5 * dimensions.x;
+  float scaledY = 0.5 * dimensions.y;
+  float scaledZ = 0.5 * dimensions.z;
+
+  vertices.Resize( numVertices );
+
+  Vector<Vector3> positions; //Stores vertex positions, which are shared between vertexes at the same position but with a different normal.
+  positions.Resize(8);
+  Vector<Vector3> normals; //Stores normals, which are shared between vertexes of the same face.
+  normals.Resize(6);
+
+  positions[0] = Vector3( -scaledX,  scaledY, -scaledZ );
+  positions[1] = Vector3(  scaledX,  scaledY, -scaledZ );
+  positions[2] = Vector3(  scaledX,  scaledY,  scaledZ );
+  positions[3] = Vector3( -scaledX,  scaledY,  scaledZ );
+  positions[4] = Vector3( -scaledX, -scaledY, -scaledZ );
+  positions[5] = Vector3(  scaledX, -scaledY, -scaledZ );
+  positions[6] = Vector3(  scaledX, -scaledY,  scaledZ );
+  positions[7] = Vector3( -scaledX, -scaledY,  scaledZ );
+
+  normals[0] = Vector3(  0,  1,  0 );
+  normals[1] = Vector3(  0,  0, -1 );
+  normals[2] = Vector3(  1,  0,  0 );
+  normals[3] = Vector3(  0,  0,  1 );
+  normals[4] = Vector3( -1,  0,  0 );
+  normals[5] = Vector3(  0, -1,  0 );
+
+  //Top face, upward normals.
+  for( int i = 0; i < 4; i++, vertexIndex++ )
+  {
+    vertices[vertexIndex].position = positions[i];
+    vertices[vertexIndex].normal = normals[0];
+  }
+
+  //Top face, outward normals.
+  for( int i = 0; i < 4; i++, vertexIndex += 2 )
+  {
+    vertices[vertexIndex].position = positions[i];
+    vertices[vertexIndex].normal = normals[i + 1];
+
+    if( i == 3 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex + 1].position = positions[0];
+    }
+    else
+    {
+      vertices[vertexIndex + 1].position = positions[i + 1];
+    }
+    vertices[vertexIndex + 1].normal = normals[i + 1];
+  }
+
+  //Bottom face, outward normals.
+  for( int i = 0; i < 4; i++, vertexIndex += 2 )
+  {
+    vertices[vertexIndex].position = positions[i + 4];
+    vertices[vertexIndex].normal = normals[i + 1];
+
+    if( i == 3 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex + 1].position = positions[4];
+    }
+    else
+    {
+      vertices[vertexIndex + 1].position = positions[i + 5];
+    }
+    vertices[vertexIndex + 1].normal = normals[i + 1];
+  }
+
+  //Bottom face, downward normals.
+  for( int i = 0; i < 4; i++, vertexIndex++ )
+  {
+    vertices[vertexIndex].position = positions[i + 4];
+    vertices[vertexIndex].normal = normals[5];
+  }
+
+}
+
+void PrimitiveRenderer::FormCubeTriangles( Vector<unsigned short>& indices )
+{
+  int numTriangles = 12;
+  int triangleIndex = 0;  //Track progress through indices.
+
+  indices.Resize( 3 * numTriangles );
+
+  //Top face.
+  indices[triangleIndex] =     0;
+  indices[triangleIndex + 1] = 1;
+  indices[triangleIndex + 2] = 2;
+  indices[triangleIndex + 3] = 2;
+  indices[triangleIndex + 4] = 3;
+  indices[triangleIndex + 5] = 0;
+  triangleIndex += 6;
+
+  int topFaceStart = 4;
+  int bottomFaceStart = 12;
+
+  //Side faces.
+  for( int i = 0; i < 8; i += 2, triangleIndex += 6 )
+  {
+    indices[triangleIndex    ] = i + topFaceStart;
+    indices[triangleIndex + 1] = i + bottomFaceStart + 1;
+    indices[triangleIndex + 2] = i + topFaceStart + 1;
+    indices[triangleIndex + 3] = i + topFaceStart;
+    indices[triangleIndex + 4] = i + bottomFaceStart;
+    indices[triangleIndex + 5] = i + bottomFaceStart + 1;
+  }
+
+  //Bottom face.
+  indices[triangleIndex] =     20;
+  indices[triangleIndex + 1] = 21;
+  indices[triangleIndex + 2] = 22;
+  indices[triangleIndex + 3] = 22;
+  indices[triangleIndex + 4] = 23;
+  indices[triangleIndex + 5] = 20;
+}
+
+void PrimitiveRenderer::ComputeOctahedronVertices( Vector<Vertex>& vertices, Vector3 dimensions, float smoothness )
+{
+  int numVertices = 3 * 8; //Three per face
+  int vertexIndex = 0; //Tracks progress through vertices.
+  float scaledX = 0.5 * dimensions.x;
+  float scaledY = 0.5 * dimensions.y;
+  float scaledZ = 0.5 * dimensions.z;
+
+  vertices.Resize( numVertices );
+
+  Vector<Vector3> positions; //Stores vertex positions, which are shared between vertexes at the same position but with a different normal.
+  positions.Resize(6);
+  Vector<Vector3> normals; //Stores normals, which are shared between vertexes of the same face.
+  normals.Resize(8);
+  Vector<Vector3> outerNormals;  //Holds normals that point outwards at each vertex.
+  outerNormals.Resize( 6 );
+
+  positions[0] = Vector3(  0.0,  scaledY,  0.0 );
+  positions[1] = Vector3( -scaledX,  0.0,  0.0 );
+  positions[2] = Vector3(  0.0,  0.0, -scaledZ );
+  positions[3] = Vector3(  scaledX,  0.0,  0.0 );
+  positions[4] = Vector3(  0.0,  0.0,  scaledZ );
+  positions[5] = Vector3(  0.0, -scaledY,  0.0 );
+
+  normals[0] = Vector3( -1,  1, -1 );
+  normals[1] = Vector3(  1,  1, -1 );
+  normals[2] = Vector3(  1,  1,  1 );
+  normals[3] = Vector3( -1,  1,  1 );
+  normals[4] = Vector3( -1, -1, -1 );
+  normals[5] = Vector3(  1, -1, -1 );
+  normals[6] = Vector3(  1, -1,  1 );
+  normals[7] = Vector3( -1, -1,  1 );
+
+  outerNormals[0] = Vector3(  0,  1,  0 );
+  outerNormals[1] = Vector3( -1,  0,  0 );
+  outerNormals[2] = Vector3(  0,  0, -1 );
+  outerNormals[3] = Vector3(  1,  0,  0 );
+  outerNormals[4] = Vector3(  0,  0,  1 );
+  outerNormals[5] = Vector3(  0, -1,  0 );
+
+  //Loop through top faces.
+  for( int i = 0; i < 4; i++, vertexIndex += 3 )
+  {
+    if( i == 3 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex    ].position = positions[0];
+      vertices[vertexIndex    ].normal = outerNormals[0] * smoothness + normals[i] * (1 - smoothness);
+      vertices[vertexIndex + 1].position = positions[i + 1];
+      vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i] * (1 - smoothness);
+      vertices[vertexIndex + 2].position = positions[1];
+      vertices[vertexIndex + 2].normal = outerNormals[1] * smoothness + normals[i] * (1 - smoothness);
+    }
+    else
+    {
+      vertices[vertexIndex    ].position = positions[0];
+      vertices[vertexIndex    ].normal = outerNormals[0] * smoothness + normals[i] * (1 - smoothness);
+      vertices[vertexIndex + 1].position = positions[i + 1];
+      vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i] * (1 - smoothness);
+      vertices[vertexIndex + 2].position = positions[i + 2];
+      vertices[vertexIndex + 2].normal = outerNormals[i + 2] * smoothness + normals[i] * (1 - smoothness);
+    }
+  }
+
+  //Loop through bottom faces.
+  for( int i = 0; i < 4; i++, vertexIndex += 3 )
+  {
+    if( i == 3 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex    ].position = positions[5];
+      vertices[vertexIndex    ].normal = outerNormals[5] * smoothness + normals[i + 4] * (1 - smoothness);
+      vertices[vertexIndex + 1].position = positions[i + 1];
+      vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i + 4] * (1 - smoothness);
+      vertices[vertexIndex + 2].position = positions[1];
+      vertices[vertexIndex + 2].normal = outerNormals[1] * smoothness + normals[i + 4] * (1 - smoothness);
+    }
+    else
+    {
+      vertices[vertexIndex    ].position = positions[5];
+      vertices[vertexIndex    ].normal = outerNormals[5] * smoothness + normals[i + 4] * (1 - smoothness);
+      vertices[vertexIndex + 1].position = positions[i + 1];
+      vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i + 4] * (1 - smoothness);
+      vertices[vertexIndex + 2].position = positions[i + 2];
+      vertices[vertexIndex + 2].normal = outerNormals[i + 2] * smoothness + normals[i + 4] * (1 - smoothness);
+    }
+  }
+}
+
+void PrimitiveRenderer::FormOctahedronTriangles( Vector<unsigned short>& indices )
+{
+  int numTriangles = 8;
+  int numIndices = numTriangles * 3;
+
+  indices.Resize( numIndices );
+
+  for( unsigned short i = 0; i < numIndices; i++ )
+  {
+    indices[i] = i;
+  }
+}
+
+void PrimitiveRenderer::ComputeBevelledCubeVertices( Vector<Vertex>& vertices, Vector3 dimensions,
+                                                     float bevelPercentage, float bevelSmoothness )
+{
+  int numPositions = 24;
+  int numFaces = 26;
+  int numOuterFaces = 6;
+  int numVertices = 6 * 4 + 12 * 4 + 8 * 3; //Six outer faces, 12 slanting rectangles, 8 slanting triangles.
+  int vertexIndex = 0;  //Track progress through vertices.
+  int normalIndex = 0;  //Track progress through normals, as vertices are calculated per face.
+
+  float minDimension = std::min( std::min( dimensions.x, dimensions.y ), dimensions.z );
+  float bevelScale = 1.0 - bevelPercentage;
+  float bevelAmount = 0.5 * bevelScale * minDimension;
+
+  float outerX = 0.5 * dimensions.x;
+  float outerY = 0.5 * dimensions.y;
+  float outerZ = 0.5 * dimensions.z;
+
+  float bevelX = outerX - ( 0.5 * minDimension - bevelAmount );
+  float bevelY = outerY - ( 0.5 * minDimension - bevelAmount );
+  float bevelZ = outerZ - ( 0.5 * minDimension - bevelAmount );
+
+  Vector<Vector3> positions;  //Holds object points, to be shared between vertexes.
+  positions.Resize( numPositions );
+  Vector<Vector3> normals;  //Holds face normals, to be shared between vertexes.
+  normals.Resize( numFaces );
+  Vector<Vector3> outerNormals;  //Holds normals of the outermost faces specifically.
+  outerNormals.Resize( numOuterFaces );
+  vertices.Resize( numVertices );
+
+  //Topmost face positions.
+  positions[0 ] = Vector3( -bevelX,  outerY, -bevelZ );
+  positions[1 ] = Vector3(  bevelX,  outerY, -bevelZ );
+  positions[2 ] = Vector3(  bevelX,  outerY,  bevelZ );
+  positions[3 ] = Vector3( -bevelX,  outerY,  bevelZ );
+
+  //Second layer positions.
+  positions[4 ] = Vector3( -outerX,  bevelY, -bevelZ );
+  positions[5 ] = Vector3( -bevelX,  bevelY, -outerZ );
+  positions[6 ] = Vector3(  bevelX,  bevelY, -outerZ );
+  positions[7 ] = Vector3(  outerX,  bevelY, -bevelZ );
+  positions[8 ] = Vector3(  outerX,  bevelY,  bevelZ );
+  positions[9 ] = Vector3(  bevelX,  bevelY,  outerZ );
+  positions[10] = Vector3( -bevelX,  bevelY,  outerZ );
+  positions[11] = Vector3( -outerX,  bevelY,  bevelZ );
+
+  //Third layer positions.
+  positions[12] = Vector3( -outerX, -bevelY, -bevelZ );
+  positions[13] = Vector3( -bevelX, -bevelY, -outerZ );
+  positions[14] = Vector3(  bevelX, -bevelY, -outerZ );
+  positions[15] = Vector3(  outerX, -bevelY, -bevelZ );
+  positions[16] = Vector3(  outerX, -bevelY,  bevelZ );
+  positions[17] = Vector3(  bevelX, -bevelY,  outerZ );
+  positions[18] = Vector3( -bevelX, -bevelY,  outerZ );
+  positions[19] = Vector3( -outerX, -bevelY,  bevelZ );
+
+  //Bottom-most face positions.
+  positions[20] = Vector3( -bevelX, -outerY, -bevelZ );
+  positions[21] = Vector3(  bevelX, -outerY, -bevelZ );
+  positions[22] = Vector3(  bevelX, -outerY,  bevelZ );
+  positions[23] = Vector3( -bevelX, -outerY,  bevelZ );
+
+  //Top face normal.
+  normals[0 ] = Vector3(  0,  1,  0 );
+
+  //Top slope normals.
+  normals[1 ] = Vector3( -1,  1, -1 );
+  normals[2 ] = Vector3(  0,  1, -1 );
+  normals[3 ] = Vector3(  1,  1, -1 );
+  normals[4 ] = Vector3(  1,  1,  0 );
+  normals[5 ] = Vector3(  1,  1,  1 );
+  normals[6 ] = Vector3(  0,  1,  1 );
+  normals[7 ] = Vector3( -1,  1,  1 );
+  normals[8 ] = Vector3( -1,  1,  0 );
+
+  //Side normals.
+  normals[9 ] = Vector3( -1,  0, -1 );
+  normals[10] = Vector3(  0,  0, -1 );
+  normals[11] = Vector3(  1,  0, -1 );
+  normals[12] = Vector3(  1,  0,  0 );
+  normals[13] = Vector3(  1,  0,  1 );
+  normals[14] = Vector3(  0,  0,  1 );
+  normals[15] = Vector3( -1,  0,  1 );
+  normals[16] = Vector3( -1,  0,  0 );
+
+  //Bottom slope normals.
+  normals[17] = Vector3( -1, -1, -1 );
+  normals[18] = Vector3(  0, -1, -1 );
+  normals[19] = Vector3(  1, -1, -1 );
+  normals[20] = Vector3(  1, -1,  0 );
+  normals[21] = Vector3(  1, -1,  1 );
+  normals[22] = Vector3(  0, -1,  1 );
+  normals[23] = Vector3( -1, -1,  1 );
+  normals[24] = Vector3( -1, -1,  0 );
+
+  //Bottom face normal.
+  normals[25] = Vector3(  0, -1,  0 );
+
+  //Top, back, right, front, left and bottom faces, respectively.
+  outerNormals[0] = Vector3(  0,  1,  0 );
+  outerNormals[1] = Vector3(  0,  0, -1 );
+  outerNormals[2] = Vector3(  1,  0,  0 );
+  outerNormals[3] = Vector3(  0,  0,  1 );
+  outerNormals[4] = Vector3( -1,  0,  0 );
+  outerNormals[5] = Vector3(  0, -1,  0 );
+
+  //Topmost face vertices.
+  for( int i = 0; i < 4; i++, vertexIndex++ )
+  {
+    vertices[vertexIndex].position = positions[i];
+    vertices[vertexIndex].normal = normals[normalIndex];
+  }
+
+  normalIndex++;
+
+  //Top slope vertices.
+  for( int i = 0; i < 4; i++, vertexIndex += 7, normalIndex += 2 )
+  {
+    //Triangle part
+    vertices[vertexIndex    ].position = positions[i];
+    vertices[vertexIndex    ].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+    vertices[vertexIndex + 1].position = positions[2 * i + 4];
+    vertices[vertexIndex + 1].normal = outerNormals[( i == 0 ) ? 4 : i] * bevelSmoothness  + normals[normalIndex] * (1 - bevelSmoothness);
+    vertices[vertexIndex + 2].position = positions[2 * i + 5];
+    vertices[vertexIndex + 2].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+
+    //Rectangle part
+    if( i == 3 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex + 3].position = positions[i];
+      vertices[vertexIndex + 3].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 4].position = positions[0];
+      vertices[vertexIndex + 4].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 5].position = positions[2 * i + 5];
+      vertices[vertexIndex + 5].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 6].position = positions[4];
+      vertices[vertexIndex + 6].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+    }
+    else
+    {
+      vertices[vertexIndex + 3].position = positions[i];
+      vertices[vertexIndex + 3].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 4].position = positions[i + 1];
+      vertices[vertexIndex + 4].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 5].position = positions[2 * i + 5];
+      vertices[vertexIndex + 5].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 6].position = positions[2 * i + 6];
+      vertices[vertexIndex + 6].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+    }
+  }
+
+  int secondCycleBeginning = 4;
+  int thirdCycleBeginning = secondCycleBeginning + 8;
+  int bottomCycleBeginning = thirdCycleBeginning + 8;
+
+  //Side vertices.
+  for( int i = 0; i < 8; i++, vertexIndex += 4, normalIndex++ )
+  {
+    if( i == 7 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex    ].position = positions[secondCycleBeginning + i];
+      vertices[vertexIndex    ].normal = normals[normalIndex];
+      vertices[vertexIndex + 1].position = positions[secondCycleBeginning];
+      vertices[vertexIndex + 1].normal = normals[normalIndex];
+      vertices[vertexIndex + 2].position = positions[thirdCycleBeginning + i];
+      vertices[vertexIndex + 2].normal = normals[normalIndex];
+      vertices[vertexIndex + 3].position = positions[thirdCycleBeginning];
+      vertices[vertexIndex + 3].normal = normals[normalIndex];
+    }
+    else if( (i % 2) == 0 )
+    {
+      //'even' faces are corner ones, and need smoothing.
+      vertices[vertexIndex    ].position = positions[secondCycleBeginning + i];
+      vertices[vertexIndex    ].normal = outerNormals[( i == 0 ) ? 4 : i / 2] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 1].position = positions[secondCycleBeginning + i + 1];
+      vertices[vertexIndex + 1].normal = outerNormals[i / 2 + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 2].position = positions[thirdCycleBeginning + i];
+      vertices[vertexIndex + 2].normal = outerNormals[( i == 0 ) ? 4 : i / 2] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + i + 1];
+      vertices[vertexIndex + 3].normal = outerNormals[i / 2 + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+    }
+    else
+    {
+      //'odd' faces are outer ones, and so don't need smoothing.
+      vertices[vertexIndex    ].position = positions[secondCycleBeginning + i];
+      vertices[vertexIndex    ].normal = normals[normalIndex];
+      vertices[vertexIndex + 1].position = positions[secondCycleBeginning + i + 1];
+      vertices[vertexIndex + 1].normal = normals[normalIndex];
+      vertices[vertexIndex + 2].position = positions[thirdCycleBeginning + i];
+      vertices[vertexIndex + 2].normal = normals[normalIndex];
+      vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + i + 1];
+      vertices[vertexIndex + 3].normal = normals[normalIndex];
+    }
+  }
+
+  //Bottom slope vertices.
+  for( int i = 0; i < 4; i++, vertexIndex += 7, normalIndex += 2 )
+  {
+    //Triangle part
+    vertices[vertexIndex    ].position = positions[thirdCycleBeginning + 2 * i];
+    vertices[vertexIndex    ].normal = outerNormals[( i == 0 ) ? 4 : i] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+    vertices[vertexIndex + 1].position = positions[thirdCycleBeginning + 2 * i + 1];
+    vertices[vertexIndex + 1].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+    vertices[vertexIndex + 2].position = positions[bottomCycleBeginning + i];
+    vertices[vertexIndex + 2].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness);
+
+    //Rectangle part
+    if( i == 3 )
+    {
+      //End, so loop around.
+      vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + 2 * i + 1];
+      vertices[vertexIndex + 3].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 4].position = positions[thirdCycleBeginning];
+      vertices[vertexIndex + 4].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 5].position = positions[bottomCycleBeginning + i];
+      vertices[vertexIndex + 5].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 6].position = positions[bottomCycleBeginning];
+      vertices[vertexIndex + 6].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+    }
+    else
+    {
+      vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + 2 * i + 1];
+      vertices[vertexIndex + 3].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 4].position = positions[thirdCycleBeginning + 2 * i + 2];
+      vertices[vertexIndex + 4].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 5].position = positions[bottomCycleBeginning + i];
+      vertices[vertexIndex + 5].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+      vertices[vertexIndex + 6].position = positions[bottomCycleBeginning + i + 1];
+      vertices[vertexIndex + 6].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness);
+    }
+  }
+
+  //Bottom-most face vertices.
+  for( int i = 0; i < 4; i++, vertexIndex++ )
+  {
+    vertices[vertexIndex].position = positions[ bottomCycleBeginning + i];
+    vertices[vertexIndex].normal = normals[normalIndex];
+  }
+
+  normalIndex++;
+}
+
+void PrimitiveRenderer::FormBevelledCubeTriangles( Vector<unsigned short>& indices )
+{
+  int numTriangles = 44; //(Going from top to bottom, that's 2 + 12 + 16 + 12 + 2)
+  int indiceIndex = 0;  //Track progress through indices.
+  int vertexIndex = 0;  //Track progress through vertices as they're processed.
+
+  indices.Resize( 3 * numTriangles );
+
+  //Top face.
+  indices[indiceIndex    ] = vertexIndex;
+  indices[indiceIndex + 1] = vertexIndex + 1;
+  indices[indiceIndex + 2] = vertexIndex + 2;
+  indices[indiceIndex + 3] = vertexIndex + 0;
+  indices[indiceIndex + 4] = vertexIndex + 2;
+  indices[indiceIndex + 5] = vertexIndex + 3;
+  indiceIndex += 6;
+  vertexIndex += 4;
+
+  //Top slopes.
+  for( int i = 0; i < 4; i++, indiceIndex += 9, vertexIndex += 7 )
+  {
+    //Triangle part.
+    indices[indiceIndex    ] = vertexIndex;
+    indices[indiceIndex + 1] = vertexIndex + 1;
+    indices[indiceIndex + 2] = vertexIndex + 2;
+
+    //Rectangle part.
+    indices[indiceIndex + 3] = vertexIndex + 3;
+    indices[indiceIndex + 4] = vertexIndex + 4;
+    indices[indiceIndex + 5] = vertexIndex + 5;
+    indices[indiceIndex + 6] = vertexIndex + 4;
+    indices[indiceIndex + 7] = vertexIndex + 5;
+    indices[indiceIndex + 8] = vertexIndex + 6;
+  }
+
+  //Side faces.
+  for( int i = 0; i < 8; i++, indiceIndex += 6, vertexIndex += 4 )
+  {
+    indices[indiceIndex    ] = vertexIndex;
+    indices[indiceIndex + 1] = vertexIndex + 1;
+    indices[indiceIndex + 2] = vertexIndex + 2;
+    indices[indiceIndex + 3] = vertexIndex + 1;
+    indices[indiceIndex + 4] = vertexIndex + 2;
+    indices[indiceIndex + 5] = vertexIndex + 3;
+  }
+
+  //Bottom slopes.
+  for( int i = 0; i < 4; i++, indiceIndex += 9, vertexIndex += 7 )
+  {
+    //Triangle part.
+    indices[indiceIndex    ] = vertexIndex;
+    indices[indiceIndex + 1] = vertexIndex + 1;
+    indices[indiceIndex + 2] = vertexIndex + 2;
+
+    //Rectangle part.
+    indices[indiceIndex + 3] = vertexIndex + 3;
+    indices[indiceIndex + 4] = vertexIndex + 4;
+    indices[indiceIndex + 5] = vertexIndex + 5;
+    indices[indiceIndex + 6] = vertexIndex + 4;
+    indices[indiceIndex + 7] = vertexIndex + 5;
+    indices[indiceIndex + 8] = vertexIndex + 6;
+  }
+
+  //Bottom face.
+  indices[indiceIndex    ] = vertexIndex;
+  indices[indiceIndex + 1] = vertexIndex + 1;
+  indices[indiceIndex + 2] = vertexIndex + 2;
+  indices[indiceIndex + 3] = vertexIndex + 0;
+  indices[indiceIndex + 4] = vertexIndex + 2;
+  indices[indiceIndex + 5] = vertexIndex + 3;
+  indiceIndex += 6;
+  vertexIndex += 4;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h b/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h
new file mode 100644 (file)
index 0000000..555f478
--- /dev/null
@@ -0,0 +1,352 @@
+#ifndef DALI_TOOLKIT_INTERNAL_PRIMITIVE_RENDERER_H
+#define DALI_TOOLKIT_INTERNAL_PRIMITIVE_RENDERER_H
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * The geometry creation logic was based off similar methods provided by freeGLUT.
+ * Original copyright and licence information:
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Creation date: Fri Dec 3 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * The renderer which renders a simple 3D shape to the control's quad
+ *
+ * The following properties are required to create a PrimitiveRender
+ *
+ * | %Property Name  | Type        |
+ * |-----------------|-------------|
+ * | shape           | STRING      |
+ *
+ * In addition, the following properties can be (optionally) supplied to modify the shape's parameters
+ *
+ * | %Property Name    | Type        | Shapes Affected                          |
+ * |-------------------|-------------|------------------------------------------|
+ * | shapeColor        | VECTOR4     | all                                      |
+ * | slices            | INTEGER     | sphere, cone, conical frustrum, cylinder |
+ * | stacks            | INTEGER     | sphere                                   |
+ * | scaleTopRadius    | FLOAT       | conical frustrum                         |
+ * | scaleBottomRadius | FLOAT       | cone, conical frustrum                   |
+ * | scaleHeight       | FLOAT       | cone, conical frustrum, cylinder         |
+ * | scaleRadius       | FLOAT       | cylinder                                 |
+ * | scaleDimensions   | VECTOR3     | cube, octahedron, bevelled cube          |
+ * | bevelPercentage   | FLOAT       | bevelled cube                            |
+ * | bevelSmoothness   | FLOAT       | bevelled cube                            |
+ *
+ * Note: slices and stacks both have an upper limit of 255.
+ *
+ * Finally, the following can be used to affect the renderer's shader
+ *
+ * | %Property Name  | Type        | Representing                            |
+ * |-----------------|-------------|-----------------------------------------|
+ * | lightPosition   | VECTOR3     | The position (on stage) of the light    |
+ */
+class PrimitiveRenderer: public ControlRenderer
+{
+public:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object
+   */
+  PrimitiveRenderer( RendererFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~PrimitiveRenderer();
+
+public:  // from ControlRenderer
+
+  /**
+   * @copydoc ControlRenderer::SetSize
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * @copydoc ControlRenderer::SetClipRect
+   */
+  virtual void SetClipRect( const Rect<int>& clipRect );
+
+  /**
+   * @copydoc ControlRenderer::SetOffset
+   */
+  virtual void SetOffset( const Vector2& offset );
+
+  /**
+   * @copydoc ControlRenderer::CreatePropertyMap
+   */
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
+protected:
+
+  /**
+   * @copydoc ControlRenderer::DoInitialize
+   */
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+
+  /**
+   * @copydoc ControlRenderer::DoSetOnStage
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+private:
+
+  enum PrimitiveType
+  {
+    SPHERE,
+    CONE,
+    CONICAL_FRUSTRUM,
+    CYLINDER,
+    CUBE,
+    OCTAHEDRON,
+    BEVELLED_CUBE
+  };
+
+  //Simple struct to store the position and normal of a single vertex.
+  struct Vertex
+  {
+    Vertex()
+    {}
+
+    Vertex( const Vector3& position, const Vector3& normal, const Vector2& textureCoord )
+    : position( position ), normal( normal )
+    {}
+
+    Vector3 position;
+    Vector3 normal;
+  };
+
+  /**
+   * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   */
+  void InitializeRenderer();
+
+  /**
+     * @brief Create a shader for the object to use.
+     */
+  void CreateShader();
+
+  /**
+   * @brief Update shader related info, uniforms, etc. for the new shader.
+   */
+  void UpdateShaderUniforms();
+
+  /**
+   * @brief Create the geometry of the given primitive type.
+   */
+  void CreateGeometry();
+
+  /**
+   * @brief Compute the vertices and the triangles for a sphere.
+   * @param[in, out] vertices The vector of vertices.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   * @param[in] slices The number of slices as you go around the sphere. Affects the smoothness of the surface.
+   * @param[in] stacks The number of stacks as you go down the sphere. Affects the smoothness of the surface.
+   */
+  void CreateSphere( Vector<Vertex>& vertices, Vector<unsigned short>& indices, int slices, int stacks );
+
+  /**
+   * @brief Compute the vertices and the triangles for a conic shape.
+   * @param[in, out] vertices The vector of vertices.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   * @param[in] scaleTopRadius The scale of the radius of the top circle, compared to the other dimensions.
+   * @param[in] scaleBottomRadius The scale of the radius of the bottom circle, compared to the other dimensions.
+   * @param[in] scaleHeight The scale of the height of the object, compared to the other dimensions.
+   * @param[in] slices The number of slices as you go around the conic shape. Affects the smoothness of the surface.
+   */
+  void CreateConic( Vector<Vertex>& vertices, Vector<unsigned short>& indices, float scaleTopRadius,
+                           float scaleBottomRadius, float scaleHeight, int slices );
+
+  /**
+   * @brief Compute the vertices and the triangles for a bevelled cube.
+   * @param[in, out] vertices The vector of vertices.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   * @Param[in] dimensions The dimensions of the object. Scales in the same fashion as a 9-patch image.
+   * @param[in] bevelPercentage The ratio of the outer face widths to the cube's width. Between 0.0 and 1.0.
+   * @param[in] bevelSmoothness The smoothness of the bevelled edges. Between 0.0 and 1.0.
+   */
+  void CreateBevelledCube( Vector<Vertex>& vertices, Vector<unsigned short>& indices, Vector3 dimensions,
+                           float bevelPercentage, float bevelSmoothness );
+
+  /**
+   * @brief Computes look-up tables for sin and cos, over angle divisions of (2 * Pi) / divisions
+   * @param[in, out] sinTable The table of sin values.
+   * @param[in, out] cosTable The table of cos values.
+   * @param[in] divisions Determines the angle coverage of the table. E.g divisions of '4' will have the sin values 0 = sin(0), 1 = sin(Pi/2), 2 = sin(Pi), 3 = sin(3Pi/2)
+   * @Param[in] halfCircle If true, go from 0 to Pi instead of 0 to 2Pi.
+   */
+  void ComputeCircleTables( Vector<float>& sinTable, Vector<float>& cosTable, int divisions, bool halfCircle );
+
+  /**
+   * @brief Compute the vertices for a sphere.
+   * @param[in, out] vertices The vector of vertices.
+   * @param[in] slices The number of slices as you go around the sphere. Affects the smoothness of the surface.
+   * @param[in] stacks The number of stacks as you go down the sphere. Affects the smoothness of the surface.
+   */
+  void ComputeSphereVertices( Vector<Vertex>& vertices, int slices, int stacks );
+
+  /**
+   * @brief Compute the triangles for a sphere.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   * @param[in] slices The number of slices as you go around the sphere. Affects the smoothness of the surface.
+   * @param[in] stacks The number of stacks as you go down the sphere. Affects the smoothness of the surface.
+   */
+  void FormSphereTriangles( Vector<unsigned short>& indices, int slices, int stacks );
+
+  /**
+   * @brief Compute the vertices for a conical.
+   * @param[in, out] vertices The vector of vertices.
+   * @param[in] scaleTopRadius The scale of the radius of the top circle, compared to the other dimensions.
+   * @param[in] scaleBottomRadius The scale of the radius of the bottom circle, compared to the other dimensions.
+   * @param[in] scaleHeight The scale of the height of the object, compared to the other dimensions.
+   * @param[in] slices The number of slices as you go around the conical. Affects the smoothness of the surface.
+   */
+  void ComputeConicVertices( Vector<Vertex>& vertices, float scaleTopRadius, float scaleBottomRadius,
+                                    float scaleHeight, int slices );
+
+  /**
+   * @brief Compute the triangles for a conic.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   * @param[in] coneTop True if the top circle has a radius of zero, i.e. the object is a complete cone.
+   * @param[in] coneBottom True if the bottom circle has a radius of zero, i.e. the object is an inverted complete cone.
+   * @param[in] slices The number of slices as you go around the conic. Affects the smoothness of the surface.
+   */
+  void FormConicTriangles( Vector<unsigned short>& indices, float scaleTopRadius, float scaleBottomRadius,
+                                  int slices );
+
+  /**
+   * @brief Compute the vertices for a cube.
+   * @param[in, out] vertices The vector of vertices.
+   * @Param[in] dimensions The dimensions of the object.
+   */
+  void ComputeCubeVertices( Vector<Vertex>& vertices, Vector3 dimensions );
+
+  /**
+   * @brief Compute the triangles for a cube.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   */
+  void FormCubeTriangles( Vector<unsigned short>& indices );
+
+  /**
+   * @brief Compute the vertices for an octahedron (maximumly bevelled cube).
+   * @param[in, out] vertices The vector of vertices.
+   * @Param[in] dimensions The dimensions of the object.
+   * @Param[in] smoothness Defines how rounded the edges appear under lighting. Between 0.0 and 1.0.
+   */
+  void ComputeOctahedronVertices( Vector<Vertex>& vertices, Vector3 dimensions, float smoothness );
+
+  /**
+   * @brief Compute the triangles for an octahedron.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   */
+  void FormOctahedronTriangles( Vector<unsigned short>& indices );
+
+  /**
+   * @brief Compute the vertices for a bevelled cube.
+   * @param[in, out] vertices The vector of vertices.
+   * @Param[in] dimensions The dimensions of the object. Scales in the same fashion as a 9-patch image.
+   * @param[in] bevelPercentage The ratio of the outer face widths to the cube's width. Between 0.0 and 1.0.
+   * @param[in] bevelSmoothness The smoothness of the bevelled edges. Between 0.0 and 1.0.
+   */
+  void ComputeBevelledCubeVertices( Vector<Vertex>& vertices, Vector3 dimensions, float bevelPercentage,
+                                    float bevelSmoothness );
+
+  /**
+   * @brief Compute the triangles for a bevelled cube.
+   * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices.
+   */
+  void FormBevelledCubeTriangles( Vector<unsigned short>& indices );
+
+private:
+
+  // Undefined
+  PrimitiveRenderer( const PrimitiveRenderer& PrimitiveRenderer );
+
+  // Undefined
+  PrimitiveRenderer& operator=( const PrimitiveRenderer& PrimitiveRenderer );
+
+private:
+  Shader mShader;
+  Geometry mGeometry;
+
+  std::string mShape;            //Shape to render, as string.
+  Vector4 mColor;                //Color of shape.
+  Vector3 mObjectDimensions;     //Dimensions of shape, scaled to be between 0.0 and 1.0.
+
+  Vector3 mSceneCenter;
+  Vector3 mSceneSize;
+
+  //Shader properties.
+  Vector3 mLightPosition;
+
+  //Shape properties.
+  Vector3 mScaleDimensions;      ///< Scale of dimensions of bevelled cube and sub-shapes.
+  float   mScaleTopRadius;       ///< Scale of radius of top circle, to use when creating certain objects.
+  float   mScaleBottomRadius;    ///< Scale of radius of bottom circle, to use when creating certain objects.
+  float   mScaleHeight;          ///< Scale of height, to use when creating certain objects.
+  float   mScaleRadius;          ///< Scale of radius, to use when creating certain objects.
+  float   mBevelPercentage;      ///< Used to determine bevel amount when creating certain objects.
+  float   mBevelSmoothness;      ///< Used to determine the smoothness of bevelled edges.
+  int     mSlices;               ///< Number of slices to use when creating certain objects.
+  int     mStacks;               ///< Number of stacks to use when creating certain objects.
+
+  PrimitiveType mPrimitiveType;  //Shape to render, as enum.
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_INTERNAL_PRIMITIVE_RENDERER_H */
index 6cb0aa0..e1c75a2 100644 (file)
@@ -33,6 +33,7 @@
 #include <dali-toolkit/internal/controls/renderers/image/image-renderer.h>
 #include <dali-toolkit/internal/controls/renderers/svg/svg-renderer.h>
 #include <dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.h>
+#include <dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h>
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
 #include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
 #include <dali-toolkit/internal/controls/renderers/image-atlas-manager.h>
@@ -103,6 +104,10 @@ RendererFactory::RendererType RendererFactory::GetRendererType( const Property::
     {
       rendererType = MESH;
     }
+    else if( typeValue == PRIMITIVE_RENDERER )
+    {
+      rendererType = PRIMITIVE;
+    }
   }
 
   // check the url if exist, to decide the renderer type
@@ -187,6 +192,11 @@ Toolkit::ControlRenderer RendererFactory::CreateControlRenderer( const Property:
       rendererPtr = new MeshRenderer( *( mFactoryCache.Get() ) );
       break;
     }
+    case PRIMITIVE:
+    {
+      rendererPtr = new PrimitiveRenderer( *( mFactoryCache.Get() ) );
+      break;
+    }
     case UNDEFINED:
     default:
     {
index 41fd6a7..a37d413 100644 (file)
@@ -28,15 +28,17 @@ namespace Internal
 {
 
 const char * const RENDERER_TYPE("rendererType");
-const char * const COLOR_RENDERER("color");
-const char * const BORDER_RENDERER("border");
-const char * const GRADIENT_RENDERER("gradient");
-const char * const IMAGE_RENDERER("image");
-const char * const MESH_RENDERER("mesh");
+const char * const COLOR_RENDERER("COLOR");
+const char * const BORDER_RENDERER("BORDER");
+const char * const GRADIENT_RENDERER("GRADIENT");
+const char * const IMAGE_RENDERER("IMAGE");
+const char * const MESH_RENDERER("MESH");
+const char * const PRIMITIVE_RENDERER( "PRIMITIVE" );
+const char * const DEBUG_RENDERER("DEBUG");
 
 const char * const IMAGE_URL_NAME("url");
 const char * const ATLAS_RECT_UNIFORM_NAME ( "uAtlasRect" );
-const char * const COLOR( "color" );
+const char * const LIGHT_POSITION_UNIFORM_NAME( "lightPosition" );
 
 //Mesh properties
 const char * const OBJECT_URL( "objectUrl" );
@@ -44,6 +46,20 @@ const char * const MATERIAL_URL( "materialUrl" );
 const char * const TEXTURES_PATH( "texturesPath" );
 const char * const SHADER_TYPE( "shaderType" );
 const char * const USE_MIPMAPPING( "useMipmapping" );
+const char * const USE_SOFT_NORMALS( "useSoftNormals" );
+
+//Primitive shape properties
+const char * const PRIMITIVE_SHAPE( "shape" );
+const char * const SHAPE_COLOR( "shapeColor" );
+const char * const SLICES( "slices" );
+const char * const STACKS( "stacks" );
+const char * const SCALE_TOP_RADIUS( "scaleTopRadius" );
+const char * const SCALE_BOTTOM_RADIUS( "scaleBottomRadius" );
+const char * const SCALE_HEIGHT( "scaleHeight" );
+const char * const SCALE_RADIUS( "scaleRadius" );
+const char * const SCALE_DIMENSIONS( "scaleDimensions" );
+const char * const BEVEL_PERCENTAGE( "bevelPercentage" );
+const char * const BEVEL_SMOOTHNESS( "bevelSmoothness" );
 
 } // namespace Internal
 
index 0bb7d45..e07ee97 100644 (file)
@@ -33,10 +33,12 @@ extern const char * const BORDER_RENDERER;
 extern const char * const GRADIENT_RENDERER;
 extern const char * const IMAGE_RENDERER;
 extern const char * const MESH_RENDERER;
+extern const char * const PRIMITIVE_RENDERER;
+extern const char * const DEBUG_RENDERER;
 
 extern const char * const IMAGE_URL_NAME;
 extern const char * const ATLAS_RECT_UNIFORM_NAME;
-extern const char * const COLOR;
+extern const char * const LIGHT_POSITION_UNIFORM_NAME;
 
 //Mesh properties
 extern const char * const OBJECT_URL;
@@ -44,6 +46,20 @@ extern const char * const MATERIAL_URL;
 extern const char * const TEXTURES_PATH;
 extern const char * const SHADER_TYPE;
 extern const char * const USE_MIPMAPPING;
+extern const char * const USE_SOFT_NORMALS;
+
+//Primitive shape properties
+extern const char * const PRIMITIVE_SHAPE;
+extern const char * const SHAPE_COLOR;
+extern const char * const SLICES;
+extern const char * const STACKS;
+extern const char * const SCALE_TOP_RADIUS;
+extern const char * const SCALE_BOTTOM_RADIUS;
+extern const char * const SCALE_HEIGHT;
+extern const char * const SCALE_RADIUS;
+extern const char * const SCALE_DIMENSIONS;
+extern const char * const BEVEL_PERCENTAGE;
+extern const char * const BEVEL_SMOOTHNESS;
 
 } // namespace Internal
 
index ceb554c..5481d21 100644 (file)
@@ -40,7 +40,7 @@ namespace Internal
  *
  * | %Property Name           | Type             |
  * |--------------------------|------------------|
- * | imageUrl                 | STRING           |
+ * | url                      | STRING           |
  *
  */
 class SvgRenderer: public ControlRenderer
index a33845e..b8730a6 100644 (file)
@@ -28,6 +28,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/controls/renderers/svg/svg-rasterize-thread.cpp \
    $(toolkit_src_dir)/controls/renderers/svg/svg-renderer.cpp \
    $(toolkit_src_dir)/controls/renderers/mesh/mesh-renderer.cpp \
+   $(toolkit_src_dir)/controls/renderers/primitive/primitive-renderer.cpp \
    $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
    $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
    $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
index aeedd0f..d980708 100644 (file)
@@ -123,7 +123,7 @@ void EmbossFilter::Enable()
 
   customShader[ "fragmentShader" ] = COMPOSITE_FRAGMENT_SOURCE;
   rendererMap[ "shader"] = customShader;
-  rendererMap[ "rendererType"] = "image";
+  rendererMap[ "rendererType"] = "IMAGE";
 
   mRootActor.Add( mActorForComposite );
 
index 10c1e22..1fbca0d 100644 (file)
@@ -33,6 +33,97 @@ namespace
 
 const Dali::Toolkit::Text::CharacterDirection LTR = false; ///< Left To Right direction.
 
+struct FindWordData
+{
+  FindWordData( const Dali::Toolkit::Text::Character* const textBuffer,
+                Dali::Toolkit::Text::Length totalNumberOfCharacters,
+                Dali::Toolkit::Text::CharacterIndex hitCharacter,
+                bool isWhiteSpace,
+                bool isNewParagraph )
+  : textBuffer( textBuffer ),
+    totalNumberOfCharacters( totalNumberOfCharacters ),
+    hitCharacter( hitCharacter ),
+    foundIndex( 0u ),
+    isWhiteSpace( isWhiteSpace ),
+    isNewParagraph( isNewParagraph )
+  {}
+
+  ~FindWordData()
+  {}
+
+  const Dali::Toolkit::Text::Character* const textBuffer;
+  Dali::Toolkit::Text::Length                 totalNumberOfCharacters;
+  Dali::Toolkit::Text::CharacterIndex         hitCharacter;
+  Dali::Toolkit::Text::CharacterIndex         foundIndex;
+  bool                                        isWhiteSpace   : 1u;
+  bool                                        isNewParagraph : 1u;
+};
+
+bool IsWhiteSpaceOrNewParagraph( Dali::Toolkit::Text::Character character,
+                                 bool isHitWhiteSpace,
+                                 bool isHitWhiteSpaceOrNewParagraph )
+{
+  bool isWhiteSpaceOrNewParagraph = false;
+  if( isHitWhiteSpaceOrNewParagraph )
+  {
+    if( isHitWhiteSpace )
+    {
+      // Whether the current character is a white space. Note a new paragraph character is a white space as well but here is not wanted.
+      isWhiteSpaceOrNewParagraph = Dali::TextAbstraction::IsWhiteSpace( character ) && !Dali::TextAbstraction::IsNewParagraph( character );
+    }
+    else
+    {
+      // Whether the current character is a new paragraph character.
+      isWhiteSpaceOrNewParagraph = Dali::TextAbstraction::IsNewParagraph( character );
+    }
+  }
+  else
+  {
+    // Whether the current character is a white space or a new paragraph character (note the new paragraph character is a white space as well).
+    isWhiteSpaceOrNewParagraph = Dali::TextAbstraction::IsWhiteSpace( character );
+  }
+
+  return isWhiteSpaceOrNewParagraph;
+}
+
+void FindStartOfWord( FindWordData& data )
+{
+  const bool isHitWhiteSpaceOrNewParagraph = data.isWhiteSpace || data.isNewParagraph;
+
+  for( data.foundIndex = data.hitCharacter; data.foundIndex > 0; --data.foundIndex )
+  {
+    const Dali::Toolkit::Text::Character character = *( data.textBuffer + data.foundIndex - 1u );
+
+    const bool isWhiteSpaceOrNewParagraph = IsWhiteSpaceOrNewParagraph( character,
+                                                                        data.isWhiteSpace,
+                                                                        isHitWhiteSpaceOrNewParagraph );
+
+    if( isHitWhiteSpaceOrNewParagraph != isWhiteSpaceOrNewParagraph )
+    {
+      break;
+    }
+  }
+}
+
+void FindEndOfWord( FindWordData& data )
+{
+  const bool isHitWhiteSpaceOrNewParagraph = data.isWhiteSpace || data.isNewParagraph;
+
+  for( data.foundIndex = data.hitCharacter + 1u; data.foundIndex < data.totalNumberOfCharacters; ++data.foundIndex )
+  {
+    const Dali::Toolkit::Text::Character character = *( data.textBuffer + data.foundIndex );
+
+    const bool isWhiteSpaceOrNewParagraph = IsWhiteSpaceOrNewParagraph( character,
+                                                                        data.isWhiteSpace,
+                                                                        isHitWhiteSpaceOrNewParagraph );
+
+    if( isHitWhiteSpaceOrNewParagraph != isWhiteSpaceOrNewParagraph )
+    {
+      break;
+    }
+  }
+}
+
 } //namespace
 
 namespace Dali
@@ -107,10 +198,10 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
 
   CharacterIndex logicalIndex = 0u;
 
-  const Length numberOfGlyphs = visualModel->mGlyphs.Count();
-  const Length numberOfLines  = visualModel->mLines.Count();
-  if( ( 0 == numberOfGlyphs ) ||
-      ( 0 == numberOfLines ) )
+  const Length totalNumberOfGlyphs = visualModel->mGlyphs.Count();
+  const Length totalNumberOfLines  = visualModel->mLines.Count();
+  if( ( 0 == totalNumberOfGlyphs ) ||
+      ( 0 == totalNumberOfLines ) )
   {
     return logicalIndex;
   }
@@ -184,14 +275,43 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
       // Get the position of the first glyph.
       const Vector2& position = *( positionsBuffer + firstLogicalGlyphIndex );
 
-      // Whether the glyph can be split, like Latin ligatures fi, ff or Arabic .
-      const Length numberOfCharacters = *( charactersPerGlyphBuffer + firstLogicalGlyphIndex );
+      // Whether the glyph can be split, like Latin ligatures fi, ff or Arabic (ل + ا).
+      Length numberOfCharacters = *( charactersPerGlyphBuffer + firstLogicalGlyphIndex );
       if( direction != LTR )
       {
         // As characters are being traversed in visual order,
         // for right to left ligatures, the character which contains the
         // number of glyphs in the table is found first.
         // Jump the number of characters to the next glyph is needed.
+
+        if( 0u == numberOfCharacters )
+        {
+          // TODO: This is a workaround to fix an issue with complex characters in the arabic
+          // script like i.e. رّ or الأَبْجَدِيَّة العَرَبِيَّة
+          // There are characters that are not shaped in one glyph but in combination with
+          // the next one generates two of them.
+          // The visual to logical conversion table have characters in different order than
+          // expected even if all of them are arabic.
+
+          // The workaround doesn't fix the issue completely but it prevents the application
+          // to hang in an infinite loop.
+
+          // Find the number of characters.
+          for( GlyphIndex index = firstLogicalGlyphIndex + 1u;
+               ( 0u == numberOfCharacters ) && ( index < totalNumberOfGlyphs ) ;
+               ++index )
+          {
+            numberOfCharacters = *( charactersPerGlyphBuffer + index );
+          }
+
+          if( 2u > numberOfCharacters )
+          {
+            continue;
+          }
+
+          --numberOfCharacters;
+        }
+
         visualIndex += numberOfCharacters - 1u;
       }
 
@@ -264,7 +384,7 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
     {
       // The paragraph direction is right to left.
 
-      if( ( lineIndex != numberOfLines - 1u ) && // is not the last line.
+      if( ( lineIndex != totalNumberOfLines - 1u ) && // is not the last line.
           ( visualIndex == startCharacter ) )
       {
         // It places the cursor just after the first character in visual order.
@@ -285,7 +405,7 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
     // This branch checks if the closest line is the one with the last '\n'. If it is, it decrements the visual index to place
     // the cursor just before the last '\n'.
 
-    if( ( lineIndex != numberOfLines - 1u ) &&
+    if( ( lineIndex != totalNumberOfLines - 1u ) &&
         TextAbstraction::IsNewParagraph( *( logicalModel->mText.Begin() + visualIndex - 1u ) ) )
     {
       --visualIndex;
@@ -566,7 +686,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
   }
 }
 
-void FindSelectionIndices( VisualModelPtr visualModel,
+bool FindSelectionIndices( VisualModelPtr visualModel,
                            LogicalModelPtr logicalModel,
                            MetricsPtr metrics,
                            float visualX,
@@ -574,52 +694,122 @@ void FindSelectionIndices( VisualModelPtr visualModel,
                            CharacterIndex& startIndex,
                            CharacterIndex& endIndex )
 {
+
+/*
+  Hit character                                           Select
+|-------------------------------------------------------|------------------------------------------|
+| On a word                                             | The word                                 |
+| On a single white space between words                 | The word before or after the white space |
+| On one of the multiple contiguous white spaces        | The white spaces                         |
+| On a single white space which is in the position zero | The white space and the next word        |
+| On a new paragraph character                          | The word or group of white spaces before |
+|-------------------------------------------------------|------------------------------------------|
+*/
+
   CharacterIndex hitCharacter = Text::GetClosestCursorIndex( visualModel,
                                                              logicalModel,
                                                              metrics,
                                                              visualX,
                                                              visualY );
-  DALI_ASSERT_DEBUG( hitCharacter <= logicalModel->mText.Count() && "GetClosestCursorIndex returned out of bounds index" );
 
-  if( logicalModel->mText.Count() == 0 )
+  const Length totalNumberOfCharacters = logicalModel->mText.Count();
+
+  DALI_ASSERT_DEBUG( ( hitCharacter <= totalNumberOfCharacters ) && "GetClosestCursorIndex returned out of bounds index" );
+
+  if( 0u == totalNumberOfCharacters )
   {
-    return;  // if model empty
+    // Nothing to do if the model is empty.
+    return false;
   }
 
-  if( hitCharacter >= logicalModel->mText.Count() )
+  if( hitCharacter >= totalNumberOfCharacters )
   {
     // Closest hit character is the last character.
-    if( hitCharacter ==  logicalModel->mText.Count() )
+    if( hitCharacter == totalNumberOfCharacters )
     {
       hitCharacter--; //Hit character index set to last character in logical model
     }
     else
     {
       // hitCharacter is out of bounds
-      return;
+      return false;
     }
   }
 
+  const Character* const textBuffer = logicalModel->mText.Begin();
+
   startIndex = hitCharacter;
   endIndex = hitCharacter;
-  bool isHitCharacterWhitespace = TextAbstraction::IsWhiteSpace( logicalModel->mText[hitCharacter] );
 
-  // Find the start and end of the text
-  for( startIndex = hitCharacter; startIndex > 0; --startIndex )
+  // Whether the hit character is a new paragraph character.
+  const bool isHitCharacterNewParagraph = TextAbstraction::IsNewParagraph( *( textBuffer + hitCharacter ) );
+
+  // Whether the hit character is a white space. Note a new paragraph character is a white space as well but here is not wanted.
+  const bool isHitCharacterWhiteSpace = TextAbstraction::IsWhiteSpace( *( textBuffer + hitCharacter ) ) && !isHitCharacterNewParagraph;
+
+  FindWordData data( textBuffer,
+                     totalNumberOfCharacters,
+                     hitCharacter,
+                     isHitCharacterWhiteSpace,
+                     isHitCharacterNewParagraph );
+
+  if( isHitCharacterNewParagraph )
   {
-    if( isHitCharacterWhitespace != TextAbstraction::IsWhiteSpace( logicalModel->mText[ startIndex-1 ] ) )
+    // Find the first character before the hit one which is not a new paragraph character.
+
+    if( hitCharacter > 0u )
     {
-      break;
+      endIndex = hitCharacter - 1u;
+      for( ; endIndex > 0; --endIndex )
+      {
+        const Dali::Toolkit::Text::Character character = *( data.textBuffer + endIndex );
+
+        if( !Dali::TextAbstraction::IsNewParagraph( character ) )
+        {
+          break;
+        }
+      }
     }
+
+    data.hitCharacter = endIndex;
+    data.isNewParagraph = false;
+    data.isWhiteSpace = TextAbstraction::IsWhiteSpace( *( textBuffer + data.hitCharacter ) );
   }
-  const CharacterIndex pastTheEnd = logicalModel->mText.Count();
-  for( endIndex = hitCharacter + 1u; endIndex < pastTheEnd; ++endIndex )
+
+  // Find the start of the word.
+  FindStartOfWord( data );
+  startIndex = data.foundIndex;
+
+  // Find the end of the word.
+  FindEndOfWord( data );
+  endIndex = data.foundIndex;
+
+  if( 1u == ( endIndex - startIndex ) )
   {
-    if( isHitCharacterWhitespace != TextAbstraction::IsWhiteSpace( logicalModel->mText[ endIndex ] ) )
+    if( isHitCharacterWhiteSpace )
     {
-      break;
+      // Select the word before or after the white space
+
+      if( 0u == hitCharacter )
+      {
+        data.isWhiteSpace = false;
+        FindEndOfWord( data );
+        endIndex = data.foundIndex;
+      }
+      else if( hitCharacter > 0u )
+      {
+        // Find the start of the word.
+        data.hitCharacter = hitCharacter - 1u;
+        data.isWhiteSpace = false;
+        FindStartOfWord( data );
+        startIndex = data.foundIndex;
+
+        --endIndex;
+      }
     }
   }
+
+  return true;
 }
 
 } // namespace Text
index e89c335..5896b4d 100644 (file)
@@ -128,8 +128,10 @@ void GetCursorPosition( VisualModelPtr visualModel,
  * @param[in] visualY The touch point 'y' in text's coords.
  * @param[out] startIndex Index to the first character of the selected word.
  * @param[out] endIndex Index to the last character of the selected word.
+ *
+ * @return @e true if the indices are found.
  */
-void FindSelectionIndices( VisualModelPtr visualModel,
+bool FindSelectionIndices( VisualModelPtr visualModel,
                            LogicalModelPtr logicalModel,
                            MetricsPtr metrics,
                            float visualX,
index 8d9f8f5..cd51c8d 100644 (file)
@@ -795,6 +795,10 @@ struct LayoutEngine::Impl
         }
       }
 
+      // Calculates the layout size.
+      UpdateLayoutSize( lines,
+                        layoutSize );
+
       // Nothing else do if there are no glyphs to layout.
       return false;
     }
index e4029b3..2c45d35 100644 (file)
@@ -1544,13 +1544,6 @@ void Controller::Impl::OnSelectEvent( const Event& event )
     // Calculates the logical position from the x,y coords.
     RepositionSelectionHandles( xPosition,
                                 yPosition );
-
-    mEventData->mUpdateLeftSelectionPosition = true;
-    mEventData->mUpdateRightSelectionPosition = true;
-    mEventData->mUpdateHighlightBox = true;
-    mEventData->mUpdateCursorPosition = false;
-
-    mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition );
   }
 }
 
@@ -1566,6 +1559,8 @@ void Controller::Impl::OnSelectAllEvent()
 
   if( mEventData->mSelectionEnabled )
   {
+    ChangeState( EventData::SELECTING );
+
     mEventData->mLeftSelectionPosition = 0u;
     mEventData->mRightSelectionPosition = mLogicalModel->mText.Count();
 
@@ -2057,24 +2052,40 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY
   // Find which word was selected
   CharacterIndex selectionStart( 0 );
   CharacterIndex selectionEnd( 0 );
-  FindSelectionIndices( mVisualModel,
-                        mLogicalModel,
-                        mMetrics,
-                        visualX,
-                        visualY,
-                        selectionStart,
-                        selectionEnd );
+  const bool indicesFound = FindSelectionIndices( mVisualModel,
+                                                  mLogicalModel,
+                                                  mMetrics,
+                                                  visualX,
+                                                  visualY,
+                                                  selectionStart,
+                                                  selectionEnd );
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p selectionStart %d selectionEnd %d\n", this, selectionStart, selectionEnd );
 
-  if( selectionStart == selectionEnd )
+  if( indicesFound )
   {
-    ChangeState( EventData::EDITING );
-    // Nothing to select. i.e. a white space, out of bounds
-    return;
+    ChangeState( EventData::SELECTING );
+
+    mEventData->mLeftSelectionPosition = selectionStart;
+    mEventData->mRightSelectionPosition = selectionEnd;
+
+    mEventData->mUpdateLeftSelectionPosition = true;
+    mEventData->mUpdateRightSelectionPosition = true;
+    mEventData->mUpdateHighlightBox = true;
+
+    mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition );
   }
+  else
+  {
+    // Nothing to select. i.e. a white space, out of bounds
+    ChangeState( EventData::EDITING );
 
-  mEventData->mLeftSelectionPosition = selectionStart;
-  mEventData->mRightSelectionPosition = selectionEnd;
+    mEventData->mPrimaryCursorPosition = selectionEnd;
+
+    mEventData->mUpdateCursorPosition = true;
+    mEventData->mUpdateGrabHandlePosition = true;
+    mEventData->mScrollAfterUpdatePosition = true;
+    mEventData->mUpdateInputStyle = true;
+  }
 }
 
 void Controller::Impl::SetPopupButtons()
@@ -2492,13 +2503,13 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType,
   mEventData->mAllTextSelected = ( startOfSelection == 0 ) && ( endOfSelection == mLogicalModel->mText.Count() );
 }
 
-void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize )
+void Controller::Impl::ClampHorizontalScroll( const Vector2& layoutSize )
 {
   // Clamp between -space & 0.
 
-  if( actualSize.width > mVisualModel->mControlSize.width )
+  if( layoutSize.width > mVisualModel->mControlSize.width )
   {
-    const float space = ( actualSize.width - mVisualModel->mControlSize.width );
+    const float space = ( layoutSize.width - mVisualModel->mControlSize.width );
     mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x;
     mScrollPosition.x = ( mScrollPosition.x > 0.f ) ? 0.f : mScrollPosition.x;
 
@@ -2510,12 +2521,12 @@ void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize )
   }
 }
 
-void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize )
+void Controller::Impl::ClampVerticalScroll( const Vector2& layoutSize )
 {
   // Clamp between -space & 0.
-  if( actualSize.height > mVisualModel->mControlSize.height )
+  if( layoutSize.height > mVisualModel->mControlSize.height )
   {
-    const float space = ( actualSize.height - mVisualModel->mControlSize.height );
+    const float space = ( layoutSize.height - mVisualModel->mControlSize.height );
     mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y;
     mScrollPosition.y = ( mScrollPosition.y > 0.f ) ? 0.f : mScrollPosition.y;
 
index 99693ad..68659b6 100644 (file)
@@ -633,16 +633,16 @@ struct Controller::Impl
   /**
    * @biref Clamps the horizontal scrolling to get the control always filled with text.
    *
-   * @param[in] actualSize The size of the laid out text.
+   * @param[in] layoutSize The size of the laid out text.
    */
-  void ClampHorizontalScroll( const Vector2& actualSize );
+  void ClampHorizontalScroll( const Vector2& layoutSize );
 
   /**
    * @biref Clamps the vertical scrolling to get the control always filled with text.
    *
-   * @param[in] actualSize The size of the laid out text.
+   * @param[in] layoutSize The size of the laid out text.
    */
-  void ClampVerticalScroll( const Vector2& actualSize );
+  void ClampVerticalScroll( const Vector2& layoutSize );
 
   /**
    * @brief Scrolls the text to make a position visible.
index 1cf95fd..643c8b8 100644 (file)
@@ -144,7 +144,7 @@ void Controller::SetAutoScrollEnabled( bool enable )
       mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
                                                                LAYOUT                    |
                                                                ALIGN                     |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                UPDATE_DIRECTION          |
                                                                REORDER );
 
@@ -155,7 +155,7 @@ void Controller::SetAutoScrollEnabled( bool enable )
       mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
                                                                LAYOUT                    |
                                                                ALIGN                     |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                REORDER );
     }
 
@@ -925,7 +925,7 @@ void Controller::SetInputFontFamily( const std::string& fontFamily )
                                                                SHAPE_TEXT                |
                                                                GET_GLYPH_METRICS         |
                                                                LAYOUT                    |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                REORDER                   |
                                                                ALIGN );
       mImpl->mRecalculateNaturalSize = true;
@@ -999,7 +999,7 @@ void Controller::SetInputFontWeight( FontWeight weight )
                                                                SHAPE_TEXT                |
                                                                GET_GLYPH_METRICS         |
                                                                LAYOUT                    |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                REORDER                   |
                                                                ALIGN );
       mImpl->mRecalculateNaturalSize = true;
@@ -1053,7 +1053,7 @@ void Controller::SetInputFontWidth( FontWidth width )
                                                                SHAPE_TEXT                |
                                                                GET_GLYPH_METRICS         |
                                                                LAYOUT                    |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                REORDER                   |
                                                                ALIGN );
       mImpl->mRecalculateNaturalSize = true;
@@ -1107,7 +1107,7 @@ void Controller::SetInputFontSlant( FontSlant slant )
                                                                SHAPE_TEXT                |
                                                                GET_GLYPH_METRICS         |
                                                                LAYOUT                    |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                REORDER                   |
                                                                ALIGN );
       mImpl->mRecalculateNaturalSize = true;
@@ -1160,7 +1160,7 @@ void Controller::SetInputFontPointSize( float size )
                                                                SHAPE_TEXT                |
                                                                GET_GLYPH_METRICS         |
                                                                LAYOUT                    |
-                                                               UPDATE_ACTUAL_SIZE        |
+                                                               UPDATE_LAYOUT_SIZE        |
                                                                REORDER                   |
                                                                ALIGN );
       mImpl->mRecalculateNaturalSize = true;
@@ -1482,7 +1482,7 @@ Controller::UpdateTextType Controller::Relayout( const Size& size )
     mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
                                                              LAYOUT                    |
                                                              ALIGN                     |
-                                                             UPDATE_ACTUAL_SIZE        |
+                                                             UPDATE_LAYOUT_SIZE        |
                                                              REORDER );
     // Set the update info to relayout the whole text.
     mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
@@ -1705,6 +1705,9 @@ bool Controller::DoRelayout( const Size& size,
   const CharacterIndex startIndex = mImpl->mTextUpdateInfo.mParagraphCharacterIndex;
   const Length requestedNumberOfCharacters = mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters;
 
+  // Get the current layout size.
+  layoutSize = mImpl->mVisualModel->GetLayoutSize();
+
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::DoRelayout LAYOUT & operations\n");
@@ -1726,7 +1729,7 @@ bool Controller::DoRelayout( const Size& size,
 
     if( 0u == totalNumberOfGlyphs )
     {
-      if( NO_OPERATION != ( UPDATE_ACTUAL_SIZE & operations ) )
+      if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) )
       {
         mImpl->mVisualModel->SetLayoutSize( Size::ZERO );
       }
@@ -1772,14 +1775,18 @@ bool Controller::DoRelayout( const Size& size,
     layoutParameters.estimatedNumberOfLines = mImpl->mTextUpdateInfo.mEstimatedNumberOfLines;
 
     // Update the visual model.
+    Size newLayoutSize;
     viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters,
                                                    glyphPositions,
                                                    mImpl->mVisualModel->mLines,
-                                                   layoutSize );
+                                                   newLayoutSize );
 
+    viewUpdated = viewUpdated || ( newLayoutSize != layoutSize );
 
     if( viewUpdated )
     {
+      layoutSize = newLayoutSize;
+
       if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
       {
         mImpl->mAutoScrollDirectionRTL = false;
@@ -1826,8 +1833,8 @@ bool Controller::DoRelayout( const Size& size,
         }
       } // REORDER
 
-      // Sets the actual size.
-      if( NO_OPERATION != ( UPDATE_ACTUAL_SIZE & operations ) )
+      // Sets the layout size.
+      if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) )
       {
         mImpl->mVisualModel->SetLayoutSize( layoutSize );
       }
@@ -1836,10 +1843,6 @@ bool Controller::DoRelayout( const Size& size,
     // Store the size used to layout the text.
     mImpl->mVisualModel->mControlSize = size;
   }
-  else
-  {
-    layoutSize = mImpl->mVisualModel->GetLayoutSize();
-  }
 
   if( NO_OPERATION != ( ALIGN & operations ) )
   {
@@ -1873,7 +1876,7 @@ void Controller::SetMultiLineEnabled( bool enable )
 
     // Set the flags to redo the layout operations
     const OperationsMask layoutOperations =  static_cast<OperationsMask>( LAYOUT             |
-                                                                          UPDATE_ACTUAL_SIZE |
+                                                                          UPDATE_LAYOUT_SIZE |
                                                                           ALIGN              |
                                                                           REORDER );
 
@@ -2494,8 +2497,6 @@ void Controller::SelectEvent( float x, float y, bool selectAll )
 
   if( NULL != mImpl->mEventData )
   {
-    mImpl->ChangeState( EventData::SELECTING );
-
     if( selectAll )
     {
       Event event( Event::SELECT_ALL );
@@ -2923,7 +2924,7 @@ void Controller::ClearFontData()
                                                            SHAPE_TEXT                |
                                                            GET_GLYPH_METRICS         |
                                                            LAYOUT                    |
-                                                           UPDATE_ACTUAL_SIZE        |
+                                                           UPDATE_LAYOUT_SIZE        |
                                                            REORDER                   |
                                                            ALIGN );
 }
index 304ad2f..ad5c09a 100644 (file)
@@ -82,7 +82,7 @@ public:
     SHAPE_TEXT         = 0x0040,
     GET_GLYPH_METRICS  = 0x0080,
     LAYOUT             = 0x0100,
-    UPDATE_ACTUAL_SIZE = 0x0200,
+    UPDATE_LAYOUT_SIZE = 0x0200,
     REORDER            = 0x0400,
     ALIGN              = 0x0800,
     COLOR              = 0x1000,
index 0f27e3b..43eb1be 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 43;
+const unsigned int TOOLKIT_MICRO_VERSION = 44;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 725a71a..87c22af 100644 (file)
@@ -98,7 +98,7 @@
       "popupIconColor":[1.0,1.0,1.0,1.0],
       "popupPressedColor":[0.24,0.72,0.8,0.11],
       "background": {
-        "rendererType": "image",
+        "rendererType": "IMAGE",
         "url": "{DALI_IMAGE_DIR}selection-popup-bg.9.png"
         },
       "popupFadeInDuration":0.25,
index 3297e51..029dcbd 100644 (file)
@@ -98,7 +98,7 @@
       "popupIconColor":[1.0,1.0,1.0,1.0],
       "popupPressedColor":[0.24,0.72,0.8,0.11],
       "background": {
-        "rendererType": "image",
+        "rendererType": "IMAGE",
         "url": "{DALI_IMAGE_DIR}selection-popup-bg.9.png"
         },
       "popupFadeInDuration":0.25,
index 87b49b5..41cf322 100644 (file)
  * </tr>
  * </table>
  *
+ * \ifnot show_tizen_feature
+ *
+ * @section dali_toolkit_feature Related Features
+ * This API is related with the following features:\n
+ *    - http://tizen.org/feature/opengles.version.2_0\n
+ *
+ * It is recommended to design feature related codes in your application for reliability.\n
+ *
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n
+ *
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n
+ *
+ * More details on featuring your application can be found from <a href="https://developer.tizen.org/development/tools/native-tools/manifest-text-editor#feature"><b>Feature Element</b>.</a>
+ *
+ * \endif
+ *
  * @ingroup dali
  * @{
  *   @defgroup dali_toolkit_controls Controls
index 300d276..69248b9 100644 (file)
@@ -66,7 +66,7 @@ public:
 
     // Set another property to set the image-map
     Property::Map imageMap;
-    imageMap[ "rendererType" ] = "image";
+    imageMap[ "rendererType" ] = "IMAGE";
     imageMap[ "url" ]          = IMAGE_CARDS;
     imageMap[ "desiredWidth" ]        = 100;
     imageMap[ "desiredHeight" ]       = 100;
diff --git a/docs/content/images/renderers/bevelled-cube-high.png b/docs/content/images/renderers/bevelled-cube-high.png
new file mode 100644 (file)
index 0000000..d6676db
Binary files /dev/null and b/docs/content/images/renderers/bevelled-cube-high.png differ
diff --git a/docs/content/images/renderers/bevelled-cube-low.png b/docs/content/images/renderers/bevelled-cube-low.png
new file mode 100644 (file)
index 0000000..d76c836
Binary files /dev/null and b/docs/content/images/renderers/bevelled-cube-low.png differ
diff --git a/docs/content/images/renderers/cone.png b/docs/content/images/renderers/cone.png
new file mode 100644 (file)
index 0000000..6437a0e
Binary files /dev/null and b/docs/content/images/renderers/cone.png differ
diff --git a/docs/content/images/renderers/conical-frustrum.png b/docs/content/images/renderers/conical-frustrum.png
new file mode 100644 (file)
index 0000000..000c74b
Binary files /dev/null and b/docs/content/images/renderers/conical-frustrum.png differ
diff --git a/docs/content/images/renderers/cube.png b/docs/content/images/renderers/cube.png
new file mode 100644 (file)
index 0000000..af04b30
Binary files /dev/null and b/docs/content/images/renderers/cube.png differ
diff --git a/docs/content/images/renderers/cylinder.png b/docs/content/images/renderers/cylinder.png
new file mode 100644 (file)
index 0000000..d4efd00
Binary files /dev/null and b/docs/content/images/renderers/cylinder.png differ
diff --git a/docs/content/images/renderers/octahedron.png b/docs/content/images/renderers/octahedron.png
new file mode 100644 (file)
index 0000000..9ad5704
Binary files /dev/null and b/docs/content/images/renderers/octahedron.png differ
diff --git a/docs/content/images/renderers/slices.png b/docs/content/images/renderers/slices.png
new file mode 100644 (file)
index 0000000..8747577
Binary files /dev/null and b/docs/content/images/renderers/slices.png differ
diff --git a/docs/content/images/renderers/sphere.png b/docs/content/images/renderers/sphere.png
new file mode 100644 (file)
index 0000000..3efd4a0
Binary files /dev/null and b/docs/content/images/renderers/sphere.png differ
diff --git a/docs/content/images/renderers/stacks.png b/docs/content/images/renderers/stacks.png
new file mode 100644 (file)
index 0000000..fb3cb84
Binary files /dev/null and b/docs/content/images/renderers/stacks.png differ
index c157a18..ef2d933 100644 (file)
@@ -62,7 +62,7 @@ then the above image will look like:
 The background can be set to use a specified renderer, e.g the border renderer
 @code
 Property::Map renderer;
-renderer.Insert("rendererType","border");
+renderer.Insert("rendererType","BORDER");
 renderer.Insert("borderColor",COLOR::RED);
 renderer.Insert("borderSize",20.f);
 
index 9b18dfc..27a8574 100644 (file)
@@ -47,7 +47,7 @@
  *
  * @code
  * Property::Map renderer;
- * renderer.Insert("rendererType","border");
+ * renderer.Insert("rendererType","BORDER");
  * renderer.Insert("borderColor",COLOR::RED);
  * renderer.Insert("borderSize",20.f);
  *
index 1033b5f..cc15da1 100644 (file)
@@ -231,7 +231,7 @@ imageView.parentOrigin = dali.CENTER;
 
 // Set an image view property
 imageView.image = {
-  "rendererType" : "image",
+  "rendererType" : "IMAGE",
   "url": "images/icon-0.png",
   "desiredWidth" : 100,
   "desiredHeight" : 100
@@ -260,7 +260,7 @@ This is a basic example of a button defined in JSON by setting the default prope
       "position": [0, 0, 0],
       "image":
       {
-        "rendererType" : "image",
+        "rendererType" : "IMAGE",
         "url" : "images/icon-0.png",
         "desiredWidth" : 100,
         "desiredHeight" : 100
index 6930b03..fd60f06 100644 (file)
@@ -15,6 +15,7 @@ DALi provides the following renderers:
  + [Image](@ref image-renderers)
  + [Border](@ref border-renderer)
  + [Mesh](@ref mesh-renderer)
+ + [Primitive](@ref primitive-renderer)
  
 Controls can provide properties that allow users to specify the renderer type.
 Setting renderer properties are done via a property map.
@@ -31,7 +32,7 @@ Renders a solid color to the control's quad.
 
 ### Properties Supported
 
-**RendererType:** "color"
+**RendererType:** "COLOR"
 
 | Property Name | Type    | Required | Description               |
 |---------------|:-------:|:--------:|---------------------------|
@@ -44,7 +45,7 @@ Renders a solid color to the control's quad.
 Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
-map[ "rendererType" ] = "color";
+map[ "rendererType" ] = "COLOR";
 map[ "mixColor" ] = Color::RED;
 
 control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
@@ -56,7 +57,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "color",
+  rendererType : "COLOR",
   mixColor : dali.COLOR_RED
 };
 ~~~
@@ -74,18 +75,18 @@ Both Linear and Radial gradients are supported.
 
 ### Properties Supported
 
-**RendererType:** "gradient"
+**RendererType:** "GRADIENT"
 
-| Property Name                                                | Type             | Required   | Description                                                             |
-|--------------------------------------------------------------|:----------------:|:----------:|-------------------------------------------------------------------------|
-| startPosition                                                | VECTOR2          | For Linear | The start position of the linear gradient.                              |
-| endPosition                                                  | VECTOR2          | For Linear | The end position of the linear gradient.                                |
-| center                                                       | VECTOR2          | For Radial | The center point of the gradient.                                       |
-| radius                                                       | FLOAT            | For Radial | The size of the radius.                                                 |
-| stopOffset                                                   | ARRAY of FLOAT   | No         | All the stop offsets. If not supplied default is 0.0 and 1.0            |
-| stopColor                                                    | ARRAY of VECTOR4 | Yes        | The color at those stop offsets. At least 2 required to show a gradient |
-| [gradientUnits](@ref gradient-renderer-units)                | STRING           | No         | *objectBoundingBox* or *userSpace*. Default: *objectBoundingBox*.       |
-| [gradientSpreadMethod](@ref gradient-renderer-spread-method) | STRING           | No         | *pad*, *repeat* or *reflect*. Default: *pad*                            |
+| Property Name                                        | Type             | Required   | Description                                                              |
+|------------------------------------------------------|:----------------:|:----------:|--------------------------------------------------------------------------|
+| startPosition                                        | VECTOR2          | For Linear | The start position of the linear gradient.                               |
+| endPosition                                          | VECTOR2          | For Linear | The end position of the linear gradient.                                 |
+| center                                               | VECTOR2          | For Radial | The center point of the gradient.                                        |
+| radius                                               | FLOAT            | For Radial | The size of the radius.                                                  |
+| stopOffset                                           | ARRAY of FLOAT   | No         | All the stop offsets. If not supplied default is 0.0 and 1.0.            |
+| stopColor                                            | ARRAY of VECTOR4 | Yes        | The color at those stop offsets. At least 2 required to show a gradient. |
+| [units](@ref gradient-renderer-units)                | STRING           | No         | *OBJECT_BOUNDING_BOX* or *USER_SPACE*. Default: *OBJECT_BOUNDING_BOX*.   |
+| [spreadMethod](@ref gradient-renderer-spread-method) | STRING           | No         | *PAD*, *REFLECT* or *REPEAT*. Default: *PAD*.                            |
 
 If the *stopOffset* and *stopColor* arrays do not have the same number of elements, then the minimum of the two is used as the stop points.
 
@@ -95,10 +96,10 @@ Defines the coordinate system for the attributes:
  + Start (x1, y1) and End (x2 and y2) points of a line if using a linear gradient.
  + Center point (cx, cy) and radius (r) of a circle if using a radial gradient.
  
-| Value             | Description                                                                                                                                    |
-|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
-| objectBoundingBox | *Default*. Uses the normals for the start, end & center points, i.e. top-left is (-0.5, -0.5) and bottom-right it (0.5, 0.5).                  |
-| userSpace         | Uses the user coordinates for the start, end & center points, i.e. in a 200 by 200 control, top-left is (0, 0) and bottom-right is (200, 200). |
+| Value               | Description                                                                                                                                    |
+|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
+| OBJECT_BOUNDING_BOX | *Default*. Uses the normals for the start, end & center points, i.e. top-left is (-0.5, -0.5) and bottom-right is (0.5, 0.5).                  |
+| USER_SPACE          | Uses the user coordinates for the start, end & center points, i.e. in a 200 by 200 control, top-left is (0, 0) and bottom-right is (200, 200). |
 
 ### Spread Method {#gradient-renderer-spread-method}
 
@@ -106,9 +107,9 @@ Indicates what happens if the gradient starts or ends inside the bounds of the t
 
 | Value   | Description                                                                                          |
 |---------|------------------------------------------------------------------------------------------------------|
-| pad     | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad.               |
-| reflect | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad is filled. |
-| repeat  | Repeat the gradient pattern start-to-end, start-to-end, start-to-end until the quad is filled.       |
+| PAD     | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad.               |
+| REFLECT | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad is filled. |
+| REPEAT  | Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. until the quad is filled.  |
 
 ### Usage
 
@@ -118,7 +119,7 @@ Indicates what happens if the gradient starts or ends inside the bounds of the t
 Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
-map[ "rendererType" ] = "gradient";
+map[ "rendererType" ] = "GRADIENT";
 map[ "startPosition" ] = Vector2( 0.5f, 0.5f );
 map[ "endPosition" ] = Vector2( -0.5f, -0.5f );
 
@@ -147,7 +148,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "gradient",
+  rendererType : "GRADIENT",
   startPosition : [ 0.5, 0.5 ],
   endPosition : [ -0.5, -0.5 ],
   stopOffset : [ 0.0, 0.3, 0.6, 0.8, 1.0 ],
@@ -167,7 +168,7 @@ control.background =
 Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
-map[ "rendererType" ] = "gradient";
+map[ "rendererType" ] = "GRADIENT";
 map[ "center" ] = Vector2( 0.5f, 0.5f );
 map[ "radius" ] = 1.414f;
 
@@ -196,7 +197,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "gradient",
+  rendererType : "GRADIENT",
   center : [ 0.5, 0.5 ],
   radius : 1.414,
   stopOffset : [ 0.0, 0.3, 0.6, 0.8, 1.0 ],
@@ -232,15 +233,15 @@ Renders a raster image ( jpg, png etc.) into the control's quad.
 
 #### Properties Supported
 
-**RendererType:** "image"
+**RendererType:** "IMAGE"
 
-| Property Name      | Type     | Required | Description                                                                                                                                     |
-|--------------------|:--------:|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------|
-| url           | STRING   | Yes      | The URL of the image.                                                                                                                           |
-| [fittingMode](@ref resourceimagescaling-fittingmode) | STRING   | No       | *SHRINK_TO_FIT*, *SCALE_TO_FILL*, *FIT_WIDTH* or *FIT_HEIGHT*. Default: *SHRINK_TO_FIT*.                         |
-| [samplingMode](@ref resourceimagescaling-scaling)    | STRING   | No       | *BOX*, *NEAREST*, *LINEAR*, *BOX_THEN_NEAREST*, *BOX_THEN_LINEAR*, *NO_FILTERr* or *DONT_CARE*. Default: *BOX*. |
-| desiredWidth  | INT      | No       | The desired image width. Will use actual image width if not specified.                                                                          |
-| desiredHeight | INT      | No       | The desired image height. Will use actual image height if not specified.                                                                        |
+| Property Name                                        | Type     | Required | Description                                                                                                    |
+|------------------------------------------------------|:--------:|:--------:|----------------------------------------------------------------------------------------------------------------|
+| url                                                  | STRING   | Yes      | The URL of the image.                                                                                          |
+| [fittingMode](@ref resourceimagescaling-fittingmode) | STRING   | No       | *SHRINK_TO_FIT*, *SCALE_TO_FILL*, *FIT_WIDTH* or *FIT_HEIGHT*. Default: *SHRINK_TO_FIT*.                       |
+| [samplingMode](@ref resourceimagescaling-scaling)    | STRING   | No       | *BOX*, *NEAREST*, *LINEAR*, *BOX_THEN_NEAREST*, *BOX_THEN_LINEAR*, *NO_FILTER* or *DONT_CARE*. Default: *BOX*. |
+| desiredWidth                                         | INT      | No       | The desired image width. Will use actual image width if not specified.                                         |
+| desiredHeight                                        | INT      | No       | The desired image height. Will use actual image height if not specified.                                       |
 
 #### Usage
 
@@ -249,7 +250,7 @@ Renders a raster image ( jpg, png etc.) into the control's quad.
 Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
-map[ "rendererType" ] = "image";
+map[ "rendererType" ] = "IMAGE";
 map[ "url" ] = "path-to-image.jpg";
 
 control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
@@ -261,7 +262,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "image",
+  rendererType : "IMAGE",
   url : "path-to-image.jpg"
 };
 ~~~
@@ -276,7 +277,7 @@ Renders an n-patch or a 9-patch image into the control's quad.
 
 #### Properties Supported
 
-**RendererType:** "image"
+**RendererType:** "IMAGE"
 
 | Property Name | Type    | Required | Description                      |
 |---------------|:-------:|:--------:|----------------------------------|
@@ -291,7 +292,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
 
-map[ "rendererType" ] = "image";
+map[ "rendererType" ] = "IMAGE";
 map[ "url" ] = "path-to-image.9.png";
 
 control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
@@ -303,7 +304,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "image",
+  rendererType : "IMAGE",
   url : "path-to-image.9.png"
 };
 ~~~
@@ -347,7 +348,7 @@ Renders a svg image into the control's quad.
  
 #### Properties Supported
 
-**RendererType:** "image"
+**RendererType:** "IMAGE"
 
 | Property Name | Type    | Required | Description                      |
 |---------------|:-------:|:--------:|----------------------------------|
@@ -361,7 +362,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
 
-map[ "rendererType" ] = "image";
+map[ "rendererType" ] = "IMAGE";
 map[ "url" ] = "path-to-image.svg";
 
 control.SetSize( 200.f, 200.f );
@@ -374,7 +375,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "image",
+  rendererType : "IMAGE",
   url : "path-to-image.svg"
 };
 ~~~
@@ -389,7 +390,7 @@ Renders a solid color as an internal border to the control's quad.
 
 ### Properties Supported
 
-**RendererType:** "border"
+**RendererType:** "BORDER"
 
 | Property Name | Type    | Required | Description                                      |
 |---------------|:-------:|:--------:|--------------------------------------------------|
@@ -405,7 +406,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
 
-map[ "rendererType" ] = "border";
+map[ "rendererType" ] = "BORDER";
 map[ "borderColor"  ] = Color::BLUE;
 map[ "borderSize"   ] = 5.0f;
 
@@ -418,7 +419,7 @@ var control = new dali.Control( "Control" );
 
 control.background =
 {
-  rendererType : "border",
+  rendererType : "BORDER",
   borderColor : dali.COLOR_BLUE,
   borderSize = 5
 };
@@ -435,27 +436,171 @@ Renders a mesh using a .obj file, optionally with textures provided by a mtl fil
 
 ### Properties Supported
 
-**RendererType** "mesh"
+**RendererType** "MESH"
 
-| Property Name | Type    | Required           | Description                                                          |
-|---------------|:-------:|:------------------:|----------------------------------------------------------------------|
-| objectUrl     | STRING  | Yes                | The location of the .obj file.                                       |
-| materialUrl   | STRING  | No                 | The location of the .mtl file. Leave blank for a textureless object. |
-| texturesPath  | STRING  | If using material  | Path to the directory textures (including gloss and normal) are stored in.   |
-| shaderType    | STRING  | No                 | Sets the type of shader to be used with the mesh. Note that if anything the shader requires is missing, it will use a simpler one that it can handle with what has been supplied.\n Possible values: "textureless", "diffuseTexture", "allTextures".  |
+| Property Name                                | Type    | Required           | Description                                                                                |
+|----------------------------------------------|:-------:|:------------------:|--------------------------------------------------------------------------------------------|
+| objectUrl                                    | STRING  | Yes                | The location of the ".obj" file.                                                           |
+| materialUrl                                  | STRING  | No                 | The location of the ".mtl" file. Leave blank for a textureless object.                     |
+| texturesPath                                 | STRING  | If using material  | Path to the directory the textures (including gloss and normal) are stored in.             |
+| [shaderType](@ref mesh-renderer-shader-type) | STRING  | No                 | Sets the type of shader to be used with the mesh.                                          |
+| useMipmapping                                | BOOLEAN | No                 | Flag for whether to use mipmaps for textures or not. Default true.                         |
+| useSoftNormals                               | BOOLEAN | No                 | Flag for whether to average normals at each point to smooth textures or not. Default true. |
+| lightPosition                                | VECTOR3 | No                 | The position, in stage space, of the point light that applies lighting to the model. This is based off the stage's dimensions, so using the width and height of the stage halved will correspond to the center, and using all zeroes will place the light at the upper left corner. Note that this corresponds to a shader property, so it can be registered and set in the actor as well. |
+
+### Shader Type {#mesh-renderer-shader-type}
+
+When specifying the shader type, if anything the shader requires is missing, a simpler type that can be handled with what has been supplied will be used instead.
+**Possible values:**
+| String Value    | Description                                    |
+|-----------------|------------------------------------------------|
+| TEXTURELESS     | *Simplest*. A flat color with shading is used. |
+| DIFFUSE_TEXTURE | Textured.                                      |
+| ALL_TEXTURES    | Has a gloss, normal map and texture map.       |
 
 ### Usage
 
 ~~~{.cpp}
 // C++
+Dali::Stage stage = Dali::Stage::GetCurrent();
+Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
+
+Dali::Property::Map map;
+
+map[ "rendererType"  ] = "MESH";
+map[ "objectUrl"     ] = "home/models/Dino.obj";
+map[ "materialUrl"   ] = "home/models/Dino.mtl";
+map[ "texturesPath"  ] = "home/images/";
+
+control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
+~~~
+
+___________________________________________________________________________________________________
+
+## Primitive Renderer {#primitive-renderer}
+
+Renders a simple 3D shape, such as a cube or sphere. Scaled to fit the control.
+
+![ ](../assets/img/renderers/cube.png)
+![ ](renderers/cube.png)
+
+### Properties Supported
+
+**RendererType** "PRIMITIVE"
+
+| Property Name                         | Type    | Description                                                                     | Default Value        | Range                          |
+|---------------------------------------|:-------:|---------------------------------------------------------------------------------|:--------------------:|:------------------------------:|
+| [shape](@ref shape-details)           | STRING  | The specific shape to render.                                                   | "SPHERE"             | [See list](@ref shape-details) |
+| shapeColor                            | VECTOR4 | The color of the shape.                                                         | (0.5, 0.5, 0.5, 1.0) | 0.0 - 1.0 for each             |
+| [slices](@ref slices-details)         | INT     | The number of slices as you go around the shape.                                | 128                  | 1 - 255                        |
+| [stacks](@ref stacks-details)         | INT     | The number of stacks as you go down the shape.                                  | 128                  | 1 - 255                        |
+| scaleTopRadius                        | FLOAT   | The scale of the radius of the top circle of a conical frustrum.                | 1.0                  | ≥ 0.0                          |
+| scaleBottomRadius                     | FLOAT   | The scale of the radius of the bottom circle of a conical frustrum.             | 1.5                  | ≥ 0.0                          |
+| scaleHeight                           | FLOAT   | The scale of the height of a conic.                                             | 3.0                  | > 0.0                          |
+| scaleRadius                           | FLOAT   | The scale of the radius of a cylinder.                                          | 1.0                  | > 0.0                          |
+| scaleDimensions                       | VECTOR3 | The dimensions of a cuboid. Scales in the same fashion as a 9-patch image.      | (1.0, 1.0, 1.0)      | > 0.0 for each                 |
+| [bevelPercentage](@ref bevel-details) | FLOAT   | Determines how bevelled the cuboid should be, based off the smallest dimension. | 0.0 (no bevel)       | 0.0 - 1.0                      |
+| bevelSmoothness                       | FLOAT   | Defines how smooth the bevelled edges should be.                                | 0.0 (sharp edges)    | 0.0 - 1.0                      |
+| lightPosition                        | VECTOR3 | The position, in stage space, of the point light that applies lighting to the model. This is based off the stage's dimensions, so using the width and height of the stage halved will correspond to the center, and using all zeroes will place the light at the upper left back corner. Note that this corresponds to a shader property, so it can be registered and set in the actor as well. | (Offset outwards from the center of the screen.) | Unlimited |
+
+### Shapes {#shape-details}
+
+There are six shapes that can be chosen, some of which are simplified specialisations of another.
+
+| Value            | Description                                                                       | Parameters                                                    |
+|------------------|-----------------------------------------------------------------------------------|---------------------------------------------------------------|
+| SPHERE           | *Default*.                                                                        | color, slices, stacks                                         |
+| CONICAL_FRUSTRUM | The area bound between two circles, i.e. a cone with the tip removed.             | color, scaleTopRadius, scaleBottomRadius, scaleHeight, slices |
+| CONE             | Equivalent to a conical frustrum with top radius of zero.                         | color, scaleBottomRadius, scaleHeight, slices                 |
+| CYLINDER         | Equivalent to a conical frustrum with equal radii for the top and bottom circles. | color, scaleRadius, scaleHeight, slices                       |
+| CUBE             | Equivalent to a bevelled cube with a bevel percentage of zero.                    | color, scaleDimensions                                        |
+| OCTAHEDRON       | Equivalent to a bevelled cube with a bevel percentage of one.                     | color, scaleDimensions                                        |
+| BEVELLED_CUBE    | A cube/cuboid with all edges flattened to some degree.                            | color, scaleDimensions, bevelPercentage, bevelSmoothness      |
+
+Examples below:
+
+**sphere:**
+
+![ ](../assets/img/renderers/sphere.png)
+![ ](renderers/sphere.png)
+
+**conics:**
+
+| Frustrum | Cone | Cylinder |
+|----------|------|----------|
+| ![ ](../assets/img/renderers/conical-frustrum.png) ![ ](renderers/conical-frustrum.png) | ![ ](../assets/img/renderers/cone.png) ![ ](renderers/cone.png) | ![ ](../assets/img/renderers/cylinder.png) ![ ](renderers/cylinder.png) |
+
+### Bevel {#bevel-details}
+
+Bevel percentage ranges from 0.0 to 1.0. It affects the ratio of the outer face widths to the width of the overall cube, as shown:
+
+| 0.0 ( cube) | 0.3 | 0.7 | 1.0 (octahedron) |
+|-------------|-----|-----|------------------|
+| ![ ](../assets/img/renderers/cube.png) ![ ](renderers/cube.png) | ![ ](../assets/img/renderers/bevelled-cube-low.png) ![ ](renderers/bevelled-cube-low.png) | ![ ](../assets/img/renderers/bevelled-cube-high.png) ![ ](renderers/bevelled-cube-high.png) | ![ ](../assets/img/renderers/octahedron.png) ![ ](renderers/octahedron.png) |
+
+### Slices {#slices-details}
+
+For spheres and conical frustrums, 'slices' determines how many divisions there are as you go around the object.
+
+![ ](../assets/img/renderers/slices.png)
+![ ](renderers/slices.png)
+
+### Stacks {#stacks-details}
+
+For spheres, 'stacks' determines how many layers there are as you go down the object.
+
+![ ](../assets/img/renderers/stacks.png)
+![ ](renderers/stacks.png)
+
+### Usage
+
+**sphere**
+
+~~~{.cpp}
+// C++
+Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
+
+Dali::Property::Map map;
+
+map[ "rendererType" ] = "PRIMITIVE";
+map[ "shape"        ] = "SPHERE";
+map[ "shapeColor"   ] = Vector4( 1.0, 0.5, 0.0, 1.0 );
+
+control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
+~~~
+
+**conical frustrum**
+
+~~~{.cpp}
+// C++
+Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
+
+Dali::Property::Map map;
+
+map[ "rendererType"      ] = "PRIMITIVE";
+map[ "shape"             ] = "CONICAL_FRUSTRUM";
+map[ "shapeColor"        ] = Vector4( 1.0, 0.5, 0.0, 1.0 );
+map[ "scaleTopRadius"    ] = 1.0f;
+map[ "scaleBottomRadius" ] = 1.5f;
+map[ "scaleHeight"       ] = 3.0f;
+
+control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
+~~~
+
+**bevelled cube**
+
+~~~{.cpp}
+// C++
 Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
 
 Dali::Property::Map map;
 
-map[ "rendererType" ] = "mesh";
-map[ "objectUrl"    ] = "home/models/Dino.obj";
-map[ "materialUrl"  ] = "home/models/Dino.mtl";
-map[ "texturesPath" ] = "home/images/";
+map[ "rendererType"    ] = "PRIMITIVE";
+map[ "shape"           ] = "BEVELLED_CUBE";
+map[ "shapeColor"      ] = Vector4( 1.0, 0.5, 0.0, 1.0 );
+map[ "bevelPercentage" ] = 0.4f;
 
 control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
 ~~~
index 2016ea7..2871198 100644 (file)
@@ -15,7 +15,7 @@
           "type":"ImageView",
           "image":
           {
-            "rendererType" : "image",
+            "rendererType" : "IMAGE",
             "url": "{icon_path}"
           },
           "position":[20.0, 0.0, 0.0],
@@ -59,7 +59,7 @@
           "type":"ImageView",
           "image":
           {
-            "rendererType" : "image",
+            "rendererType" : "IMAGE",
             "url": "{icon_path}"
           },
           "position":[0.0, -10.0, 0.0],
index 2016ea7..2871198 100644 (file)
@@ -15,7 +15,7 @@
           "type":"ImageView",
           "image":
           {
-            "rendererType" : "image",
+            "rendererType" : "IMAGE",
             "url": "{icon_path}"
           },
           "position":[20.0, 0.0, 0.0],
@@ -59,7 +59,7 @@
           "type":"ImageView",
           "image":
           {
-            "rendererType" : "image",
+            "rendererType" : "IMAGE",
             "url": "{icon_path}"
           },
           "position":[0.0, -10.0, 0.0],
index eb2312d..8188de1 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.1.43
+Version:    1.1.44
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT
index fbff9bd..e5a3da4 100644 (file)
@@ -190,7 +190,7 @@ var imageView = createImageView();
 var shader = createColorShiftAndZoomEffect();
   
 var image = {
-    "rendererType" : "image",
+    "rendererType" : "IMAGE",
     "url" : getImageDirectory()+"gallery-medium-50.jpg",
     "shader" : shader
 };
index 3b61fc2..e0b0f48 100644 (file)
@@ -45,7 +45,7 @@ imageView.size = imageViewSize; // If not set, it will use either the natural im
 dali.stage.add( imageView );
   
 var image = {
-    "rendererType" : "image",
+    "rendererType" : "IMAGE",
     "url" : "myImage.jpg",
     "desiredWidth" : desiredWidth,   // The desired image width while loading (optional but preferable to set for efficiency)
     "desiredHeight" : desiredHeight,   // The desired image height while loading (optional but preferable to set for efficiency)
index 8f0c3ed..9643c3e 100644 (file)
@@ -30,7 +30,7 @@
             "type":"ImageView",
             "image":
             {
-              "rendererType" : "image",
+              "rendererType" : "IMAGE",
               "url": "{icon_path}"
             },
             "position":[20.0, 0.0, 0.0],