Revert public API changes. Handle methods.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / primitive / primitive-visual.cpp
index 7634ce5..43c69cc 100644 (file)
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/common/constants.h>
+#include <dali/devel-api/object/handle-devel.h>
+#include <dali/devel-api/scripting/enum-helper.h>
+#include <dali/devel-api/scripting/scripting.h>
 
-//INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
 
 namespace Dali
 {
@@ -39,6 +43,31 @@ namespace Internal
 namespace
 {
 
+// shapes
+DALI_ENUM_TO_STRING_TABLE_BEGIN( SHAPE_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, SPHERE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, CONICAL_FRUSTRUM )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, CONE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, CYLINDER )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, CUBE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, OCTAHEDRON )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::PrimitiveVisual::Shape, BEVELLED_CUBE )
+DALI_ENUM_TO_STRING_TABLE_END( SHAPE_TYPE )
+
+//Property names
+const char * const PRIMITIVE_SHAPE( "shape" );
+const char * const SHAPE_COLOR( "mixColor" );
+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" );
+const char * const LIGHT_POSITION_UNIFORM_NAME( "lightPosition" );
+
 //Primitive property defaults
 const int     DEFAULT_SLICES =              128; ///< For spheres and conics
 const int     DEFAULT_STACKS =              128; ///< For spheres and conics
@@ -48,19 +77,17 @@ 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.
+const Vector4 DEFAULT_COLOR =               Vector4( 0.5, 0.5, 0.5, 1.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   MIN_SLICES =           3;   ///< Minimum number of slices for spheres and conics
+const int   MIN_STACKS =           2;   ///< 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" );
@@ -72,7 +99,7 @@ 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 COLOR_UNIFORM_NAME( "mixColor" );
 const char * const OBJECT_DIMENSIONS_UNIFORM_NAME( "uObjectDimensions" );
 const char * const STAGE_OFFSET_UNIFORM_NAME( "uStageOffset" );
 
@@ -97,13 +124,26 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   uniform   mediump vec3 lightPosition;\n
   uniform   mediump vec2 uStageOffset;\n
 
-  void main()\n
+  //Visual size and offset
+  uniform mediump vec2 offset;\n
+  uniform mediump vec2 size;\n
+  uniform mediump vec4 offsetSizeMode;\n
+  uniform mediump vec2 origin;\n
+  uniform mediump vec2 anchorPoint;\n
+
+  vec4 ComputeVertexPosition()\n
   {\n
-    float xRatio = uSize.x / uObjectDimensions.x;\n
-    float yRatio = uSize.y / uObjectDimensions.y;\n
-    float scaleFactor = min( xRatio, yRatio );\n
+    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
+    float scaleFactor = min( visualSize.x / uObjectDimensions.x, visualSize.y / uObjectDimensions.y );\n
+    vec3 originFlipY =  vec3(origin.x, -origin.y, 0.0);
+    vec3 anchorPointFlipY = vec3( anchorPoint.x, -anchorPoint.y, 0.0);
+    vec3 offset = vec3( ( offset / uSize.xy ) * offsetSizeMode.xy + offset * (1.0-offsetSizeMode.xy), 0.0) * vec3(1.0,-1.0,1.0);\n
+    return vec4( (aPosition + anchorPointFlipY)*scaleFactor + (offset + originFlipY)*uSize, 1.0 );\n
+  }\n
 
-    vec4 normalisedVertexPosition = vec4( aPosition * scaleFactor, 1.0 );\n
+  void main()\n
+  {\n
+    vec4 normalisedVertexPosition = ComputeVertexPosition();\n
     vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
     vertexPosition = uMvpMatrix * vertexPosition;\n
 
@@ -127,14 +167,21 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   precision mediump float;\n
   varying   mediump vec3  vIllumination;\n
   uniform   lowp    vec4  uColor;\n
+  uniform   lowp    vec4  mixColor;\n
 
   void main()\n
   {\n
-    gl_FragColor = vec4( vIllumination.rgb * uColor.rgb, uColor.a );\n
+    vec4 baseColor = mixColor * uColor;\n
+    gl_FragColor = vec4( vIllumination.rgb * baseColor.rgb, baseColor.a );\n
   }\n
 );
 
-} // namespace
+} // unnamed namespace
+
+PrimitiveVisualPtr PrimitiveVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new PrimitiveVisual( factoryCache );
+}
 
 PrimitiveVisual::PrimitiveVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
