Merge remote-tracking branch 'origin/tizen' into new_text
[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/common/set-wrapper.h>
25 #include <dali/public-api/math/quaternion.h>
26 #include <dali/public-api/math/math-utils.h>
27 #include <dali/public-api/math/vector3.h>
28 #include <dali/internal/common/message.h>
29 #include <dali/internal/update/common/animatable-property.h>
30 #include <dali/internal/update/common/property-owner.h>
31 #include <dali/internal/update/common/property-vector3.h>
32 #include <dali/internal/update/common/scene-graph-buffers.h>
33 #include <dali/internal/update/common/inherited-property.h>
34 #include <dali/integration-api/debug.h>
35 #include <dali/internal/update/nodes/node-declarations.h>
36 #include <dali/internal/update/node-attachments/node-attachment-declarations.h>
37 #include <dali/internal/render/renderers/render-data-provider.h>
38
39 namespace Dali
40 {
41
42 namespace Internal
43 {
44
45 // value types used by messages
46 template <> struct ParameterType< ColorMode > : public BasicType< ColorMode > {};
47 template <> struct ParameterType< PositionInheritanceMode > : public BasicType< PositionInheritanceMode > {};
48 template <> struct ParameterType< SizeMode > : public BasicType< SizeMode > {};
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 orientation and scale affects the world position.
366    * Therefore the world orientation & 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& parentWorldOrientation = mParent->GetWorldOrientation(updateBufferIndex);
385         if(!parentWorldOrientation.IsIdentity())
386         {
387           finalPosition *= parentWorldOrientation;
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 orientation & scale
422           localOffset *= scale;
423           const Quaternion& localWorldOrientation = mWorldOrientation[updateBufferIndex];
424           if(!localWorldOrientation.IsIdentity())
425           {
426             localOffset *= localWorldOrientation;
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 orientation of the node, relative to its parent.
498    * @param[in] bufferIndex The buffer to read from.
499    * @return The local orientation.
500    */
501   const Quaternion& GetOrientation(BufferIndex bufferIndex) const
502   {
503     return mOrientation[bufferIndex];
504   }
505
506   /**
507    * Sets both the local & base orientations of the node.
508    * @param[in] updateBufferIndex The current update buffer index.
509    * @param[in] orientation The new local & base orientation.
510    */
511   void BakeOrientation(BufferIndex updateBufferIndex, const Quaternion& orientation)
512   {
513     mOrientation.Bake( updateBufferIndex, orientation );
514   }
515
516   /**
517    * Sets the orientation of the node derived from the rotation of all its parents.
518    * @param[in] updateBufferIndex The current update buffer index.
519    * @param[in] orientation The world orientation.
520    */
521   void SetWorldOrientation( BufferIndex updateBufferIndex, const Quaternion& orientation )
522   {
523     mWorldOrientation.Set( updateBufferIndex, orientation );
524   }
525
526   /**
527    * Sets the orientation of the node derived from the rotation of all its parents.
528    * This method should only be called when the parents world orientation is up-to-date.
529    * @pre The node has a parent.
530    * @param[in] updateBufferIndex The current update buffer index.
531    */
532   void InheritWorldOrientation( BufferIndex updateBufferIndex )
533   {
534     DALI_ASSERT_DEBUG(mParent != NULL);
535
536     const Quaternion& localOrientation = mOrientation[updateBufferIndex];
537
538     if(localOrientation.IsIdentity())
539     {
540       mWorldOrientation.Set( updateBufferIndex, mParent->GetWorldOrientation(updateBufferIndex) );
541     }
542     else
543     {
544       Quaternion finalOrientation( mParent->GetWorldOrientation(updateBufferIndex) );
545       finalOrientation *= localOrientation;
546       mWorldOrientation.Set( updateBufferIndex, finalOrientation );
547     }
548   }
549
550   /**
551    * Copies the previous inherited orientation, if this changed in the previous frame.
552    * This method should be called instead of InheritWorldOrientation i.e. if the inherited orientation
553    * does not need to be recalculated in the current frame.
554    * @param[in] updateBufferIndex The current update buffer index.
555    */
556   void CopyPreviousWorldOrientation( BufferIndex updateBufferIndex )
557   {
558     mWorldOrientation.CopyPrevious( updateBufferIndex );
559   }
560
561   /**
562    * Retrieve the orientation 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& GetWorldOrientation( BufferIndex bufferIndex ) const
567   {
568     return mWorldOrientation[bufferIndex];
569   }
570
571   /**
572    * Set whether the Node inherits orientation.
573    * @param[in] inherit True if the parent orientation is inherited.
574    */
575   void SetInheritOrientation(bool inherit)
576   {
577     if (inherit != mInheritOrientation)
578     {
579       mInheritOrientation = inherit;
580
581       SetDirtyFlag(TransformFlag);
582     }
583   }
584
585   /**
586    * Query whether the node inherits orientation from its parent.
587    * @return True if the parent orientation is inherited.
588    */
589   bool IsOrientationInherited() const
590   {
591     return mInheritOrientation;
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    * Copies the previously used size, if this changed in the previous frame.
745    * @param[in] updateBufferIndex The current update buffer index.
746    */
747   void CopyPreviousSize( BufferIndex updateBufferIndex )
748   {
749     SetSize( updateBufferIndex, GetSize( 1u - updateBufferIndex ) );
750   }
751
752   /**
753    * Retrieve the visibility of the node.
754    * @param[in] bufferIndex The buffer to read from.
755    * @return True if the node is visible.
756    */
757   bool IsVisible(BufferIndex bufferIndex) const
758   {
759     return mVisible[bufferIndex];
760   }
761
762   /**
763    * Retrieves whether a node is fully visible.
764    * A node is fully visible if is visible and all its ancestors are visible.
765    * @param[in] updateBufferIndex The current update buffer index.
766    * @return True if the node is fully visible.
767    */
768   bool IsFullyVisible( BufferIndex updateBufferIndex ) const;
769
770   /**
771    * Retrieve the opacity of the node.
772    * @param[in] bufferIndex The buffer to read from.
773    * @return The opacity.
774    */
775   float GetOpacity(BufferIndex bufferIndex) const
776   {
777     return mColor[bufferIndex].a;
778   }
779
780   /**
781    * Retrieve the color of the node.
782    * @param[in] bufferIndex The buffer to read from.
783    * @return The color.
784    */
785   const Vector4& GetColor(BufferIndex bufferIndex) const
786   {
787     return mColor[bufferIndex];
788   }
789
790   /**
791    * Sets the color of the node derived from the color of all its parents.
792    * @param[in] color The world color.
793    * @param[in] updateBufferIndex The current update buffer index.
794    */
795   void SetWorldColor(const Vector4& color, BufferIndex updateBufferIndex)
796   {
797     mWorldColor.Set( updateBufferIndex, color );
798   }
799
800   /**
801    * Sets the color of the node derived from the color of all its parents.
802    * This method should only be called when the parents world color is up-to-date.
803    * @pre The node has a parent.
804    * @param[in] updateBufferIndex The current update buffer index.
805    */
806   void InheritWorldColor( BufferIndex updateBufferIndex )
807   {
808     DALI_ASSERT_DEBUG(mParent != NULL);
809
810     // default first
811     if( mColorMode == USE_OWN_MULTIPLY_PARENT_ALPHA )
812     {
813       const Vector4& ownColor = mColor[updateBufferIndex];
814       mWorldColor.Set( updateBufferIndex, ownColor.r, ownColor.g, ownColor.b, ownColor.a * mParent->GetWorldColor(updateBufferIndex).a );
815     }
816     else if( mColorMode == USE_OWN_MULTIPLY_PARENT_COLOR )
817     {
818       mWorldColor.Set( updateBufferIndex, mParent->GetWorldColor(updateBufferIndex) * mColor[updateBufferIndex] );
819     }
820     else if( mColorMode == USE_PARENT_COLOR )
821     {
822       mWorldColor.Set( updateBufferIndex, mParent->GetWorldColor(updateBufferIndex) );
823     }
824     else // USE_OWN_COLOR
825     {
826       mWorldColor.Set( updateBufferIndex, mColor[updateBufferIndex] );
827     }
828   }
829
830   /**
831    * Copies the previous inherited scale, if this changed in the previous frame.
832    * This method should be called instead of InheritWorldScale i.e. if the inherited scale
833    * does not need to be recalculated in the current frame.
834    * @param[in] updateBufferIndex The current update buffer index.
835    */
836   void CopyPreviousWorldColor( BufferIndex updateBufferIndex )
837   {
838     mWorldColor.CopyPrevious( updateBufferIndex );
839   }
840
841   /**
842    * Retrieve the color of the node, possibly derived from the color
843    * of all its parents, depending on the value of mColorMode.
844    * @param[in] bufferIndex The buffer to read from.
845    * @return The world color.
846    */
847   const Vector4& GetWorldColor(BufferIndex bufferIndex) const
848   {
849     return mWorldColor[bufferIndex];
850   }
851
852   /**
853    * Set the color mode. This specifies whether the Node uses its own color,
854    * or inherits its parent color.
855    * @param[in] colorMode The new color mode.
856    */
857   void SetColorMode(ColorMode colorMode)
858   {
859     mColorMode = colorMode;
860
861     SetDirtyFlag(ColorFlag);
862   }
863
864   /**
865    * Retrieve the color mode.
866    * @return The color mode.
867    */
868   ColorMode GetColorMode() const
869   {
870     return mColorMode;
871   }
872
873   /**
874    * Sets the size of the node.
875    * @param[in] bufferIndex The buffer to write to.
876    * @param[in] size The size to write.
877    */
878   void SetSize( BufferIndex bufferIndex, const Vector3& size )
879   {
880     mSize[bufferIndex] = size;
881   }
882
883   /**
884    * Retrieve the size of the node.
885    * @param[in] bufferIndex The buffer to read from.
886    * @return The size.
887    */
888   const Vector3& GetSize(BufferIndex bufferIndex) const
889   {
890     return mSize[bufferIndex];
891   }
892
893   /**
894    * Set the world-matrix of a node, with scale + rotation + translation.
895    * Scale and rotation are centered at the origin.
896    * Translation is applied independently of the scale or rotatation axis.
897    * @param[in] updateBufferIndex The current update buffer index.
898    * @param[in] scale The scale.
899    * @param[in] rotation The rotation.
900    * @param[in] translation The translation.
901    */
902   void SetWorldMatrix( BufferIndex updateBufferIndex, const Vector3& scale, const Quaternion& rotation, const Vector3& translation )
903   {
904     mWorldMatrix.Get( updateBufferIndex ).SetTransformComponents( scale, rotation, translation );
905     mWorldMatrix.SetDirty( updateBufferIndex );
906   }
907
908   /**
909    * Retrieve the cached world-matrix of a node.
910    * @param[in] bufferIndex The buffer to read from.
911    * @return The world-matrix.
912    */
913   const Matrix& GetWorldMatrix( BufferIndex bufferIndex ) const
914   {
915     return mWorldMatrix[ bufferIndex ];
916   }
917
918   /**
919    * Copy previous frames world matrix
920    * @param[in] updateBufferIndex The current update buffer index.
921    */
922   void CopyPreviousWorldMatrix( BufferIndex updateBufferIndex )
923   {
924     mWorldMatrix.CopyPrevious( updateBufferIndex );
925   }
926
927   /**
928    * Mark the node as exclusive to a single RenderTask.
929    * @param[in] renderTask The render-task, or NULL if the Node is not exclusive to a single RenderTask.
930    */
931   void SetExclusiveRenderTask( RenderTask* renderTask )
932   {
933     mExclusiveRenderTask = renderTask;
934   }
935
936   /**
937    * Query whether the node is exclusive to a single RenderTask.
938    * @return The render-task, or NULL if the Node is not exclusive to a single RenderTask.
939    */
940   RenderTask* GetExclusiveRenderTask() const
941   {
942     return mExclusiveRenderTask;
943   }
944
945   /**
946    * Set how the Node and its children should be drawn; see Dali::Actor::SetDrawMode() for more details.
947    * @param[in] drawMode The new draw-mode to use.
948    */
949   void SetDrawMode( const DrawMode::Type& drawMode )
950   {
951     mDrawMode = drawMode;
952   }
953
954   /**
955    * Returns whether node is an overlay or not.
956    * @return True if node is an overlay, false otherwise.
957    */
958   DrawMode::Type GetDrawMode() const
959   {
960     return mDrawMode;
961   }
962
963   /**
964    * Equality operator, checks for identity, not values.
965    *
966    */
967   bool operator==( const Node* rhs ) const
968   {
969     if ( this == rhs )
970     {
971       return true;
972     }
973     return false;
974   }
975
976   /**
977    * Set the inhibit local transform flag.@n
978    * Setting this flag will stop the node's local transform (position, scale and orientation)
979    * being applied on top of its parents transformation.
980    * @param[in] flag When true, local transformation is inhibited when calculating the world matrix.
981    */
982   void SetInhibitLocalTransform( bool flag )
983   {
984     SetDirtyFlag( TransformFlag );
985     mInhibitLocalTransform = flag;
986   }
987
988   /**
989    * Get the inhibit local transform flag.@n
990    * See @ref SetInhibitLocalTransform
991    * @result A flag, when true, local transformation is inhibited when calculating the world matrix.
992    */
993   bool GetInhibitLocalTransform() const
994   {
995     return mInhibitLocalTransform;
996   }
997
998 protected:
999
1000   /**
1001    * Set the parent of a Node.
1002    * @param[in] parentNode the new parent.
1003    */
1004   void SetParent(Node& parentNode);
1005
1006   /**
1007    * Protected constructor; See also Node::New()
1008    */
1009   Node();
1010
1011 private: // from RenderDataProvider
1012
1013   /**
1014    * @copydoc RenderDataProvider::GetModelMatrix
1015    */
1016   virtual const Matrix& GetModelMatrix( unsigned int bufferId )
1017   {
1018     return GetWorldMatrix( bufferId );
1019   }
1020
1021   /**
1022    * @copydoc RenderDataProvider::GetRenderColor
1023    */
1024   virtual const Vector4& GetRenderColor( unsigned int bufferId )
1025   {
1026     return GetWorldColor( bufferId );
1027   }
1028
1029 private:
1030
1031   // Undefined
1032   Node(const Node&);
1033
1034   // Undefined
1035   Node& operator=(const Node& rhs);
1036
1037   /**
1038    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
1039    */
1040   virtual void ResetDefaultProperties( BufferIndex updateBufferIndex );
1041
1042   /**
1043    * Recursive helper to disconnect a Node and its children.
1044    * Disconnected Nodes have no parent or children.
1045    * @param[in] updateBufferIndex The current update buffer index.
1046    * @param[in] connectedNodes Disconnected Node attachments should be removed from here.
1047    * @param[in] disconnectedNodes Disconnected Node attachments should be added here.
1048    */
1049   void RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes, std::set<Node*>& disconnectedNodes );
1050
1051 public: // Default properties
1052
1053   PropertyVector3                mParentOrigin;  ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed
1054   PropertyVector3                mAnchorPoint;   ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed
1055
1056   AnimatableProperty<Vector3>    mSize;          ///< Size is provided for layouting
1057   AnimatableProperty<Vector3>    mPosition;      ///< Local transform; distance between parent-origin & anchor-point
1058   AnimatableProperty<Quaternion> mOrientation;   ///< Local transform; rotation relative to parent node
1059   AnimatableProperty<Vector3>    mScale;         ///< Local transform; scale relative to parent node
1060   AnimatableProperty<bool>       mVisible;       ///< Visibility can be inherited from the Node hierachy
1061   AnimatableProperty<Vector4>    mColor;         ///< Color can be inherited from the Node hierarchy
1062
1063   // Inherited properties; read-only from public API
1064
1065   InheritedVector3    mWorldPosition;     ///< Full inherited position
1066   InheritedQuaternion mWorldOrientation;  ///< Full inherited orientation
1067   InheritedVector3    mWorldScale;        ///< Full inherited scale
1068   InheritedMatrix     mWorldMatrix;       ///< Full inherited world matrix
1069   InheritedColor      mWorldColor;        ///< Full inherited color
1070
1071 protected:
1072
1073   Node*               mParent;                       ///< Pointer to parent node (a child is owned by its parent)
1074   RenderTask*         mExclusiveRenderTask;          ///< Nodes can be marked as exclusive to a single RenderTask
1075
1076   NodeAttachmentOwner mAttachment;                   ///< Optional owned attachment
1077   NodeContainer       mChildren;                     ///< Container of children; not owned
1078
1079   Vector3             mGeometryScale;                ///< Applied before calculating world transform.
1080   Vector3             mInitialVolume;                ///< Initial volume... TODO - need a better name.
1081
1082   // flags, compressed to bitfield
1083   int  mDirtyFlags:10;                               ///< A composite set of flags for each of the Node properties
1084
1085   bool mIsRoot:1;                                    ///< True if the node cannot have a parent
1086   bool mInheritOrientation:1;                        ///< Whether the parent's orientation should be inherited.
1087   bool mInheritScale:1;                              ///< Whether the parent's scale should be inherited.
1088   bool mTransmitGeometryScaling:1;                   ///< Whether geometry scaling should be applied to world transform.
1089   bool mInhibitLocalTransform:1;                     ///< whether local transform should be applied.
1090   bool mIsActive:1;                                  ///< When a Node is marked "active" it has been disconnected, and its properties have not been modified
1091
1092   DrawMode::Type          mDrawMode:2;               ///< How the Node and its children should be drawn
1093   PositionInheritanceMode mPositionInheritanceMode:2;///< Determines how position is inherited, 2 bits is enough
1094   ColorMode               mColorMode:2;              ///< Determines whether mWorldColor is inherited, 2 bits is enough
1095
1096   // Changes scope, should be at end of class
1097   DALI_LOG_OBJECT_STRING_DECLARATION;
1098 };
1099
1100 // Messages for Node
1101
1102 inline void SetInheritOrientationMessage( EventThreadServices& eventThreadServices, const Node& node, bool inherit )
1103 {
1104   typedef MessageValue1< Node, bool > LocalType;
1105
1106   // Reserve some memory inside the message queue
1107   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1108
1109   // Construct message in the message queue memory; note that delete should not be called on the return value
1110   new (slot) LocalType( &node, &Node::SetInheritOrientation, inherit );
1111 }
1112
1113 inline void SetInitialVolumeMessage( EventThreadServices& eventThreadServices, const Node& node, const Vector3& initialVolume )
1114 {
1115   typedef MessageValue1< Node, Vector3 > LocalType;
1116
1117   // Reserve some memory inside the message queue
1118   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1119
1120   // Construct message in the message queue memory; note that delete should not be called on the return value
1121   new (slot) LocalType( &node, &Node::SetInitialVolume, initialVolume );
1122 }
1123
1124 inline void SetTransmitGeometryScalingMessage( EventThreadServices& eventThreadServices, const Node& node, bool transmitGeometryScaling )
1125 {
1126   typedef MessageValue1< Node, bool > LocalType;
1127
1128   // Reserve some memory inside the message queue
1129   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1130
1131   // Construct message in the message queue memory; note that delete should not be called on the return value
1132   new (slot) LocalType( &node, &Node::SetTransmitGeometryScaling, transmitGeometryScaling );
1133 }
1134
1135 inline void SetParentOriginMessage( EventThreadServices& eventThreadServices, const Node& node, const Vector3& origin )
1136 {
1137   typedef MessageValue1< Node, Vector3 > LocalType;
1138
1139   // Reserve some memory inside the message queue
1140   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1141
1142   // Construct message in the message queue memory; note that delete should not be called on the return value
1143   new (slot) LocalType( &node, &Node::SetParentOrigin, origin );
1144 }
1145
1146 inline void SetAnchorPointMessage( EventThreadServices& eventThreadServices, const Node& node, const Vector3& anchor )
1147 {
1148   typedef MessageValue1< Node, Vector3 > LocalType;
1149
1150   // Reserve some memory inside the message queue
1151   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1152
1153   // Construct message in the message queue memory; note that delete should not be called on the return value
1154   new (slot) LocalType( &node, &Node::SetAnchorPoint, anchor );
1155 }
1156
1157 inline void SetPositionInheritanceModeMessage( EventThreadServices& eventThreadServices, const Node& node, PositionInheritanceMode mode )
1158 {
1159   typedef MessageValue1< Node, PositionInheritanceMode > LocalType;
1160
1161   // Reserve some memory inside the message queue
1162   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1163
1164   // Construct message in the message queue memory; note that delete should not be called on the return value
1165   new (slot) LocalType( &node, &Node::SetPositionInheritanceMode, mode );
1166 }
1167
1168 inline void SetInheritScaleMessage( EventThreadServices& eventThreadServices, const Node& node, bool inherit )
1169 {
1170   typedef MessageValue1< Node, bool > LocalType;
1171
1172   // Reserve some memory inside the message queue
1173   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1174
1175   // Construct message in the message queue memory; note that delete should not be called on the return value
1176   new (slot) LocalType( &node, &Node::SetInheritScale, inherit );
1177 }
1178
1179 inline void SetColorModeMessage( EventThreadServices& eventThreadServices, const Node& node, ColorMode colorMode )
1180 {
1181   typedef MessageValue1< Node, ColorMode > LocalType;
1182
1183   // Reserve some memory inside the message queue
1184   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1185
1186   // Construct message in the message queue memory; note that delete should not be called on the return value
1187   new (slot) LocalType( &node, &Node::SetColorMode, colorMode );
1188 }
1189
1190 inline void SetDrawModeMessage( EventThreadServices& eventThreadServices, const Node& node, DrawMode::Type drawMode )
1191 {
1192   typedef MessageValue1< Node, DrawMode::Type > LocalType;
1193
1194   // Reserve some memory inside the message queue
1195   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
1196
1197   // Construct message in the message queue memory; note that delete should not be called on the return value
1198   new (slot) LocalType( &node, &Node::SetDrawMode, drawMode );
1199 }
1200
1201 } // namespace SceneGraph
1202
1203 } // namespace Internal
1204
1205 } // namespace Dali
1206
1207 #endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_H_