[dali_1.0.9] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_NODE_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_NODE_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/actors/actor-enumerations.h>
23 #include <dali/public-api/actors/draw-mode.h>
24 #include <dali/public-api/math/quaternion.h>
25 #include <dali/public-api/math/math-utils.h>
26 #include <dali/public-api/math/vector3.h>
27 #include <dali/internal/common/message.h>
28 #include <dali/internal/common/event-to-update.h>
29 #include <dali/internal/update/common/animatable-property.h>
30 #include <dali/internal/update/common/double-buffered.h>
31 #include <dali/internal/update/common/property-owner.h>
32 #include <dali/internal/update/common/property-vector3.h>
33 #include <dali/internal/update/common/scene-graph-buffers.h>
34 #include <dali/internal/update/common/inherited-property.h>
35 #include <dali/integration-api/debug.h>
36 #include <dali/internal/update/nodes/node-declarations.h>
37 #include <dali/internal/update/node-attachments/node-attachment-declarations.h>
38 #include <dali/internal/render/renderers/render-data-provider.h>
39
40 namespace Dali
41 {
42
43 namespace Internal
44 {
45
46 // value types used by messages
47 template <> struct ParameterType< ColorMode > : public BasicType< ColorMode > {};
48 template <> struct ParameterType< PositionInheritanceMode > : public BasicType< PositionInheritanceMode > {};
49
50 namespace SceneGraph
51 {
52
53 class DiscardQueue;
54 class Layer;
55 class NodeAttachment;
56 class RenderTask;
57 class UpdateManager;
58
59 /**
60  * Flag whether property has changed, during the Update phase.
61  */
62 enum NodePropertyFlags
63 {
64   NothingFlag          = 0x000,
65   TransformFlag        = 0x001,
66   VisibleFlag          = 0x002,
67   ColorFlag            = 0x004,
68   SizeFlag             = 0x008,
69   OverlayFlag          = 0x010,
70   SortModifierFlag     = 0x020,
71   ChildDeletedFlag     = 0x040
72 };
73
74 static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
75
76 /**
77  * Size is not inherited.
78  * VisibleFlag is inherited so that attachments can be synchronized with nodes after they become visible
79  */
80 static const int InheritedDirtyFlags = TransformFlag | VisibleFlag | ColorFlag | OverlayFlag;
81
82 // Flags which require the scene renderable lists to be updated
83 static const int RenderableUpdateFlags = TransformFlag | SortModifierFlag | ChildDeletedFlag;
84
85 /**
86  * Node is the base class for all nodes in the Scene Graph.
87  * Each node provides a transformation which applies to the node and its children.
88  * Node data is double-buffered. This allows an update thread to modify node data, without interferring
89  * with another thread reading the values from the previous update traversal.
90  */
91 class Node : public PropertyOwner, public RenderDataProvider
92 {
93 public:
94
95   // Defaults
96   static const PositionInheritanceMode DEFAULT_POSITION_INHERITANCE_MODE;
97   static const ColorMode DEFAULT_COLOR_MODE;
98
99   // Creation methods
100
101   /**
102    * Construct a new Node.
103    */
104   static Node* New();
105
106   /**
107    * Virtual destructor
108    */
109   virtual ~Node();
110
111   /**
112    * When a Node is marked "active" it has been disconnected, but its properties have been modified.
113    * @note An inactive Node will be skipped during the UpdateManager ResetProperties stage.
114    * @param[in] isActive True if the Node is active.
115    */
116   void SetActive( bool isActive )
117   {
118     mIsActive = isActive;
119   }
120
121   /**
122    * Query whether the Node is active.
123    * @return True if the Node is active.
124    */
125   bool IsActive() const
126   {
127     return mIsActive;
128   }
129
130   /**
131    * Called during UpdateManager::DestroyNode shortly before Node is destroyed.
132    */
133   void OnDestroy();
134
135   // Layer interface
136
137   /**
138    * Query whether the node is a layer.
139    * @return True if the node is a layer.
140    */
141   bool IsLayer()
142   {
143     return (GetLayer() != NULL);
144   }
145
146   /**
147    * Convert a node to a layer.
148    * @return A pointer to the layer, or NULL.
149    */
150   virtual Layer* GetLayer()
151   {
152     return NULL;
153   }
154
155   // Attachments
156
157   /**
158    * Attach an object to this Node; This should only be done by UpdateManager::AttachToNode.
159    * @pre The Node does not already have an attachment.
160    * @param[in] attachment The object to attach.
161    */
162   void Attach( NodeAttachment& attachment );
163
164   /**
165    * Query the node if it has an attachment.
166    * @return True if it has an attachment.
167    */
168   bool HasAttachment() const
169   {
170     return mAttachment;
171   }
172
173   /**
174    * Retreive the object attached to this node.
175    * @return The attachment.
176    */
177   NodeAttachment& GetAttachment() const
178   {
179     return *mAttachment;
180   }
181
182   // Containment methods
183
184   /**
185    * Query whether a node is the root node. Root nodes cannot have a parent node.
186    * A node becomes a root node, when it is installed by UpdateManager.
187    * @return True if the node is a root node.
188    */
189   bool IsRoot() const
190   {
191     return mIsRoot;
192   }
193
194   /**
195    * Set whether a node is the root node. Root nodes cannot have a parent node.
196    * This method should only be called by UpdateManager.
197    * @pre When isRoot is true, the node must not have a parent.
198    * @param[in] isRoot Whether the node is now a root node.
199    */
200   void SetRoot(bool isRoot);
201
202   /**
203    * Retrieve the parent of a Node.
204    * @return The parent node, or NULL if the Node has not been added to the scene-graph.
205    */
206   Node* GetParent()
207   {
208     return mParent;
209   }
210
211   /**
212    * Retrieve the parent of a Node.
213    * @return The parent node, or NULL if the Node has not been added to the scene-graph.
214    */
215   const Node* GetParent() const
216   {
217     return mParent;
218   }
219
220   /**
221    * Connect a node to the scene-graph.
222    * @pre A node cannot be added to itself.
223    * @pre The parent node is connected to the scene-graph.
224    * @pre The childNode does not already have a parent.
225    * @pre The childNode is not a root node.
226    * @param[in] childNode The child to add.
227    * @param[in] index to insert at, if not supplied or -1 it will be appended
228    *
229    */
230   void ConnectChild( Node* childNode, int index = -1);
231
232   /**
233    * Disconnect a child (& its children) from the scene-graph.
234    * @pre childNode is a child of this Node.
235    * @param[in] updateBufferIndex The current update buffer index.
236    * @param[in] childNode The node to disconnect.
237    * @param[in] connectedNodes Disconnected Node attachments should be removed from here.
238    * @param[in] disconnectedNodes Disconnected Node attachments should be added here.
239    */
240   void DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes );
241
242   /**
243    * Retrieve the children a Node.
244    * @return The container of children.
245    */
246   const NodeContainer& GetChildren() const
247   {
248     return mChildren;
249   }
250
251   /**
252    * Retrieve the children a Node.
253    * @return The container of children.
254    */
255   NodeContainer& GetChildren()
256   {
257     return mChildren;
258   }
259
260   // Update methods
261
262   /**
263    * Flag that one of the node values has changed in the current frame.
264    * @param[in] flag The flag to set.
265    */
266   void SetDirtyFlag(NodePropertyFlags flag)
267   {
268     mDirtyFlags |= flag;
269   }
270
271   /**
272    * Flag that all of the node values are dirty.
273    */
274   void SetAllDirtyFlags()
275   {
276     mDirtyFlags = AllFlags;
277   }
278
279   /**
280    * Query whether a node is dirty.
281    * @return The dirty flags
282    */
283   int GetDirtyFlags() const;
284
285   /**
286    * Query whether a node is clean.
287    * @return True if the node is clean.
288    */
289   bool IsClean() const
290   {
291     return ( NothingFlag == GetDirtyFlags() );
292   }
293
294   /**
295    * Retrieve the parent-origin of the node.
296    * @return The parent-origin.
297    */
298   const Vector3& GetParentOrigin() const
299   {
300     return mParentOrigin.mValue;
301   }
302
303   /**
304    * Sets both the local & base parent-origins of the node.
305    * @param[in] origin The new local & base parent-origins.
306    */
307   void SetParentOrigin(const Vector3& origin)
308   {
309     mParentOrigin.mValue = origin;
310     mParentOrigin.OnSet();
311   }
312
313   /**
314    * Retrieve the anchor-point of the node.
315    * @return The anchor-point.
316    */
317   const Vector3& GetAnchorPoint() const
318   {
319     return mAnchorPoint.mValue;
320   }
321
322   /**
323    * Sets both the local & base anchor-points of the node.
324    * @param[in] anchor The new local & base anchor-points.
325    */
326   void SetAnchorPoint(const Vector3& anchor)
327   {
328     mAnchorPoint.mValue = anchor;
329     mAnchorPoint.OnSet();
330   }
331
332   /**
333    * Retrieve the local position of the node, relative to its parent.
334    * @param[in] bufferIndex The buffer to read from.
335    * @return The local position.
336    */
337   const Vector3& GetPosition(BufferIndex bufferIndex) const
338   {
339     return mPosition[bufferIndex];
340   }
341
342   /**
343    * Sets both the local & base positions of the node.
344    * @param[in] updateBufferIndex The current update buffer index.
345    * @param[in] position The new local & base position.
346    */
347   void BakePosition(BufferIndex updateBufferIndex, const Vector3& position)
348   {
349     mPosition.Bake( updateBufferIndex, position );
350   }
351
352   /**
353    * Sets the world of the node derived from the position of all its parents.
354    * @param[in] updateBufferIndex The current update buffer index.
355    * @param[in] position The world position.
356    */
357   void SetWorldPosition( BufferIndex updateBufferIndex, const Vector3& position )
358   {
359     mWorldPosition.Set( updateBufferIndex, position );
360   }
361
362   /**
363    * Sets the position of the node derived from the position of all its parents.
364    * This method should only be called when the parent's world position is up-to-date.
365    * With a non-central anchor-point, the local rotation and scale affects the world position.
366    * Therefore the world rotation & scale must be updated before the world position.
367    * @pre The node has a parent.
368    * @param[in] updateBufferIndex The current update buffer index.
369    */
370   void InheritWorldPosition(BufferIndex updateBufferIndex)
371   {
372     DALI_ASSERT_DEBUG(mParent != NULL);
373
374     switch( mPositionInheritanceMode )
375     {
376       case INHERIT_PARENT_POSITION  : ///@see Dali::PositionInheritanceMode for how these modes are expected to work
377       {
378         Vector3 finalPosition(-0.5f, -0.5f, -0.5f);
379
380         finalPosition += mParentOrigin.mValue;
381         finalPosition *= mParent->GetSize(updateBufferIndex);
382         finalPosition += mPosition[updateBufferIndex];
383         finalPosition *= mParent->GetWorldScale(updateBufferIndex);
384         const Quaternion& parentWorldRotation = mParent->GetWorldRotation(updateBufferIndex);
385         if(!parentWorldRotation.IsIdentity())
386         {
387           finalPosition *= parentWorldRotation;
388         }
389
390         // check if a node needs to be offsetted locally (only applies when AnchorPoint is not central)
391         // dont use operator== as that does a slower comparison (and involves function calls)
392         Vector3 localOffset(0.5f, 0.5f, 0.5f);    // AnchorPoint::CENTER
393         localOffset -= mAnchorPoint.mValue;
394
395         if( ( fabsf( localOffset.x ) >= Math::MACHINE_EPSILON_0 ) ||
396             ( fabsf( localOffset.y ) >= Math::MACHINE_EPSILON_0 ) ||
397             ( fabsf( localOffset.z ) >= Math::MACHINE_EPSILON_0 ) )
398         {
399           localOffset *= mSize[updateBufferIndex];
400
401           Vector3 scale = mWorldScale[updateBufferIndex];
402           if(GetTransmitGeometryScaling())
403           {
404             // Remove geometry scaling to get back to actor scale
405             scale /= mGeometryScale;
406           }
407           // Also pick up sign of local scale
408           if (mScale[updateBufferIndex].x < 0.0f)
409           {
410             scale.x = -scale.x;
411           }
412           if (mScale[updateBufferIndex].y < 0.0f)
413           {
414             scale.y = -scale.y;
415           }
416           if (mScale[updateBufferIndex].z < 0.0f)
417           {
418             scale.z = -scale.z;
419           }
420
421           // If the anchor-point is not central, then position is affected by the local rotation & scale
422           localOffset *= scale;
423           const Quaternion& localWorldRotation = mWorldRotation[updateBufferIndex];
424           if(!localWorldRotation.IsIdentity())
425           {
426             localOffset *= localWorldRotation;
427           }
428           finalPosition += localOffset;
429         }
430
431         finalPosition += mParent->GetWorldPosition(updateBufferIndex);
432         mWorldPosition.Set( updateBufferIndex, finalPosition );
433         break;
434       }
435       case USE_PARENT_POSITION_PLUS_LOCAL_POSITION :
436       {
437         // copy parents position plus local transform
438         mWorldPosition.Set( updateBufferIndex, mParent->GetWorldPosition(updateBufferIndex) + mPosition[updateBufferIndex] );
439         break;
440       }
441       case USE_PARENT_POSITION :
442       {
443         // copy parents position
444         mWorldPosition.Set( updateBufferIndex, mParent->GetWorldPosition(updateBufferIndex) );
445         break;
446       }
447       case DONT_INHERIT_POSITION :
448       {
449         // use local position as world position
450         mWorldPosition.Set( updateBufferIndex, mPosition[updateBufferIndex] );
451         break;
452       }
453     }
454   }
455
456   /**
457    * Copies the previous inherited position, if this changed in the previous frame.
458    * This method should be called instead of InheritWorldPosition i.e. if the inherited position
459    * does not need to be recalculated in the current frame.
460    * @param[in] updateBufferIndex The current update buffer index.
461    */
462   void CopyPreviousWorldPosition( BufferIndex updateBufferIndex )
463   {
464     mWorldPosition.CopyPrevious( updateBufferIndex );
465   }
466
467   /**
468    * Retrieve the position of the node derived from the position of all its parents.
469    * @return The world position.
470    */
471   const Vector3& GetWorldPosition( BufferIndex bufferIndex ) const
472   {
473     return mWorldPosition[bufferIndex];
474   }
475
476   /**
477    * Set the position inheritance mode.
478    * @see Dali::Actor::PositionInheritanceMode
479    * @param[in] mode The new position inheritance mode.
480    */
481   void SetPositionInheritanceMode( PositionInheritanceMode mode )
482   {
483     mPositionInheritanceMode = mode;
484
485     SetDirtyFlag(TransformFlag);
486   }
487
488   /**
489    * @return The position inheritance mode.
490    */
491   PositionInheritanceMode GetPositionInheritanceMode() const
492   {
493     return mPositionInheritanceMode;
494   }
495
496   /**
497    * Retrieve the local rotation of the node, relative to its parent.
498    * @param[in] bufferIndex The buffer to read from.
499    * @return The local rotation.
500    */
501   const Quaternion& GetRotation(BufferIndex bufferIndex) const
502   {
503     return mRotation[bufferIndex];
504   }
505
506   /**
507    * Sets both the local & base rotations of the node.
508    * @param[in] updateBufferIndex The current update buffer index.
509    * @param[in] rotation The new local & base rotation.
510    */
511   void BakeRotation(BufferIndex updateBufferIndex, const Quaternion& rotation)
512   {
513     mRotation.Bake( updateBufferIndex, rotation );
514   }
515
516   /**
517    * Sets the rotation of the node derived from the rotation of all its parents.
518    * @param[in] updateBufferIndex The current update buffer index.
519    * @param[in] rotation The world rotation.
520    */
521   void SetWorldRotation( BufferIndex updateBufferIndex, const Quaternion& rotation )
522   {
523     mWorldRotation.Set( updateBufferIndex, rotation );
524   }
525
526   /**
527    * Sets the rotation of the node derived from the rotation of all its parents.
528    * This method should only be called when the parents world rotation is up-to-date.
529    * @pre The node has a parent.
530    * @param[in] updateBufferIndex The current update buffer index.
531    */
532   void InheritWorldRotation( BufferIndex updateBufferIndex )
533   {
534     DALI_ASSERT_DEBUG(mParent != NULL);
535
536     const Quaternion& localRotation = mRotation[updateBufferIndex];
537
538     if(localRotation.IsIdentity())
539     {
540       mWorldRotation.Set( updateBufferIndex, mParent->GetWorldRotation(updateBufferIndex) );
541     }
542     else
543     {
544       Quaternion finalRotation( mParent->GetWorldRotation(updateBufferIndex) );
545       finalRotation *= localRotation;
546       mWorldRotation.Set( updateBufferIndex, finalRotation );
547     }
548   }
549
550   /**
551    * Copies the previous inherited rotation, if this changed in the previous frame.
552    * This method should be called instead of InheritWorldRotation i.e. if the inherited rotation
553    * does not need to be recalculated in the current frame.
554    * @param[in] updateBufferIndex The current update buffer index.
555    */
556   void CopyPreviousWorldRotation( BufferIndex updateBufferIndex )
557   {
558     mWorldRotation.CopyPrevious( updateBufferIndex );
559   }
560
561   /**
562    * Retrieve the rotation of the node derived from the rotation of all its parents.
563    * @param[in] bufferIndex The buffer to read from.
564    * @return The world rotation.
565    */
566   const Quaternion& GetWorldRotation( BufferIndex bufferIndex ) const
567   {
568     return mWorldRotation[bufferIndex];
569   }
570
571   /**
572    * Set whether the Node inherits rotation.
573    * @param[in] inherit True if the parent rotation is inherited.
574    */
575   void SetInheritRotation(bool inherit)
576   {
577     if (inherit != mInheritRotation)
578     {
579       mInheritRotation = inherit;
580
581       SetDirtyFlag(TransformFlag);
582     }
583   }
584
585   /**
586    * Query whether the node inherits rotation from its parent.
587    * @return True if the parent rotation is inherited.
588    */
589   bool IsRotationInherited() const
590   {
591     return mInheritRotation;
592   }
593
594   /**
595    * Set the initial volume of the node. Used for calculating geometry scaling
596    * as the node size is changed  when transmitGeometryScaling is set to true.
597    *
598    * This property is not animatable.
599    *
600    * @param[in] volume The initial volume of this nodes meshes & children
601    */
602   void SetInitialVolume( const Vector3& volume)
603   {
604     mInitialVolume = volume;
605     SetDirtyFlag(SizeFlag);
606   }
607
608   /**
609    * Get the initial volume.  Used for calculating geometry scaling
610    * when TransmitGeometryScaling is true (i.e., the scaling is baked
611    * into the node tranform)
612    *
613    * @return The initial volume of this node and children.
614    */
615   Vector3 GetInitialVolume()
616   {
617     return mInitialVolume;
618   }
619
620   /**
621    * Sets whether the geometry scaling should be applied to the node
622    * (In which case, set the initial scale using SetInitialVolume()).
623    *
624    * If it is applied to the node, then the attachments are not scaled,
625    * as the scaling is then already baked into the node transform.
626    *
627    * @param[in] transmitGeometryScaling true if scaling is to be applied
628    * to the node.
629    */
630   void SetTransmitGeometryScaling(bool transmitGeometryScaling)
631   {
632     mTransmitGeometryScaling = transmitGeometryScaling;
633     SetDirtyFlag(SizeFlag);
634   }
635
636   /**
637    * Find out whether the node allows geometry scaling to be transmitted to its children.
638    * @return true if transmitted.
639    */
640   bool GetTransmitGeometryScaling() const
641   {
642     return mTransmitGeometryScaling;
643   }
644
645   /**
646    * Retrieve the local scale of the node, relative to its parent.
647    * @param[in] bufferIndex The buffer to read from.
648    * @return The local scale.
649    */
650   const Vector3& GetScale(BufferIndex bufferIndex) const
651   {
652     return mScale[bufferIndex];
653   }
654
655   /**
656    * Sets the scale of the node derived from the scale of all its parents and a pre-scale
657    * @param[in] updateBufferIndex The current update buffer index.
658    * @param[in] scale The world scale.
659    */
660   void SetWorldScale(BufferIndex updateBufferIndex, const Vector3& scale)
661   {
662     mWorldScale.Set( updateBufferIndex, mGeometryScale * scale );
663   }
664
665   /**
666    * Sets the scale of the node derived from the scale of all its parents and a pre-scale.
667    * This method should only be called when the parents world scale is up-to-date.
668    * @pre The node has a parent.
669    * @param[in] updateBufferIndex The current update buffer index.
670    */
671   void InheritWorldScale(BufferIndex updateBufferIndex)
672   {
673     DALI_ASSERT_DEBUG(mParent != NULL);
674
675     mWorldScale.Set( updateBufferIndex, mParent->GetWorldScale(updateBufferIndex) * mGeometryScale * mScale[updateBufferIndex] );
676   }
677
678   /**
679    * Copies the previous inherited scale, if this changed in the previous frame.
680    * This method should be called instead of InheritWorldScale i.e. if the inherited scale
681    * does not need to be recalculated in the current frame.
682    * @param[in] updateBufferIndex The current update buffer index.
683    */
684   void CopyPreviousWorldScale( BufferIndex updateBufferIndex )
685   {
686     mWorldScale.CopyPrevious( updateBufferIndex );
687   }
688
689   /**
690    * Retrieve the scale of the node derived from the scale of all its parents.
691    * @param[in] bufferIndex The buffer to read from.
692    * @return The world scale.
693    */
694   const Vector3& GetWorldScale( BufferIndex bufferIndex ) const
695   {
696     return mWorldScale[bufferIndex];
697   }
698
699   /**
700    * Set whether the Node inherits scale.
701    * @param inherit True if the Node inherits scale.
702    */
703   void SetInheritScale( bool inherit )
704   {
705     if( inherit != mInheritScale )
706     {
707       mInheritScale = inherit;
708
709       SetDirtyFlag( TransformFlag );
710     }
711   }
712
713   /**
714    * Query whether the Node inherits scale.
715    * @return if scale is inherited
716    */
717   bool IsScaleInherited() const
718   {
719     return mInheritScale;
720   }
721
722   /**
723    * Sets a geometry scale, calculated when TransmitGeometryScaling is true.
724    * Must only be used from render thread.
725    * @param[in] geometryScale The geometry scale value
726    */
727   void SetGeometryScale(Vector3 geometryScale)
728   {
729     mGeometryScale = geometryScale;
730
731     SetDirtyFlag( TransformFlag );
732   }
733
734   /**
735    * Retrieve the geometry scale, calculated when TransmitGeometryScaling is true.
736    * @return The geometry scale value.
737    */
738   const Vector3& GetGeometryScale() const
739   {
740     return mGeometryScale;
741   }
742
743   /**
744    * Retrieve the visibility of the node.
745    * @param[in] bufferIndex The buffer to read from.
746    * @return True if the node is visible.
747    */
748   bool IsVisible(BufferIndex bufferIndex) const
749   {
750     return mVisible[bufferIndex];
751   }
752
753   /**
754    * Retrieves whether a node is fully visible.
755    * A node is fully visible if is visible and all its ancestors are visible.
756    * @param[in] updateBufferIndex The current update buffer index.
757    * @return True if the node is fully visible.
758    */
759   bool IsFullyVisible( BufferIndex updateBufferIndex ) const;
760
761   /**
762    * Retrieve the opacity of the node.
763    * @param[in] bufferIndex The buffer to read from.
764    * @return The opacity.
765    */
766   float GetOpacity(BufferIndex bufferIndex) const
767   {
768     return mColor[bufferIndex].a;
769   }
770
771   /**
772    * Retrieve the color of the node.
773    * @param[in] bufferIndex The buffer to read from.
774    * @return The color.
775    */
776   const Vector4& GetColor(BufferIndex bufferIndex) const
777   {
778     return mColor[bufferIndex];
779   }
780
781   /**
782    * Sets the color of the node derived from the color of all its parents.
783    * @param[in] color The world color.
784    * @param[in] updateBufferIndex The current update buffer index.
785    */
786   void SetWorldColor(const Vector4& color, BufferIndex updateBufferIndex)
787   {
788     mWorldColor.Set( updateBufferIndex, color );
789   }
790
791   /**
792    * Sets the color of the node derived from the color of all its parents.
793    * This method should only be called when the parents world color is up-to-date.
794    * @pre The node has a parent.
795    * @param[in] updateBufferIndex The current update buffer index.
796    */
797   void InheritWorldColor( BufferIndex updateBufferIndex )
798   {
799     DALI_ASSERT_DEBUG(mParent != NULL);
800
801     // default first
802     if( mColorMode == USE_OWN_MULTIPLY_PARENT_ALPHA )
803     {
804       const Vector4& ownColor = mColor[updateBufferIndex];
805       mWorldColor.Set( updateBufferIndex, ownColor.r, ownColor.g, ownColor.b, ownColor.a * mParent->GetWorldColor(updateBufferIndex).a );
806     }
807     else if( mColorMode == USE_OWN_MULTIPLY_PARENT_COLOR )
808     {
809       mWorldColor.Set( updateBufferIndex, mParent->GetWorldColor(updateBufferIndex) * mColor[updateBufferIndex] );
810     }
811     else if( mColorMode == USE_PARENT_COLOR )
812     {
813       mWorldColor.Set( updateBufferIndex, mParent->GetWorldColor(updateBufferIndex) );
814     }
815     else // USE_OWN_COLOR
816     {
817       mWorldColor.Set( updateBufferIndex, mColor[updateBufferIndex] );
818     }
819   }
820
821   /**
822    * Copies the previous inherited scale, if this changed in the previous frame.
823    * This method should be called instead of InheritWorldScale i.e. if the inherited scale
824    * does not need to be recalculated in the current frame.
825    * @param[in] updateBufferIndex The current update buffer index.
826    */
827   void CopyPreviousWorldColor( BufferIndex updateBufferIndex )
828   {
829     mWorldColor.CopyPrevious( updateBufferIndex );
830   }
831
832   /**
833    * Retrieve the color of the node, possibly derived from the color
834    * of all its parents, depending on the value of mColorMode.
835    * @param[in] bufferIndex The buffer to read from.
836    * @return The world color.
837    */
838   const Vector4& GetWorldColor(BufferIndex bufferIndex) const
839   {
840     return mWorldColor[bufferIndex];
841   }
842
843   /**
844    * Set the color mode. This specifies whether the Node uses its own color,
845    * or inherits its parent color.
846    * @param[in] colorMode The new color mode.
847    */
848   void SetColorMode(ColorMode colorMode)
849   {
850     mColorMode = colorMode;
851
852     SetDirtyFlag(ColorFlag);
853   }
854
855   /**
856    * Retrieve the color mode.
857    * @return The color mode.
858    */
859   ColorMode GetColorMode() const
860   {
861     return mColorMode;
862   }
863
864   /**
865    * Retrieve the size of the node.
866    * @param[in] bufferIndex The buffer to read from.
867    * @return The size.
868    */
869   const Vector3& GetSize(BufferIndex bufferIndex) const
870   {
871     return mSize[bufferIndex];
872   }
873
874   /**
875    * Set the world-matrix of a node, with scale + rotation + translation.
876    * Scale and rotation are centered at the origin.
877    * Translation is applied independently of the scale or rotatation axis.
878    * @param[in] updateBufferIndex The current update buffer index.
879    * @param[in] scale The scale.
880    * @param[in] rotation The rotation.
881    * @param[in] translation The translation.
882    */
883   void SetWorldMatrix( BufferIndex updateBufferIndex, const Vector3& scale, const Quaternion& rotation, const Vector3& translation )
884   {
885     mWorldMatrix.Get( updateBufferIndex ).SetTransformComponents( scale, rotation, translation );
886     mWorldMatrix.SetDirty( updateBufferIndex );
887   }
888
889   /**
890    * Retrieve the cached world-matrix of a node.
891    * @param[in] bufferIndex The buffer to read from.
892    * @return The world-matrix.
893    */
894   const Matrix& GetWorldMatrix( BufferIndex bufferIndex ) const
895   {
896     return mWorldMatrix[ bufferIndex ];
897   }
898
899   /**
900    * Copy previous frames world matrix
901    * @param[in] updateBufferIndex The current update buffer index.
902    */
903   void CopyPreviousWorldMatrix( BufferIndex updateBufferIndex )
904   {
905     mWorldMatrix.CopyPrevious( updateBufferIndex );
906   }
907
908   /**
909    * Mark the node as exclusive to a single RenderTask.
910    * @param[in] renderTask The render-task, or NULL if the Node is not exclusive to a single RenderTask.
911    */
912   void SetExclusiveRenderTask( RenderTask* renderTask )
913   {
914     mExclusiveRenderTask = renderTask;
915   }
916
917   /**
918    * Query whether the node is exclusive to a single RenderTask.
919    * @return The render-task, or NULL if the Node is not exclusive to a single RenderTask.
920    */
921   RenderTask* GetExclusiveRenderTask() const
922   {
923     return mExclusiveRenderTask;
924   }
925
926   /**
927    * Set how the Node and its children should be drawn; see Dali::Actor::SetDrawMode() for more details.
928    * @param[in] drawMode The new draw-mode to use.
929    */
930   void SetDrawMode( const DrawMode::Type& drawMode )
931   {
932     mDrawMode = drawMode;
933   }
934
935   /**
936    * Returns whether node is an overlay or not.
937    * @return True if node is an overlay, false otherwise.
938    */
939   DrawMode::Type GetDrawMode() const
940   {
941     return mDrawMode;
942   }
943
944   /**
945    * Equality operator, checks for identity, not values.
946    *
947    */
948   bool operator==( const Node* rhs ) const
949   {
950     if ( this == rhs )
951     {
952       return true;
953     }
954     return false;
955   }
956
957   /**
958    * Set the inhibit local transform flag.@n
959    * Setting this flag will stop the node's local transform (position, scale and orientation)
960    * being applied on top of its parents transformation.
961    * @param[in] flag When true, local transformation is inhibited when calculating the world matrix.
962    */
963   void SetInhibitLocalTransform( bool flag )
964   {
965     SetDirtyFlag( TransformFlag );
966     mInhibitLocalTransform = flag;
967   }
968
969   /**
970    * Get the inhibit local transform flag.@n
971    * See @ref SetInhibitLocalTransform
972    * @result A flag, when true, local transformation is inhibited when calculating the world matrix.
973    */
974   bool GetInhibitLocalTransform() const
975   {
976     return mInhibitLocalTransform;
977   }
978
979 protected:
980
981   /**
982    * Set the parent of a Node.
983    * @param[in] parentNode the new parent.
984    */
985   void SetParent(Node& parentNode);
986
987   /**
988    * Protected constructor; See also Node::New()
989    */
990   Node();
991
992 private: // from RenderDataProvider
993
994   /**
995    * @copydoc RenderDataProvider::GetModelMatrix
996    */
997   virtual const Matrix& GetModelMatrix( unsigned int bufferId )
998   {
999     return GetWorldMatrix( bufferId );
1000   }
1001
1002   /**
1003    * @copydoc RenderDataProvider::GetRenderColor
1004    */
1005   virtual const Vector4& GetRenderColor( unsigned int bufferId )
1006   {
1007     return GetWorldColor( bufferId );
1008   }
1009
1010 private:
1011
1012   // Undefined
1013   Node(const Node&);
1014
1015   // Undefined
1016   Node& operator=(const Node& rhs);
1017
1018   /**
1019    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
1020    */
1021   virtual void ResetDefaultProperties( BufferIndex updateBufferIndex );
1022
1023   /**
1024    * Recursive helper to disconnect a Node and its children.
1025    * Disconnected Nodes have no parent or children.
1026    * @param[in] updateBufferIndex The current update buffer index.
1027    * @param[in] connectedNodes Disconnected Node attachments should be removed from here.
1028    * @param[in] disconnectedNodes Disconnected Node attachments should be added here.
1029    */
1030   void RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes, std::set<Node*>& disconnectedNodes );
1031
1032 public: // Default properties
1033
1034   PropertyVector3                mParentOrigin;  ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed
1035   PropertyVector3                mAnchorPoint;   ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed
1036
1037   AnimatableProperty<Vector3>    mSize;          ///< Size is provided for layouting
1038   AnimatableProperty<Vector3>    mPosition;      ///< Local transform; distance between parent-origin & anchor-point
1039   AnimatableProperty<Quaternion> mRotation;      ///< Local transform; rotation relative to parent node
1040   AnimatableProperty<Vector3>    mScale;         ///< Local transform; scale relative to parent node
1041   AnimatableProperty<bool>       mVisible;       ///< Visibility can be inherited from the Node hierachy
1042   AnimatableProperty<Vector4>    mColor;         ///< Color can be inherited from the Node hierarchy
1043
1044   // Inherited properties; read-only from public API
1045
1046   InheritedProperty<Vector3>    mWorldPosition; ///< Full inherited position
1047   InheritedProperty<Quaternion> mWorldRotation; ///< Full inherited rotation
1048   InheritedProperty<Vector3>    mWorldScale;    ///< Full inherited scale
1049   InheritedProperty<Matrix>     mWorldMatrix;   ///< Full inherited world matrix
1050   InheritedColor                mWorldColor;    ///< Full inherited color
1051
1052 protected:
1053
1054   Node*               mParent;                       ///< Pointer to parent node (a child is owned by its parent)
1055   RenderTask*         mExclusiveRenderTask;          ///< Nodes can be marked as exclusive to a single RenderTask
1056
1057   NodeAttachmentOwner mAttachment;                   ///< Optional owned attachment
1058   NodeContainer       mChildren;                     ///< Container of children; not owned
1059
1060   Vector3             mGeometryScale;                ///< Applied before calculating world transform.
1061   Vector3             mInitialVolume;                ///< Initial volume... TODO - need a better name
1062
1063   // flags, compressed to bitfield
1064   int  mDirtyFlags:10;                               ///< A composite set of flags for each of the Node properties
1065
1066   bool mIsRoot:1;                                    ///< True if the node cannot have a parent
1067   bool mInheritRotation:1;                           ///< Whether the parent's rotation should be inherited.
1068   bool mInheritScale:1;                              ///< Whether the parent's scale should be inherited.
1069   bool mTransmitGeometryScaling:1;                   ///< Whether geometry scaling should be applied to world transform.
1070   bool mInhibitLocalTransform:1;                     ///< whether local transform should be applied.
1071   bool mIsActive:1;                                  ///< When a Node is marked "active" it has been disconnected, and its properties have not been modified
1072
1073   DrawMode::Type          mDrawMode:2;               ///< How the Node and its children should be drawn
1074   PositionInheritanceMode mPositionInheritanceMode:2;///< Determines how position is inherited, 2 bits is enough
1075   ColorMode               mColorMode:2;              ///< Determines whether mWorldColor is inherited, 2 bits is enough
1076
1077   // Changes scope, should be at end of class
1078   DALI_LOG_OBJECT_STRING_DECLARATION;
1079 };
1080
1081 // Messages for Node
1082
1083 inline void SetInheritRotationMessage( EventToUpdate& eventToUpdate, const Node& node, bool inherit )
1084 {
1085   typedef MessageValue1< Node, bool > LocalType;
1086
1087   // Reserve some memory inside the message queue
1088   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1089
1090   // Construct message in the message queue memory; note that delete should not be called on the return value
1091   new (slot) LocalType( &node, &Node::SetInheritRotation, inherit );
1092 }
1093
1094 inline void SetInitialVolumeMessage( EventToUpdate& eventToUpdate, const Node& node, const Vector3& initialVolume )
1095 {
1096   typedef MessageValue1< Node, Vector3 > LocalType;
1097
1098   // Reserve some memory inside the message queue
1099   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1100
1101   // Construct message in the message queue memory; note that delete should not be called on the return value
1102   new (slot) LocalType( &node, &Node::SetInitialVolume, initialVolume );
1103 }
1104
1105 inline void SetTransmitGeometryScalingMessage( EventToUpdate& eventToUpdate, const Node& node, bool transmitGeometryScaling )
1106 {
1107   typedef MessageValue1< Node, bool > LocalType;
1108
1109   // Reserve some memory inside the message queue
1110   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1111
1112   // Construct message in the message queue memory; note that delete should not be called on the return value
1113   new (slot) LocalType( &node, &Node::SetTransmitGeometryScaling, transmitGeometryScaling );
1114 }
1115
1116 inline void SetParentOriginMessage( EventToUpdate& eventToUpdate, const Node& node, const Vector3& origin )
1117 {
1118   typedef MessageValue1< Node, Vector3 > LocalType;
1119
1120   // Reserve some memory inside the message queue
1121   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1122
1123   // Construct message in the message queue memory; note that delete should not be called on the return value
1124   new (slot) LocalType( &node, &Node::SetParentOrigin, origin );
1125 }
1126
1127 inline void SetAnchorPointMessage( EventToUpdate& eventToUpdate, const Node& node, const Vector3& anchor )
1128 {
1129   typedef MessageValue1< Node, Vector3 > LocalType;
1130
1131   // Reserve some memory inside the message queue
1132   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1133
1134   // Construct message in the message queue memory; note that delete should not be called on the return value
1135   new (slot) LocalType( &node, &Node::SetAnchorPoint, anchor );
1136 }
1137
1138 inline void SetPositionInheritanceModeMessage( EventToUpdate& eventToUpdate, const Node& node, PositionInheritanceMode mode )
1139 {
1140   typedef MessageValue1< Node, PositionInheritanceMode > LocalType;
1141
1142   // Reserve some memory inside the message queue
1143   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1144
1145   // Construct message in the message queue memory; note that delete should not be called on the return value
1146   new (slot) LocalType( &node, &Node::SetPositionInheritanceMode, mode );
1147 }
1148
1149 inline void SetInheritScaleMessage( EventToUpdate& eventToUpdate, const Node& node, bool inherit )
1150 {
1151   typedef MessageValue1< Node, bool > LocalType;
1152
1153   // Reserve some memory inside the message queue
1154   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1155
1156   // Construct message in the message queue memory; note that delete should not be called on the return value
1157   new (slot) LocalType( &node, &Node::SetInheritScale, inherit );
1158 }
1159
1160 inline void SetColorModeMessage( EventToUpdate& eventToUpdate, const Node& node, ColorMode colorMode )
1161 {
1162   typedef MessageValue1< Node, ColorMode > LocalType;
1163
1164   // Reserve some memory inside the message queue
1165   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1166
1167   // Construct message in the message queue memory; note that delete should not be called on the return value
1168   new (slot) LocalType( &node, &Node::SetColorMode, colorMode );
1169 }
1170
1171 inline void SetDrawModeMessage( EventToUpdate& eventToUpdate, const Node& node, DrawMode::Type drawMode )
1172 {
1173   typedef MessageValue1< Node, DrawMode::Type > LocalType;
1174
1175   // Reserve some memory inside the message queue
1176   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1177
1178   // Construct message in the message queue memory; note that delete should not be called on the return value
1179   new (slot) LocalType( &node, &Node::SetDrawMode, drawMode );
1180 }
1181
1182 } // namespace SceneGraph
1183
1184 } // namespace Internal
1185
1186 } // namespace Dali
1187
1188 #endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_H_