@@ -148,7 +195,7 @@ PrimitiveVisual::PrimitiveVisual( VisualFactoryCache& factoryCache )
   mBevelSmoothness( DEFAULT_BEVEL_SMOOTHNESS ),
   mSlices( DEFAULT_SLICES ),
   mStacks( DEFAULT_STACKS ),
-  mPrimitiveType( SPHERE )
+  mPrimitiveType( Toolkit::PrimitiveVisual::Shape::SPHERE )
 {
 }
 
@@ -156,52 +203,13 @@ PrimitiveVisual::~PrimitiveVisual()
 {
 }
 
-void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void PrimitiveVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   //Find out which shape to renderer.
-  Property::Value* primitiveType = propertyMap.Find( PRIMITIVE_SHAPE );
-  if( primitiveType )
+  Property::Value* primitiveTypeValue = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SHAPE, PRIMITIVE_SHAPE );
+  if( primitiveTypeValue )
   {
-    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 PrimitiveVisual.\n" );
-      }
-    }
-    else
-    {
-      DALI_LOG_ERROR( "Invalid type for shape in PrimitiveVisual.\n" );
-    }
+    Scripting::GetEnumerationProperty( *primitiveTypeValue, SHAPE_TYPE_TABLE, SHAPE_TYPE_TABLE_COUNT, mPrimitiveType );
   }
   else
   {
@@ -210,13 +218,13 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
 
   //Read in other potential properties.
 
-  Property::Value* color = propertyMap.Find( SHAPE_COLOR );
+  Property::Value* color = propertyMap.Find( Toolkit::PrimitiveVisual::Property::MIX_COLOR, SHAPE_COLOR );
   if( color && !color->Get( mColor ) )
   {
     DALI_LOG_ERROR( "Invalid type for color in PrimitiveVisual.\n" );
   }
 
-  Property::Value* slices = propertyMap.Find( SLICES );
+  Property::Value* slices = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SLICES, SLICES );
   if( slices )
   {
     if( slices->Get( mSlices ) )
@@ -225,10 +233,12 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
       if( mSlices > MAX_PARTITIONS )
       {
         mSlices = MAX_PARTITIONS;
+        DALI_LOG_WARNING( "Value for slices clamped.\n" );
       }
       else if ( mSlices < MIN_SLICES )
       {
         mSlices = MIN_SLICES;
+        DALI_LOG_WARNING( "Value for slices clamped.\n" );
       }
     }
     else
@@ -237,7 +247,7 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
     }
   }
 
-  Property::Value* stacks = propertyMap.Find( STACKS );
+  Property::Value* stacks = propertyMap.Find( Toolkit::PrimitiveVisual::Property::STACKS, STACKS );
   if( stacks )
   {
     if( stacks->Get( mStacks ) )
@@ -246,10 +256,12 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
       if( mStacks > MAX_PARTITIONS )
       {
         mStacks = MAX_PARTITIONS;
+        DALI_LOG_WARNING( "Value for stacks clamped.\n" );
       }
       else if ( mStacks < MIN_STACKS )
       {
         mStacks = MIN_STACKS;
+        DALI_LOG_WARNING( "Value for stacks clamped.\n" );
       }
     }
     else
@@ -258,31 +270,31 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
     }
   }
 
-  Property::Value* scaleTop = propertyMap.Find( SCALE_TOP_RADIUS );
+  Property::Value* scaleTop = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SCALE_TOP_RADIUS, SCALE_TOP_RADIUS );
   if( scaleTop && !scaleTop->Get( mScaleTopRadius ) )
   {
     DALI_LOG_ERROR( "Invalid type for scale top radius in PrimitiveVisual.\n" );
   }
 
-  Property::Value* scaleBottom = propertyMap.Find( SCALE_BOTTOM_RADIUS );
+  Property::Value* scaleBottom = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, SCALE_BOTTOM_RADIUS );
   if( scaleBottom && !scaleBottom->Get( mScaleBottomRadius ) )
   {
     DALI_LOG_ERROR( "Invalid type for scale bottom radius in PrimitiveVisual.\n" );
   }
 
-  Property::Value* scaleHeight = propertyMap.Find( SCALE_HEIGHT );
+  Property::Value* scaleHeight = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SCALE_HEIGHT, SCALE_HEIGHT );
   if( scaleHeight && !scaleHeight->Get( mScaleHeight ) )
   {
     DALI_LOG_ERROR( "Invalid type for scale height in PrimitiveVisual.\n" );
   }
 
