* @param[in] buffer The current render buffer index (previous update buffer)
* @param[in] viewMatrix The view matrix from the appropriate camera.
* @param[in] projectionMatrix The projection matrix from the appropriate camera.
- * @param[in] cullMode True if the renderers should be subjected to clipspace culling
*/
inline void ProcessRenderList(
const RenderList& renderList,
SceneGraph::Shader& defaultShader,
BufferIndex bufferIndex,
const Matrix& viewMatrix,
- const Matrix& projectionMatrix,
- bool cullMode )
+ const Matrix& projectionMatrix )
{
DALI_PRINT_RENDER_LIST( renderList );
//Enable depth writes if depth buffer is enabled and item is opaque
context.DepthMask( depthBufferEnabled && ( item.IsOpaque() || item.GetRenderer().RequiresDepthTest() ) );
- item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, cullMode, !item.IsOpaque() );
+ item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, !item.IsOpaque() );
}
}
else
const RenderItem& item = renderList.GetItem( index );
DALI_PRINT_RENDER_ITEM( item );
- item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, cullMode, !item.IsOpaque() );
+ item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, !item.IsOpaque() );
}
}
if( renderList &&
!renderList->IsEmpty() )
{
- ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix, instruction.mCullMode );
+ ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix );
}
}
}
mClearColor(),
mIsViewportSet( false ),
mIsClearColorSet( false ),
- mCullMode(false),
mOffscreenTextureId( 0 ),
mCameraAttachment( 0 ),
mNextFreeRenderList( 0 )
mIsViewportSet = NULL != viewport;
mClearColor = clearColor ? *clearColor : Color::BLACK;
mIsClearColorSet = NULL != clearColor;
- mCullMode = false;
mOffscreenTextureId = offscreenTextureId;
mRenderTracker = NULL;
mNextFreeRenderList = 0;
Vector4 mClearColor; ///< Optional color to clear with
bool mIsViewportSet:1; ///< Flag to determine whether the viewport is set
bool mIsClearColorSet:1; ///< Flag to determine whether the clearColor is set
- bool mCullMode:1; ///< True if renderers should be frustum culled
unsigned int mOffscreenTextureId; ///< Optional offscreen target
const Matrix& modelViewMatrix,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
- bool cull,
bool blend )
{
// Get the program to use:
* @param[in] modelViewMatrix The model-view matrix.
* @param[in] viewMatrix The view matrix.
* @param[in] projectionMatrix The projection matrix.
- * @param[in] cull Whether to frustum cull this renderer
*/
void Render( Context& context,
SceneGraph::TextureCache& textureCache,
const Matrix& modelViewMatrix,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
- bool cull,
bool blend);
/**
* @param viewMatrix used to calculate modelview matrix for the item
* @param cameraAttachment The camera used to render
* @param isLayer3d Whether we are processing a 3D layer or not
+ * @param cull Whether frustum culling is enabled or not
*/
inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
RenderList& renderList,
Renderable& renderable,
const Matrix& viewMatrix,
SceneGraph::CameraAttachment& cameraAttachment,
- bool isLayer3d )
+ bool isLayer3d,
+ bool cull )
{
- // Check for cull against view frustum
- const Matrix& worldMatrix = renderable.mNode->GetWorldMatrix( updateBufferIndex );
- bool inside = true;
+ bool inside( true );
- if ( renderable.mRenderer->GetMaterial().GetShader()->GeometryHintEnabled( Dali::ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY ) )
+ const Matrix& worldMatrix = renderable.mNode->GetWorldMatrix( updateBufferIndex );
+ if ( cull && renderable.mRenderer->GetMaterial().GetShader()->GeometryHintEnabled( Dali::ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY ) )
{
const Vector3& position = worldMatrix.GetTranslation3();
const Vector3& scale = renderable.mNode->GetScale( updateBufferIndex );
const Vector3& halfSize = renderable.mNode->GetSize( updateBufferIndex ) * scale * 0.5f;
+ float radius( halfSize.Length() );
+
+ inside = (radius > Math::MACHINE_EPSILON_1000) &&
+ (cameraAttachment.CheckAABBInFrustum( updateBufferIndex, position, halfSize) );
- // Do a fast sphere check
- if ( cameraAttachment.CheckSphereInFrustum( updateBufferIndex, position, halfSize.Length() ) )
- {
- // Check geometry AABB
- //TODO: Take into account orientation
- if ( !cameraAttachment.CheckAABBInFrustum( updateBufferIndex, position, halfSize ) )
- {
- inside = false;
- }
- }
- else
- {
- inside = false;
- }
}
if ( inside )
{
- // Get the next free RenderItem
- RenderItem& item = renderList.GetNextFreeItem();
- item.SetRenderer( &renderable.mRenderer->GetRenderer() );
- item.SetNode( renderable.mNode );
- item.SetIsOpaque( renderable.mRenderer->IsFullyOpaque(updateBufferIndex, *renderable.mNode ) );
-
- if( isLayer3d )
+ Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode );
+ if( opacity != Renderer::TRANSPARENT )
{
- item.SetDepthIndex( renderable.mRenderer->GetDepthIndex() );
- }
- else
- {
- item.SetDepthIndex( renderable.mRenderer->GetDepthIndex() + static_cast<int>( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER );
- }
+ // Get the next free RenderItem
+ RenderItem& item = renderList.GetNextFreeItem();
+ item.SetRenderer( &renderable.mRenderer->GetRenderer() );
+ item.SetNode( renderable.mNode );
+ item.SetIsOpaque( opacity == Renderer::OPAQUE );
- // save MV matrix onto the item
- Matrix::Multiply( item.GetModelViewMatrix(), worldMatrix, viewMatrix );
+ if( isLayer3d )
+ {
+ item.SetDepthIndex( renderable.mRenderer->GetDepthIndex() );
+ }
+ else
+ {
+ item.SetDepthIndex( renderable.mRenderer->GetDepthIndex() + static_cast<int>( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER );
+ }
+ // save MV matrix onto the item
+ Matrix::Multiply( item.GetModelViewMatrix(), worldMatrix, viewMatrix );
+ }
}
}
* @param viewMatrix used to calculate modelview matrix for the items
* @param cameraAttachment The camera used to render
* @param isLayer3d Whether we are processing a 3D layer or not
+ * @param cull Whether frustum culling is enabled or not
*/
inline void AddRenderersToRenderList( BufferIndex updateBufferIndex,
RenderList& renderList,
RenderableContainer& renderables,
const Matrix& viewMatrix,
SceneGraph::CameraAttachment& cameraAttachment,
- bool isLayer3d )
+ bool isLayer3d,
+ bool cull)
{
DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n");
unsigned int rendererCount( renderables.Size() );
for( unsigned int i(0); i<rendererCount; ++i )
{
- AddRendererToRenderList( updateBufferIndex, renderList, renderables[i], viewMatrix, cameraAttachment, isLayer3d );
+ AddRendererToRenderList( updateBufferIndex, renderList, renderables[i], viewMatrix, cameraAttachment, isLayer3d, cull );
}
}
* @param instruction to fill in
* @param sortingHelper to use for sorting the renderitems (to avoid reallocating)
* @param tryReuseRenderList whether to try to reuse the cached items from the instruction
+ * @param cull Whether frustum culling is enabled or not
*/
inline void AddColorRenderers( BufferIndex updateBufferIndex,
Layer& layer,
bool stencilRenderablesExist,
RenderInstruction& instruction,
RendererSortingHelper& sortingHelper,
- bool tryReuseRenderList )
+ bool tryReuseRenderList,
+ bool cull)
{
RenderList& renderList = instruction.GetNextFreeRenderList( layer.colorRenderables.Size() );
renderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
}
}
- AddRenderersToRenderList( updateBufferIndex, renderList, layer.colorRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D );
+ AddRenderersToRenderList( updateBufferIndex, renderList, layer.colorRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
SortColorRenderItems( updateBufferIndex, renderList, layer, sortingHelper );
//Set render flags
* @param stencilRenderablesExist is true if there are stencil renderers on this layer
* @param instruction to fill in
* @param tryReuseRenderList whether to try to reuse the cached items from the instruction
+ * @param cull Whether frustum culling is enabled or not
*/
inline void AddOverlayRenderers( BufferIndex updateBufferIndex,
Layer& layer,
SceneGraph::CameraAttachment& cameraAttachment,
bool stencilRenderablesExist,
RenderInstruction& instruction,
- bool tryReuseRenderList )
+ bool tryReuseRenderList,
+ bool cull )
{
RenderList& overlayRenderList = instruction.GetNextFreeRenderList( layer.overlayRenderables.Size() );
overlayRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
return;
}
}
- AddRenderersToRenderList( updateBufferIndex, overlayRenderList, layer.overlayRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D );
+ AddRenderersToRenderList( updateBufferIndex, overlayRenderList, layer.overlayRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
}
/**
* @param viewmatrix for the camera from rendertask
* @param instruction to fill in
* @param tryReuseRenderList whether to try to reuse the cached items from the instruction
+ * @param cull Whether frustum culling is enabled or not
*/
inline void AddStencilRenderers( BufferIndex updateBufferIndex,
Layer& layer,
const Matrix& viewMatrix,
SceneGraph::CameraAttachment& cameraAttachment,
RenderInstruction& instruction,
- bool tryReuseRenderList )
+ bool tryReuseRenderList,
+ bool cull )
{
RenderList& stencilRenderList = instruction.GetNextFreeRenderList( layer.stencilRenderables.Size() );
stencilRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
return;
}
}
- AddRenderersToRenderList( updateBufferIndex, stencilRenderList, layer.stencilRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D );
+ AddRenderersToRenderList( updateBufferIndex, stencilRenderList, layer.stencilRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
}
-/**
- * Prepare a single render instruction
- * @param updateBufferIndex to use
- * @param sortedLayers to prepare the instruction from
- * @param renderTask to get the view matrix
- * @param sortingHelper to use for sorting the renderitems (to avoid reallocating)
- * @param instructions container
- */
void PrepareRenderInstruction( BufferIndex updateBufferIndex,
SortedLayerPointers& sortedLayers,
RenderTask& renderTask,
RendererSortingHelper& sortingHelper,
+ bool cull,
RenderInstructionContainer& instructions )
{
// Retrieve the RenderInstruction buffer from the RenderInstructionContainer
if( stencilRenderablesExist &&
( colorRenderablesExist || overlayRenderablesExist ) )
{
- AddStencilRenderers( updateBufferIndex, layer, viewMatrix, cameraAttachment, instruction, tryReuseRenderList );
+ AddStencilRenderers( updateBufferIndex, layer, viewMatrix, cameraAttachment, instruction, tryReuseRenderList, cull );
}
if ( colorRenderablesExist )
stencilRenderablesExist,
instruction,
sortingHelper,
- tryReuseRenderList );
+ tryReuseRenderList,
+ cull );
}
if ( overlayRenderablesExist )
{
AddOverlayRenderers( updateBufferIndex, layer, viewMatrix, cameraAttachment, stencilRenderablesExist,
- instruction, tryReuseRenderList );
+ instruction, tryReuseRenderList, cull );
}
}
- instruction.mCullMode = renderTask.GetCullMode();
-
// inform the render instruction that all renderers have been added and this frame is complete
instruction.UpdateCompleted();
}
* @param[in] sortedLayers The layers containing lists of opaque/transparent renderables.
* @param[in] renderTask The rendering task information.
* @param[in] sortingHelper to avoid allocating containers for sorting every frame
+ * @param[in] cull Whether frustum culling is enabled or not
* @param[out] instructions The rendering instructions for the next frame.
*/
void PrepareRenderInstruction( BufferIndex updateBufferIndex,
SortedLayerPointers& sortedLayers,
RenderTask& renderTask,
RendererSortingHelper& sortingHelper,
+ bool cull,
RenderInstructionContainer& instructions );
} // namespace SceneGraph
inheritedDrawMode |= node.GetDrawMode();
- if( node.ResolveVisibility( updateBufferIndex ) )
+ const unsigned int count = node.GetRendererCount();
+ for( unsigned int i = 0; i < count; ++i )
{
- const unsigned int count = node.GetRendererCount();
- for( unsigned int i = 0; i < count; ++i )
- {
- SceneGraph::Renderer* renderer = node.GetRendererAt( i );
- bool ready = false;
- bool complete = false;
- renderer->GetReadyAndComplete( ready, complete );
+ SceneGraph::Renderer* renderer = node.GetRendererAt( i );
+ bool ready = false;
+ bool complete = false;
+ renderer->GetReadyAndComplete( ready, complete );
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready?"T":"F", complete?"T":"F");
+ DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready?"T":"F", complete?"T":"F");
- resourcesFinished &= complete;
+ resourcesFinished &= complete;
- if( ready ) // i.e. should be rendered (all resources are available)
+ if( ready ) // i.e. should be rendered (all resources are available)
+ {
+ if( DrawMode::STENCIL == inheritedDrawMode )
+ {
+ layer->stencilRenderables.PushBack( Renderable(&node, renderer ) );
+ }
+ else if( DrawMode::OVERLAY_2D == inheritedDrawMode )
{
- if( DrawMode::STENCIL == inheritedDrawMode )
- {
- layer->stencilRenderables.PushBack( Renderable(&node, renderer ) );
- }
- else if( DrawMode::OVERLAY_2D == inheritedDrawMode )
- {
- layer->overlayRenderables.PushBack( Renderable(&node, renderer ) );
- }
- else
- {
- layer->colorRenderables.PushBack( Renderable(&node, renderer ) );
- }
+ layer->overlayRenderables.PushBack( Renderable(&node, renderer ) );
+ }
+ else
+ {
+ layer->colorRenderables.PushBack( Renderable(&node, renderer ) );
}
}
}
+
// Recurse children
NodeContainer& children = node.GetChildren();
const NodeIter endIter = children.End();
sortedLayers,
renderTask,
sortingHelper,
+ renderTask.GetCullMode(),
instructions );
}
sortedLayers,
renderTask,
sortingHelper,
+ renderTask.GetCullMode(),
instructions );
}
#include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
// INTERNAL HEADERS
-#include <dali/public-api/common/dali-common.h>
-#include <dali/internal/update/nodes/node.h>
+#include <dali/integration-api/debug.h>
#include <dali/internal/update/controllers/scene-controller.h>
+#include <dali/internal/update/nodes/node.h>
#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/math/math-utils.h>
namespace // unnamed namespace
{
float l = 1.0f / plane.mNormal.Length();
plane.mNormal *= l;
plane.mDistance *= l;
+
+ planes.mSign[i] = Vector3( Sign(plane.mNormal.x), Sign(plane.mNormal.y), Sign(plane.mNormal.z) );
+ }
+ }
+ else
+ {
+ for ( unsigned int i = 0; i < 6; ++i )
+ {
+ planes.mSign[i] = Vector3( Sign(planes.mPlanes[ i ].mNormal.x), Sign(planes.mPlanes[ i ].mNormal.y), Sign(planes.mPlanes[ i ].mNormal.z) );
}
}
mFrustum[ updateBufferIndex ? 0 : 1 ] = planes;
bool CameraAttachment::CheckAABBInFrustum( BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents )
{
const FrustumPlanes& planes = mFrustum[ bufferIndex ];
- Vector3 tln = origin + Vector3( -halfExtents );
- Vector3 trn = origin + Vector3( halfExtents.x, -halfExtents.y, -halfExtents.z );
- Vector3 bln = origin + Vector3( -halfExtents.x, halfExtents.y, -halfExtents.z );
- Vector3 brn = origin + Vector3( halfExtents.x, halfExtents.y, -halfExtents.z );
- Vector3 tlf = origin + Vector3( -halfExtents.x, -halfExtents.y, halfExtents.z );
- Vector3 trf = origin + Vector3( halfExtents.x, -halfExtents.y, halfExtents.z );
- Vector3 blf = origin + Vector3( -halfExtents.x, halfExtents.y, halfExtents.z );
- Vector3 brf = origin + Vector3( halfExtents.x, halfExtents.y, halfExtents.z );
-
for ( uint32_t i = 0; i < 6; ++i )
{
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( tln ) >= 0 )
- {
- continue;
- }
-
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( trn ) >= 0 )
- {
- continue;
- }
-
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( bln ) >= 0 )
- {
- continue;
- }
-
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( brn ) >= 0 )
- {
- continue;
- }
-
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( tlf ) >= 0 )
- {
- continue;
- }
-
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( trf ) >= 0 )
- {
- continue;
- }
-
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( blf ) >= 0 )
+ if( planes.mPlanes[ i ].mNormal.Dot( origin + (halfExtents * planes.mSign[i]) ) > -(planes.mPlanes[ i ].mDistance) )
{
continue;
}
- if ( planes.mPlanes[ i ].mDistance + planes.mPlanes[ i ].mNormal.Dot( brf ) >= 0 )
- {
- continue;
- }
return false;
}
return true;
struct FrustumPlanes
{
Plane mPlanes[ 6 ];
+ Vector3 mSign[ 6 ];
};
/**
*
* @param bufferIndex The buffer to read from.
* @param origin the world position center of the cubeoid to check.
- * @param extents The half length of the cubeoid in world co-ordinates in each axis.
+ * @param halfExtents The half length of the cubeoid in world co-ordinates in each axis.
*
- * @return false if the cubeoid lies outside of the frustum.
+ * @return false if the cubeoid lies completely outside of the frustum, true otherwise
*/
- bool CheckAABBInFrustum( BufferIndex bufferIndex, const Vector3& origin, const Vector3& extents );
+ bool CheckAABBInFrustum( BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents );
/**
* Retrieve the projection-matrix; this is double buffered for input handling.
}
case BlendingMode::ON:
{
- mBlendPolicy = TRANSPARENT;
+ mBlendPolicy = TRANSLUCENT;
break;
}
case BlendingMode::AUTO:
if( ( opaqueCount != textureCount ) ||
( mShader && mShader->GeometryHintEnabled( Dali::ShaderEffect::HINT_BLENDING ) ) )
{
- mBlendPolicy = Material::TRANSPARENT;
+ mBlendPolicy = Material::TRANSLUCENT;
}
else
{
*/
enum BlendPolicy
{
- OPAQUE, ///< If the renderer should always be opaque
- TRANSPARENT, ///< If the renderer should always be transparent
+ OPAQUE, ///< If the renderer should never use blending
+ TRANSLUCENT, ///< If the renderer should always be use blending
USE_ACTOR_COLOR ///< If the renderer should determine opacity using the actor color
};
complete = mFinishedResourceAcquisition;
}
-// Called by ProcessRenderTasks after DoPrepareRender
-bool Renderer::IsFullyOpaque( BufferIndex updateBufferIndex, const Node& node ) const
+Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const
{
- bool opaque = false;
+ Renderer::Opacity opacity = Renderer::OPAQUE;
- if( mMaterial != NULL )
+ if( mMaterial )
{
- Material::BlendPolicy blendPolicy = mMaterial->GetBlendPolicy();
- switch( blendPolicy )
+ if( mMaterial->GetBlendPolicy() == Material::TRANSLUCENT )
{
- case Material::OPAQUE:
- {
- opaque = true;
- break;
- }
- case Material::TRANSPARENT:
+ opacity = Renderer::TRANSLUCENT;
+ }
+ else if( mMaterial->GetBlendPolicy() == Material::USE_ACTOR_COLOR )
+ {
+ float alpha = node.GetWorldColor( updateBufferIndex ).a;
+ if( alpha <= FULLY_TRANSPARENT )
{
- opaque = false;
- break;
+ opacity = TRANSPARENT;
}
- case Material::USE_ACTOR_COLOR:
+ else if( alpha <= FULLY_OPAQUE )
{
- opaque = node.GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE;
- break;
+ opacity = TRANSLUCENT;
}
}
}
- return opaque;
+ return opacity;
}
void Renderer::ConnectionsChanged( PropertyOwner& object )
{
public:
+ enum Opacity
+ {
+ OPAQUE,
+ TRANSPARENT,
+ TRANSLUCENT
+ };
+
/**
* Default constructor
*/
void GetReadyAndComplete( bool& ready, bool& complete ) const;
/**
- * Query whether the renderer is fully opaque.
+ * Query whether the renderer is fully opaque, fully transparent or transparent.
* @param[in] updateBufferIndex The current update buffer index.
- * @return True if fully opaque.
+ * @return OPAQUE if fully opaque, TRANSPARENT if fully transparent and TRANSLUCENT if in between
*/
- bool IsFullyOpaque( BufferIndex updateBufferIndex, const Node& node ) const;
+ Opacity GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const;
/**
* Query whether the renderer is currently in use by an actor on the stage
}
/**
+ * @brief Extracts the sign of a number
+ *
+ * @param[in] value The value we want to extract the sign
+ * @return -1 for negative values, +1 for positive values and 0 if value is 0
+ */
+template <typename T>
+int Sign( T value )
+{
+ return ( T(0) < value ) - ( value < T(0) );
+}
+
+/**
* @}
*/
} // namespace Dali