-  Property::Value* scaleRadius = propertyMap.Find( SCALE_RADIUS );
+  Property::Value* scaleRadius = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SCALE_RADIUS, SCALE_RADIUS );
   if( scaleRadius && !scaleRadius->Get( mScaleRadius ) )
   {
     DALI_LOG_ERROR( "Invalid type for scale radius in PrimitiveVisual.\n" );
   }
 
-  Property::Value* dimensions = propertyMap.Find( SCALE_DIMENSIONS );
+  Property::Value* dimensions = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SCALE_DIMENSIONS, SCALE_DIMENSIONS );
   if( dimensions )
   {
     if( dimensions->Get( mScaleDimensions ) )
@@ -291,14 +303,17 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
       if( mScaleDimensions.x <= 0.0 )
       {
         mScaleDimensions.x = 1.0;
+        DALI_LOG_WARNING( "Value for scale dimensions clamped. Must be greater than zero.\n" );
       }
       if( mScaleDimensions.y <= 0.0 )
       {
         mScaleDimensions.y = 1.0;
+        DALI_LOG_WARNING( "Value for scale dimensions clamped. Must be greater than zero.\n" );
       }
       if( mScaleDimensions.z <= 0.0 )
       {
         mScaleDimensions.z = 1.0;
+        DALI_LOG_WARNING( "Value for scale dimensions clamped. Must be greater than zero.\n" );
       }
     }
     else
@@ -307,7 +322,7 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
     }
   }
 
-  Property::Value* bevel = propertyMap.Find( BEVEL_PERCENTAGE );
+  Property::Value* bevel = propertyMap.Find( Toolkit::PrimitiveVisual::Property::BEVEL_PERCENTAGE, BEVEL_PERCENTAGE );
   if( bevel )
   {
     if( bevel->Get( mBevelPercentage ) )
@@ -316,10 +331,12 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
       if( mBevelPercentage < MIN_BEVEL_PERCENTAGE )
       {
         mBevelPercentage = MIN_BEVEL_PERCENTAGE;
+        DALI_LOG_WARNING( "Value for bevel percentage clamped.\n" );
       }
       else if( mBevelPercentage > MAX_BEVEL_PERCENTAGE )
       {
         mBevelPercentage = MAX_BEVEL_PERCENTAGE;
+        DALI_LOG_WARNING( "Value for bevel percentage clamped.\n" );
       }
     }
     else
@@ -328,7 +345,7 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
     }
   }
 
-  Property::Value* smoothness = propertyMap.Find( BEVEL_SMOOTHNESS );
+  Property::Value* smoothness = propertyMap.Find( Toolkit::PrimitiveVisual::Property::BEVEL_SMOOTHNESS, BEVEL_SMOOTHNESS );
   if( smoothness )
   {
     if( smoothness->Get( mBevelSmoothness ) )
@@ -337,10 +354,12 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
       if( mBevelSmoothness < MIN_SMOOTHNESS )
       {
         mBevelSmoothness = MIN_SMOOTHNESS;
+        DALI_LOG_WARNING( "Value for bevel smoothness clamped.\n" );
       }
       else if( mBevelSmoothness > MAX_SMOOTHNESS )
       {
         mBevelSmoothness = MAX_SMOOTHNESS;
+        DALI_LOG_WARNING( "Value for bevel smoothness clamped.\n" );
       }
     }
     else
@@ -350,7 +369,7 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
   }
 
   //Read in light position.
-  Property::Value* lightPosition = propertyMap.Find( LIGHT_POSITION_UNIFORM_NAME );
+  Property::Value* lightPosition = propertyMap.Find( Toolkit::PrimitiveVisual::Property::LIGHT_POSITION, LIGHT_POSITION_UNIFORM_NAME );
   if( lightPosition )
   {
     if( !lightPosition->Get( mLightPosition ) )
@@ -369,46 +388,43 @@ void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyM
   }
 }
 
-void PrimitiveVisual::SetSize( const Vector2& size )
+void PrimitiveVisual::GetNaturalSize( Vector2& naturalSize )
 {
-  Visual::Base::SetSize( size );
-
-  // ToDo: renderer responds to the size change
-}
-
-void PrimitiveVisual::SetClipRect( const Rect<int>& clipRect )
-{
-  Visual::Base::SetClipRect( clipRect );
-
-  //ToDo: renderer responds to the clipRect change
-}
-
-void PrimitiveVisual::SetOffset( const Vector2& offset )
-{
-  //ToDo: renderer applies the offset
+  naturalSize.x = mObjectDimensions.x;
+  naturalSize.y = mObjectDimensions.y;
 }
 
 void PrimitiveVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void PrimitiveVisual::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 );
+  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::Visual::PRIMITIVE );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SHAPE, mPrimitiveType );
+  map.Insert( Toolkit::PrimitiveVisual::Property::MIX_COLOR, mColor );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SLICES, mSlices );
+  map.Insert( Toolkit::PrimitiveVisual::Property::STACKS, mStacks );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SCALE_TOP_RADIUS, mScaleTopRadius );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SCALE_BOTTOM_RADIUS, mScaleBottomRadius );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SCALE_HEIGHT, mScaleHeight );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SCALE_RADIUS, mScaleRadius );
+  map.Insert( Toolkit::PrimitiveVisual::Property::SCALE_DIMENSIONS, mScaleDimensions );
+  map.Insert( Toolkit::PrimitiveVisual::Property::BEVEL_PERCENTAGE, mBevelPercentage );
+  map.Insert( Toolkit::PrimitiveVisual::Property::BEVEL_SMOOTHNESS, mBevelSmoothness );
+  map.Insert( Toolkit::PrimitiveVisual::Property::LIGHT_POSITION, mLightPosition );
+}
+
+void PrimitiveVisual::OnSetTransform()
+{
+  if( mImpl->mRenderer )
+  {
+    mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+  }
 }
 
 void PrimitiveVisual::InitializeRenderer()
@@ -424,6 +440,10 @@ void PrimitiveVisual::InitializeRenderer()
   }
 
   mImpl->mRenderer = Renderer::New( mGeometry, mShader );
+  mImpl->mRenderer.SetProperty( Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK );
+
+  //Register transform properties
+  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
 }
 
 void PrimitiveVisual::UpdateShaderUniforms()
@@ -439,7 +459,7 @@ void PrimitiveVisual::UpdateShaderUniforms()
   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 );
+  DevelHandle::RegisterProperty( mShader, Toolkit::PrimitiveVisual::Property::MIX_COLOR, COLOR_UNIFORM_NAME, mColor );
   mShader.RegisterProperty( OBJECT_DIMENSIONS_UNIFORM_NAME, mObjectDimensions );
 }
 
@@ -456,41 +476,41 @@ void PrimitiveVisual::CreateGeometry()
 
   switch( mPrimitiveType )
   {
-    case SPHERE:
+    case Toolkit::PrimitiveVisual::Shape::SPHERE:
     {
       CreateSphere( vertices, indices, mSlices, mStacks );
       break;
     }
-    case CONE:
+    case Toolkit::PrimitiveVisual::Shape::CONE:
     {
       //Create a conic with zero top radius.
       CreateConic( vertices, indices, 0, mScaleBottomRadius, mScaleHeight, mSlices );
       break;
     }
-    case CONICAL_FRUSTRUM:
+    case Toolkit::PrimitiveVisual::Shape::CONICAL_FRUSTRUM:
     {
       CreateConic( vertices, indices, mScaleTopRadius, mScaleBottomRadius, mScaleHeight, mSlices );
       break;
     }
-    case CYLINDER:
+    case Toolkit::PrimitiveVisual::Shape::CYLINDER:
     {
       //Create a conic with equal radii on the top and bottom.
       CreateConic( vertices, indices, mScaleRadius, mScaleRadius, mScaleHeight, mSlices );
       break;
     }
-    case CUBE:
+    case Toolkit::PrimitiveVisual::Shape::CUBE:
     {
       //Create a cube by creating a bevelled cube with minimum bevel.
       CreateBevelledCube( vertices, indices, mScaleDimensions, 0.0, 0.0 );
       break;
     }
-    case OCTAHEDRON:
+    case Toolkit::PrimitiveVisual::Shape::OCTAHEDRON:
     {
       //Create an octahedron by creating a bevelled cube with maximum bevel.
       CreateBevelledCube( vertices, indices, mScaleDimensions, 1.0, mBevelSmoothness );
       break;
     }
-    case BEVELLED_CUBE:
+    case Toolkit::PrimitiveVisual::Shape::BEVELLED_CUBE:
     {
       CreateBevelledCube( vertices, indices, mScaleDimensions, mBevelPercentage, mBevelSmoothness );
       break;
@@ -538,7 +558,8 @@ void PrimitiveVisual::CreateConic( Vector<Vertex>& vertices, Vector<unsigned sho
 void PrimitiveVisual::CreateBevelledCube( Vector<Vertex>& vertices, Vector<unsigned short>& indices,
                                             Vector3 dimensions, float bevelPercentage, float bevelSmoothness )
 {
-  dimensions.Normalize();
+  float maxDimension = std::max( std::max( dimensions.x, dimensions.y ), dimensions.z );
+  dimensions = dimensions / maxDimension;
 
   if( bevelPercentage <= MIN_BEVEL_PERCENTAGE ) //No bevel, form a cube.
   {
@@ -644,16 +665,16 @@ void PrimitiveVisual::FormSphereTriangles( Vector<unsigned short>& indices, int
   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;
+      indices[indiceIndex + 1] = 1;
     }
     else
     {
-      indices[indiceIndex + 2] = i + 1;
+      indices[indiceIndex + 1] = i + 1;
     }
+    indices[indiceIndex + 2] = i;
   }
 
   //Middle Stacks. Want to form triangles between the top and bottom stacks, so loop up to the number of stacks - 2.
@@ -665,20 +686,20 @@ void PrimitiveVisual::FormSphereTriangles( Vector<unsigned short>& indices, int
       {
         //End, so loop around.
         indices[indiceIndex] =     previousCycleBeginning + j;
-        indices[indiceIndex + 1] = currentCycleBeginning + j;
-        indices[indiceIndex + 2] = previousCycleBeginning;
+        indices[indiceIndex + 1] = previousCycleBeginning;
+        indices[indiceIndex + 2] = currentCycleBeginning + j;
         indices[indiceIndex + 3] = currentCycleBeginning + j;
-        indices[indiceIndex + 4] = currentCycleBeginning;
-        indices[indiceIndex + 5] = previousCycleBeginning;
+        indices[indiceIndex + 4] = previousCycleBeginning;
+        indices[indiceIndex + 5] = currentCycleBeginning;
       }
       else
       {
         indices[indiceIndex] =     previousCycleBeginning + j;
-        indices[indiceIndex + 1] = currentCycleBeginning + j;
-        indices[indiceIndex + 2] = previousCycleBeginning + 1 + j;
+        indices[indiceIndex + 1] = previousCycleBeginning + 1 + j;
+        indices[indiceIndex + 2] = currentCycleBeginning + j;
         indices[indiceIndex + 3] = currentCycleBeginning + j;
-        indices[indiceIndex + 4] = currentCycleBeginning + 1 + j;
-        indices[indiceIndex + 5] = previousCycleBeginning + 1 + j;
+        indices[indiceIndex + 4] = previousCycleBeginning + 1 + j;
+        indices[indiceIndex + 5] = currentCycleBeginning + 1 + j;
       }
     }
   }
@@ -866,16 +887,16 @@ void PrimitiveVisual::FormConicTriangles( Vector<unsigned short>& indices, float
     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;
+        indices[indiceIndex + 1] = bottomFaceCycleBeginning;
       }
       else
       {
-        indices[indiceIndex + 2] = bottomFaceCycleBeginning + i + 1;
+        indices[indiceIndex + 1] = bottomFaceCycleBeginning + i + 1;
       }
+      indices[indiceIndex + 2] = bottomFaceCycleBeginning + i;
     }
   }
   else if( !coneTop || !coneBottom )
@@ -900,16 +921,16 @@ void PrimitiveVisual::FormConicTriangles( Vector<unsigned short>& indices, float
     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;
+        indices[indiceIndex + 1] = slices + 1;
       }
       else
       {
-        indices[indiceIndex + 2] = slices + i + 1;
+        indices[indiceIndex + 1] = slices + i + 1;
       }
+      indices[indiceIndex + 2] = slices + i;
     }
   }
 }
@@ -1006,11 +1027,11 @@ void PrimitiveVisual::FormCubeTriangles( Vector<unsigned short>& indices )
 
   //Top face.
   indices[triangleIndex] =     0;
-  indices[triangleIndex + 1] = 1;
-  indices[triangleIndex + 2] = 2;
+  indices[triangleIndex + 1] = 2;
+  indices[triangleIndex + 2] = 1;
   indices[triangleIndex + 3] = 2;
-  indices[triangleIndex + 4] = 3;
-  indices[triangleIndex + 5] = 0;
+  indices[triangleIndex + 4] = 0;
+  indices[triangleIndex + 5] = 3;
   triangleIndex += 6;
 
   int topFaceStart = 4;
@@ -1020,11 +1041,11 @@ void PrimitiveVisual::FormCubeTriangles( Vector<unsigned short>& indices )
   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 + 1] = i + topFaceStart + 1;
+    indices[triangleIndex + 2] = i + bottomFaceStart + 1;
     indices[triangleIndex + 3] = i + topFaceStart;
-    indices[triangleIndex + 4] = i + bottomFaceStart;
-    indices[triangleIndex + 5] = i + bottomFaceStart + 1;
+    indices[triangleIndex + 4] = i + bottomFaceStart + 1;
+    indices[triangleIndex + 5] = i + bottomFaceStart;
   }
 
   //Bottom face.
@@ -1084,19 +1105,19 @@ void PrimitiveVisual::ComputeOctahedronVertices( Vector<Vertex>& vertices, Vecto
       //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);
+      vertices[vertexIndex + 1].position = positions[1];
+      vertices[vertexIndex + 1].normal = outerNormals[1] * smoothness + normals[i] * (1 - smoothness);
+      vertices[vertexIndex + 2].position = positions[i + 1];
+      vertices[vertexIndex + 2].normal = outerNormals[i + 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);
+      vertices[vertexIndex + 1].position = positions[i + 2];
+      vertices[vertexIndex + 1].normal = outerNormals[i + 2] * smoothness + normals[i] * (1 - smoothness);
+      vertices[vertexIndex + 2].position = positions[i + 1];
+      vertices[vertexIndex + 2].normal = outerNormals[i + 1] * smoothness + normals[i] * (1 - smoothness);
     }
   }
 
@@ -1149,16 +1170,17 @@ void PrimitiveVisual::ComputeBevelledCubeVertices( Vector<Vertex>& vertices, Vec
   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 bevelAmount = 0.5 * std::min( bevelPercentage, minDimension ); //Cap bevel amount if necessary.
 
+  //Distances from centre to outer edge points.
   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 );
+  //Distances from centre to bevelled points.
+  float bevelX = outerX - bevelAmount;
+  float bevelY = outerY - bevelAmount;
+  float bevelZ = outerZ - bevelAmount;
 
   Vector<Vector3> positions;  //Holds object points, to be shared between vertexes.
   positions.Resize( numPositions );
@@ -1392,11 +1414,11 @@ void PrimitiveVisual::FormBevelledCubeTriangles( Vector<unsigned short>& indices
 
   //Top face.
   indices[indiceIndex    ] = vertexIndex;
-  indices[indiceIndex + 1] = vertexIndex + 1;
-  indices[indiceIndex + 2] = vertexIndex + 2;
+  indices[indiceIndex + 1] = vertexIndex + 2;
+  indices[indiceIndex + 2] = vertexIndex + 1;
   indices[indiceIndex + 3] = vertexIndex + 0;
-  indices[indiceIndex + 4] = vertexIndex + 2;
-  indices[indiceIndex + 5] = vertexIndex + 3;
+  indices[indiceIndex + 4] = vertexIndex + 3;
+  indices[indiceIndex + 5] = vertexIndex + 2;
   indiceIndex += 6;
   vertexIndex += 4;
 
@@ -1405,16 +1427,16 @@ void PrimitiveVisual::FormBevelledCubeTriangles( Vector<unsigned short>& indices
   {
     //Triangle part.
     indices[indiceIndex    ] = vertexIndex;
-    indices[indiceIndex + 1] = vertexIndex + 1;
-    indices[indiceIndex + 2] = vertexIndex + 2;
+    indices[indiceIndex + 1] = vertexIndex + 2;
+    indices[indiceIndex + 2] = vertexIndex + 1;
 
     //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;
+    indices[indiceIndex + 7] = vertexIndex + 6;
+    indices[indiceIndex + 8] = vertexIndex + 5;
   }
 
   //Side faces.
@@ -1424,8 +1446,8 @@ void PrimitiveVisual::FormBevelledCubeTriangles( Vector<unsigned short>& indices
     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;
+    indices[indiceIndex + 4] = vertexIndex + 3;
+    indices[indiceIndex + 5] = vertexIndex + 2;
   }
 
   //Bottom slopes.
@@ -1441,8 +1463,8 @@ void PrimitiveVisual::FormBevelledCubeTriangles( Vector<unsigned short>& indices
     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;
+    indices[indiceIndex + 7] = vertexIndex + 6;
+    indices[indiceIndex + 8] = vertexIndex + 5;
   }
 
   //Bottom face.