2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include <dali/internal/event/actors/actor-impl.h>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector3.h>
30 #include <dali/public-api/math/radian.h>
31 #include <dali/public-api/object/type-registry.h>
32 #include <dali/public-api/scripting/scripting.h>
34 #include <dali/internal/common/internal-constants.h>
35 #include <dali/internal/event/render-tasks/render-task-impl.h>
36 #include <dali/internal/event/actors/camera-actor-impl.h>
37 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
38 #include <dali/internal/event/common/property-index-ranges.h>
39 #include <dali/internal/event/common/stage-impl.h>
40 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
41 #include <dali/internal/event/animation/constraint-impl.h>
42 #include <dali/internal/event/common/projection.h>
43 #include <dali/internal/update/common/animatable-property.h>
44 #include <dali/internal/update/common/property-owner-messages.h>
45 #include <dali/internal/update/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/effects/shader-effect-impl.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
59 #include <dali/internal/event/events/pan-gesture-detector-impl.h>
60 #include <dali/internal/event/events/pinch-gesture-detector-impl.h>
61 #include <dali/internal/event/events/long-press-gesture-detector-impl.h>
62 #include <dali/internal/event/events/tap-gesture-detector-impl.h>
64 using Dali::Internal::SceneGraph::Node;
65 using Dali::Internal::SceneGraph::AnimatableProperty;
66 using Dali::Internal::SceneGraph::PropertyBase;
67 using Dali::Internal::SceneGraph::Shader;
74 const Property::Index Actor::PARENT_ORIGIN = 0;
75 const Property::Index Actor::PARENT_ORIGIN_X = 1;
76 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
77 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
78 const Property::Index Actor::ANCHOR_POINT = 4;
79 const Property::Index Actor::ANCHOR_POINT_X = 5;
80 const Property::Index Actor::ANCHOR_POINT_Y = 6;
81 const Property::Index Actor::ANCHOR_POINT_Z = 7;
82 const Property::Index Actor::SIZE = 8;
83 const Property::Index Actor::SIZE_WIDTH = 9;
84 const Property::Index Actor::SIZE_HEIGHT = 10;
85 const Property::Index Actor::SIZE_DEPTH = 11;
86 const Property::Index Actor::POSITION = 12;
87 const Property::Index Actor::POSITION_X = 13;
88 const Property::Index Actor::POSITION_Y = 14;
89 const Property::Index Actor::POSITION_Z = 15;
90 const Property::Index Actor::WORLD_POSITION = 16;
91 const Property::Index Actor::WORLD_POSITION_X = 17;
92 const Property::Index Actor::WORLD_POSITION_Y = 18;
93 const Property::Index Actor::WORLD_POSITION_Z = 19;
94 const Property::Index Actor::ROTATION = 20;
95 const Property::Index Actor::WORLD_ROTATION = 21;
96 const Property::Index Actor::SCALE = 22;
97 const Property::Index Actor::SCALE_X = 23;
98 const Property::Index Actor::SCALE_Y = 24;
99 const Property::Index Actor::SCALE_Z = 25;
100 const Property::Index Actor::WORLD_SCALE = 26;
101 const Property::Index Actor::VISIBLE = 27;
102 const Property::Index Actor::COLOR = 28;
103 const Property::Index Actor::COLOR_RED = 29;
104 const Property::Index Actor::COLOR_GREEN = 30;
105 const Property::Index Actor::COLOR_BLUE = 31;
106 const Property::Index Actor::COLOR_ALPHA = 32;
107 const Property::Index Actor::WORLD_COLOR = 33;
108 const Property::Index Actor::WORLD_MATRIX = 34;
109 const Property::Index Actor::NAME = 35;
110 const Property::Index Actor::SENSITIVE = 36;
111 const Property::Index Actor::LEAVE_REQUIRED = 37;
112 const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
113 const Property::Index Actor::INHERIT_ROTATION = 39;
114 const Property::Index Actor::INHERIT_SCALE = 40;
115 const Property::Index Actor::COLOR_MODE = 41;
116 const Property::Index Actor::POSITION_INHERITANCE = 42;
117 const Property::Index Actor::DRAW_MODE = 43;
119 namespace // unnamed namespace
123 * We want to discourage the use of property strings (minimize string comparisons),
124 * particularly for the default properties.
126 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
128 // Name Type writable animatable constraint-input
129 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
130 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
131 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
132 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
133 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
134 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
135 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
136 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
137 { "size", Property::VECTOR3, true, true, true }, // SIZE
138 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
139 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
140 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
141 { "position", Property::VECTOR3, true, true, true }, // POSITION
142 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
143 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
144 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
145 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
146 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
147 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
148 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
149 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
150 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
151 { "scale", Property::VECTOR3, true, true, true }, // SCALE
152 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
153 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
154 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
155 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
156 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
157 { "color", Property::VECTOR4, true, true, true }, // COLOR
158 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
159 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
160 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
161 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
162 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
163 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
164 { "name", Property::STRING, true, false, false }, // NAME
165 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
166 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
167 { "inherit-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
168 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
169 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
170 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
171 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
172 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
174 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
176 } // unnamed namespace
181 unsigned int Actor::mActorCounter = 0;
182 ActorContainer Actor::mNullChildren;
184 // Encapsulate actor related gesture information
191 : gesturesRequired( Gesture::Type( 0 ) ),
192 panDetectors( NULL ),
193 pinchDetectors( NULL ),
194 longPressDetectors( NULL ),
205 delete pinchDetectors;
206 delete longPressDetectors;
211 * Checks if the containers in GestureData are empty
215 return !panDetectors &&
217 !longPressDetectors &&
222 * Template to add a detector to the appropriate container. Dynamically allocates the container
223 * only if it is used.
225 template< typename DetectorType, typename ContainerType >
226 void AddDetector( ContainerType*& containerPtr, GestureDetector* detector )
228 if ( NULL == containerPtr )
230 containerPtr = new ContainerType;
233 containerPtr->push_back( static_cast< DetectorType* >( detector ) );
234 gesturesRequired = Gesture::Type( gesturesRequired | detector->GetType() );
238 * Template to remove a detector from the appropriate container. Deletes the container if it is
239 * no longer required.
241 template< typename ContainerType >
242 void RemoveDetector( ContainerType*& containerPtr, GestureDetector* detector )
244 if ( NULL != containerPtr )
246 ContainerType& container( *containerPtr );
247 typename ContainerType::iterator match( std::remove( container.begin(), container.end(), detector ) );
248 DALI_ASSERT_DEBUG( match != container.end() && "Actor does not have the detector" );
249 container.erase( match, container.end() );
251 if ( container.empty() )
253 gesturesRequired = Gesture::Type( gesturesRequired & ~detector->GetType() );
260 Gesture::Type gesturesRequired;
262 PanGestureDetectorContainer* panDetectors;
263 PinchGestureDetectorContainer* pinchDetectors;
264 LongPressGestureDetectorContainer* longPressDetectors;
265 TapGestureDetectorContainer* tapDetectors;
268 #ifdef DYNAMICS_SUPPORT
270 // Encapsulate actor related dynamics data
273 DynamicsData( Actor* slotOwner )
274 : slotDelegate( slotOwner )
278 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
279 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
281 DynamicsBodyPtr body;
282 JointContainer joints;
283 ReferencedJointContainer referencedJoints;
285 SlotDelegate< Actor > slotDelegate;
288 #endif // DYNAMICS_SUPPORT
293 using namespace Dali;
295 BaseHandle CreateActor()
297 return Dali::Actor::New();
300 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
302 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
303 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
304 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
305 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
307 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
308 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
312 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
314 ActorPtr Actor::New()
316 ActorPtr actor( new Actor( BASIC ) );
318 // Second-phase construction
324 const std::string& Actor::GetName() const
329 void Actor::SetName(const std::string& name)
335 // ATTENTION: string for debug purposes is not thread safe.
336 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
340 unsigned int Actor::GetId() const
345 void Actor::Attach( ActorAttachment& attachment )
347 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
351 attachment.Connect();
354 mAttachment = ActorAttachmentPtr(&attachment);
357 ActorAttachmentPtr Actor::GetAttachment()
362 bool Actor::OnStage() const
367 Dali::Layer Actor::GetLayer()
371 // Short-circuit for Layer derived actors
374 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
377 // Find the immediate Layer parent
378 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
380 if( parent->IsLayer() )
382 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
389 void Actor::Add(Actor& child)
391 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
392 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
396 mChildren = new ActorContainer;
399 Actor* const oldParent( child.mParent );
401 // child might already be ours
402 if( this != oldParent )
404 // if we already have parent, unparent us first
407 oldParent->Remove( child ); // This causes OnChildRemove callback
410 // Guard against Add() during previous OnChildRemove callback
411 if ( !child.mParent )
413 // Do this first, since user callbacks from within SetParent() may need to remove child
414 mChildren->push_back(Dali::Actor(&child));
416 // SetParent asserts that child can be added
417 child.SetParent(this);
419 // Notification for derived classes
425 void Actor::Remove(Actor& child)
427 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
437 // Find the child in mChildren, and unparent it
438 ActorIter end = mChildren->end();
439 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
441 Actor& actor = GetImplementation(*iter);
443 if( &actor == &child )
445 // Keep handle for OnChildRemove notification
446 removed = Dali::Actor( &actor );
448 // Do this first, since user callbacks from within SetParent() may need to add the child
449 mChildren->erase(iter);
451 DALI_ASSERT_DEBUG( actor.GetParent() == this );
452 actor.SetParent( NULL );
460 // Notification for derived classes
461 OnChildRemove( GetImplementation(removed) );
465 void Actor::Unparent()
469 mParent->Remove( *this );
473 unsigned int Actor::GetChildCount() const
475 return ( NULL != mChildren ) ? mChildren->size() : 0;
478 Dali::Actor Actor::GetChildAt(unsigned int index) const
480 DALI_ASSERT_ALWAYS( index < GetChildCount() );
482 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
485 ActorContainer Actor::GetChildren()
487 if( NULL != mChildren )
492 // return copy of mNullChildren
493 return mNullChildren;
496 const ActorContainer& Actor::GetChildren() const
498 if( NULL != mChildren )
503 // return const reference to mNullChildren
504 return mNullChildren;
507 ActorPtr Actor::FindChildByName(const std::string& actorName)
510 if (actorName == mName)
516 ActorIter end = mChildren->end();
517 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
519 child = GetImplementation(*iter).FindChildByName(actorName);
530 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
532 Dali::Actor child = DoGetChildByAlias(actorAlias);
534 // If not found then search by name.
537 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
540 child = Dali::Actor(child_ptr.Get());
547 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
549 Dali::Actor child = GetChildByAlias(actorAlias);
551 if (!child && mChildren )
553 ActorIter end = mChildren->end();
554 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
556 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
568 ActorPtr Actor::FindChildById(const unsigned int id)
577 ActorIter end = mChildren->end();
578 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
580 child = GetImplementation(*iter).FindChildById(id);
591 void Actor::SetParentOrigin( const Vector3& origin )
595 // mNode is being used in a separate thread; queue a message to set the value & base value
596 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
599 // Cache for event-thread access
602 // not allocated, check if different from default
603 if( ParentOrigin::DEFAULT != origin )
605 mParentOrigin = new Vector3( origin );
610 // check if different from current costs more than just set
611 *mParentOrigin = origin;
615 void Actor::SetParentOriginX( float x )
617 const Vector3& current = GetCurrentParentOrigin();
619 SetParentOrigin( Vector3( x, current.y, current.z ) );
622 void Actor::SetParentOriginY( float y )
624 const Vector3& current = GetCurrentParentOrigin();
626 SetParentOrigin( Vector3( current.x, y, current.z ) );
629 void Actor::SetParentOriginZ( float z )
631 const Vector3& current = GetCurrentParentOrigin();
633 SetParentOrigin( Vector3( current.x, current.y, z ) );
636 const Vector3& Actor::GetCurrentParentOrigin() const
638 // Cached for event-thread access
639 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
642 void Actor::SetAnchorPoint(const Vector3& anchor)
646 // mNode is being used in a separate thread; queue a message to set the value & base value
647 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
650 // Cache for event-thread access
653 // not allocated, check if different from default
654 if( AnchorPoint::DEFAULT != anchor )
656 mAnchorPoint = new Vector3( anchor );
661 // check if different from current costs more than just set
662 *mAnchorPoint = anchor;
666 void Actor::SetAnchorPointX( float x )
668 const Vector3& current = GetCurrentAnchorPoint();
670 SetAnchorPoint( Vector3( x, current.y, current.z ) );
673 void Actor::SetAnchorPointY( float y )
675 const Vector3& current = GetCurrentAnchorPoint();
677 SetAnchorPoint( Vector3( current.x, y, current.z ) );
680 void Actor::SetAnchorPointZ( float z )
682 const Vector3& current = GetCurrentAnchorPoint();
684 SetAnchorPoint( Vector3( current.x, current.y, z ) );
687 const Vector3& Actor::GetCurrentAnchorPoint() const
689 // Cached for event-thread access
690 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
693 void Actor::SetPosition(float x, float y)
695 SetPosition(Vector3(x, y, 0.0f));
698 void Actor::SetPosition(float x, float y, float z)
700 SetPosition(Vector3(x, y, z));
703 void Actor::SetPosition(const Vector3& position)
707 // mNode is being used in a separate thread; queue a message to set the value & base value
708 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
712 void Actor::SetX(float x)
716 // mNode is being used in a separate thread; queue a message to set the value & base value
717 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
721 void Actor::SetY(float y)
725 // mNode is being used in a separate thread; queue a message to set the value & base value
726 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
730 void Actor::SetZ(float z)
734 // mNode is being used in a separate thread; queue a message to set the value & base value
735 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
739 void Actor::MoveBy(const Vector3& distance)
743 // mNode is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
748 const Vector3& Actor::GetCurrentPosition() const
752 // mNode is being used in a separate thread; copy the value from the previous update
753 return mNode->GetPosition(mStage->GetEventBufferIndex());
756 return Vector3::ZERO;
759 const Vector3& Actor::GetCurrentWorldPosition() const
763 // mNode is being used in a separate thread; copy the value from the previous update
764 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
767 return Vector3::ZERO;
770 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
772 // this flag is not animatable so keep the value
773 mPositionInheritanceMode = mode;
776 // mNode is being used in a separate thread; queue a message to set the value
777 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
781 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
783 // Cached for event-thread access
784 return mPositionInheritanceMode;
787 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
789 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
790 normalizedAxis.Normalize();
792 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
794 SetRotation(rotation);
797 void Actor::SetRotation(const Quaternion& rotation)
801 // mNode is being used in a separate thread; queue a message to set the value & base value
802 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
806 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
810 // mNode is being used in a separate thread; queue a message to set the value & base value
811 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
815 void Actor::RotateBy(const Quaternion& relativeRotation)
819 // mNode is being used in a separate thread; queue a message to set the value & base value
820 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
824 const Quaternion& Actor::GetCurrentRotation() const
828 // mNode is being used in a separate thread; copy the value from the previous update
829 return mNode->GetRotation(mStage->GetEventBufferIndex());
832 return Quaternion::IDENTITY;
835 const Quaternion& Actor::GetCurrentWorldRotation() const
839 // mNode is being used in a separate thread; copy the value from the previous update
840 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
843 return Quaternion::IDENTITY;
846 void Actor::SetScale(float scale)
848 SetScale(Vector3(scale, scale, scale));
851 void Actor::SetScale(float x, float y, float z)
853 SetScale(Vector3(x, y, z));
856 void Actor::SetScale(const Vector3& scale)
860 // mNode is being used in a separate thread; queue a message to set the value & base value
861 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
865 void Actor::SetScaleX( float x )
869 // mNode is being used in a separate thread; queue a message to set the value & base value
870 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
874 void Actor::SetScaleY( float y )
878 // mNode is being used in a separate thread; queue a message to set the value & base value
879 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
883 void Actor::SetScaleZ( float z )
887 // mNode is being used in a separate thread; queue a message to set the value & base value
888 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
892 void Actor::SetInitialVolume(const Vector3& volume)
896 // mNode is being used in a separate thread; queue a message to set the value
897 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
901 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
905 // mNode is being used in a separate thread; queue a message to set the value
906 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
910 bool Actor::GetTransmitGeometryScaling() const
914 // mNode is being used in a separate thread; copy the value from the previous update
915 return mNode->GetTransmitGeometryScaling();
921 void Actor::ScaleBy(const Vector3& relativeScale)
925 // mNode is being used in a separate thread; queue a message to set the value & base value
926 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
930 const Vector3& Actor::GetCurrentScale() const
934 // mNode is being used in a separate thread; copy the value from the previous update
935 return mNode->GetScale(mStage->GetEventBufferIndex());
941 const Vector3& Actor::GetCurrentWorldScale() const
945 // mNode is being used in a separate thread; copy the value from the previous update
946 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
952 void Actor::SetInheritScale( bool inherit )
954 // non animateable so keep local copy
955 mInheritScale = inherit;
958 // mNode is being used in a separate thread; queue a message to set the value
959 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
963 bool Actor::IsScaleInherited() const
965 return mInheritScale;
968 Matrix Actor::GetCurrentWorldMatrix() const
972 // World matrix is no longer updated unless there is something observing the node.
973 // Need to calculate it from node's world position, rotation and scale:
974 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
975 Matrix worldMatrix(false);
976 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
977 mNode->GetWorldRotation( updateBufferIndex ),
978 mNode->GetWorldPosition( updateBufferIndex ) );
982 return Matrix::IDENTITY;
985 void Actor::SetVisible(bool visible)
989 // mNode is being used in a separate thread; queue a message to set the value & base value
990 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
994 bool Actor::IsVisible() const
998 // mNode is being used in a separate thread; copy the value from the previous update
999 return mNode->IsVisible( mStage->GetEventBufferIndex() );
1005 void Actor::SetOpacity(float opacity)
1009 // mNode is being used in a separate thread; queue a message to set the value & base value
1010 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1014 void Actor::OpacityBy(float relativeOpacity)
1018 // mNode is being used in a separate thread; queue a message to set the value & base value
1019 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
1023 float Actor::GetCurrentOpacity() const
1027 // mNode is being used in a separate thread; copy the value from the previous update
1028 return mNode->GetOpacity(mStage->GetEventBufferIndex());
1034 const Vector4& Actor::GetCurrentWorldColor() const
1038 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
1041 return Color::WHITE;
1044 void Actor::SetColor(const Vector4& color)
1048 // mNode is being used in a separate thread; queue a message to set the value & base value
1049 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1053 void Actor::SetColorRed( float red )
1057 // mNode is being used in a separate thread; queue a message to set the value & base value
1058 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1062 void Actor::SetColorGreen( float green )
1066 // mNode is being used in a separate thread; queue a message to set the value & base value
1067 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1071 void Actor::SetColorBlue( float blue )
1075 // mNode is being used in a separate thread; queue a message to set the value & base value
1076 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1080 void Actor::ColorBy(const Vector4& relativeColor)
1084 // mNode is being used in a separate thread; queue a message to set the value & base value
1085 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1089 const Vector4& Actor::GetCurrentColor() const
1093 // mNode is being used in a separate thread; copy the value from the previous update
1094 return mNode->GetColor(mStage->GetEventBufferIndex());
1097 return Color::WHITE;
1100 void Actor::SetInheritRotation(bool inherit)
1102 // non animateable so keep local copy
1103 mInheritRotation = inherit;
1106 // mNode is being used in a separate thread; queue a message to set the value
1107 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1111 bool Actor::IsRotationInherited() const
1113 return mInheritRotation;
1116 void Actor::SetColorMode(ColorMode colorMode)
1118 // non animateable so keep local copy
1119 mColorMode = colorMode;
1122 // mNode is being used in a separate thread; queue a message to set the value
1123 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1127 ColorMode Actor::GetColorMode() const
1129 // we have cached copy
1133 void Actor::SetSize(float width, float height)
1135 SetSize( Vector2( width, height ) );
1138 void Actor::SetSize(float width, float height, float depth)
1140 SetSize( Vector3( width, height, depth ) );
1143 void Actor::SetSize(const Vector2& size)
1145 Vector3 volume( size );
1146 volume.z = std::min( size.width, size.height );
1150 void Actor::SetSize(const Vector3& size)
1154 // mNode is being used in a separate thread; queue a message to set the value & base value
1155 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1157 // Notification for derived classes
1160 // Emit signal for application developer
1162 if( !mSetSizeSignalV2.Empty() )
1164 Dali::Actor handle( this );
1165 mSetSizeSignalV2.Emit( handle, size );
1170 void Actor::SetWidth( float width )
1174 // mNode is being used in a separate thread; queue a message to set the value & base value
1175 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1179 void Actor::SetHeight( float height )
1183 // mNode is being used in a separate thread; queue a message to set the value & base value
1184 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1188 void Actor::SetDepth( float depth )
1192 // mNode is being used in a separate thread; queue a message to set the value & base value
1193 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1197 const Vector3& Actor::GetCurrentSize() const
1201 // mNode is being used in a separate thread; copy the value from the previous update
1202 return mNode->GetSize( mStage->GetEventBufferIndex() );
1205 return Vector3::ZERO;
1208 void Actor::SetInheritShaderEffect(bool inherit)
1212 // mNode is being used in a separate thread; queue a message to set the value
1213 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1217 bool Actor::GetInheritShaderEffect() const
1221 // mNode is being used in a separate thread; copy the value from the previous update
1222 return mNode->GetInheritShader();
1228 void Actor::SetShaderEffect(ShaderEffect& effect)
1234 mShaderEffect->Disconnect();
1237 mShaderEffect = ShaderEffectPtr(&effect);
1239 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1243 // mNode is being used in a separate thread; queue a message to apply shader
1244 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1247 mShaderEffect->Connect();
1251 mShaderEffect = ShaderEffectPtr(&effect);
1253 // Effects can only be applied when the Node is connected to scene-graph
1256 ShaderEffectPtr Actor::GetShaderEffect() const
1258 return mShaderEffect;
1261 void Actor::RemoveShaderEffect()
1267 // mNode is being used in a separate thread; queue a message to remove shader
1268 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1271 // Notify shader effect
1274 mShaderEffect->Disconnect();
1278 mShaderEffect.Reset();
1281 #ifdef DYNAMICS_SUPPORT
1283 //--------------- Dynamics ---------------
1285 void Actor::DisableDynamics()
1287 if( NULL != mDynamicsData )
1289 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1291 // ensure dynamics object are disconnected from scene
1292 DisconnectDynamics();
1294 // delete joint owned by this actor
1295 while( !mDynamicsData->joints.empty() )
1297 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1300 // delete other joints referencing this actor
1301 while( !mDynamicsData->referencedJoints.empty() )
1303 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1304 ActorPtr jointOwner( joint->GetActor( true ) );
1307 jointOwner->RemoveDynamicsJoint( joint );
1311 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1314 // delete the DynamicsBody object
1315 mDynamicsData->body.Reset();
1317 // Discard Dynamics data structure
1318 delete mDynamicsData;
1319 mDynamicsData = NULL;
1323 DynamicsBodyPtr Actor::GetDynamicsBody() const
1325 DynamicsBodyPtr body;
1327 if( NULL != mDynamicsData )
1329 body = mDynamicsData->body;
1335 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1337 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1339 if( NULL == mDynamicsData )
1341 mDynamicsData = new DynamicsData( this );
1344 if( !mDynamicsData->body )
1346 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1350 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1353 if( mParent == world->GetRootActor().Get() )
1355 mDynamicsData->body->Connect(*mStage);
1361 return mDynamicsData->body;
1364 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1366 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1367 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1370 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1372 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1373 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1375 DynamicsJointPtr joint;
1377 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1381 if( NULL != mDynamicsData )
1383 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1385 if( mDynamicsData->joints.end() != it )
1387 // use existing joint
1393 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1394 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1398 bodyA = EnableDynamics( new DynamicsBodyConfig );
1403 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1406 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1407 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1409 if( OnStage() && attachedActor->OnStage() )
1411 joint->Connect(*mStage);
1414 attachedActor->ReferenceJoint( joint );
1416 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1417 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1424 const int Actor::GetNumberOfJoints() const
1426 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1429 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1431 DynamicsJointPtr joint;
1433 if( NULL != mDynamicsData )
1435 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1437 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1439 for( int i = 0; i < index; ++i )
1451 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1453 DynamicsJointPtr joint;
1455 if( NULL != mDynamicsData )
1457 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1459 if( mDynamicsData->joints.end() != it )
1461 // use existing joint
1469 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1471 if( NULL != mDynamicsData )
1473 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1474 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1476 for( ; it != endIt; ++it )
1478 if( it->second == joint.Get() )
1480 ActorPtr attachedActor( it->first );
1482 if( OnStage() && attachedActor && attachedActor->OnStage() )
1484 joint->Disconnect(*mStage);
1489 attachedActor->ReleaseJoint( joint );
1490 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1491 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1494 mDynamicsData->joints.erase(it);
1501 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1503 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1505 if( NULL != mDynamicsData )
1507 mDynamicsData->referencedJoints.push_back(joint);
1511 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1513 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1515 if( NULL != mDynamicsData )
1517 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1519 if( it != mDynamicsData->referencedJoints.end() )
1521 mDynamicsData->referencedJoints.erase( it );
1526 void Actor::SetDynamicsRoot(bool flag)
1528 if( mIsDynamicsRoot != flag )
1530 mIsDynamicsRoot = flag;
1532 if( OnStage() && mChildren )
1534 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1535 ActorIter end = mChildren->end();
1536 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1538 Actor& child = GetImplementation(*iter);
1540 if( child.GetDynamicsBody() )
1542 if( mIsDynamicsRoot )
1544 child.ConnectDynamics();
1548 child.DisconnectDynamics();
1556 bool Actor::IsDynamicsRoot() const
1558 return mIsDynamicsRoot;
1561 void Actor::AttachedActorOnStage( Dali::Actor actor )
1563 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1567 ActorPtr attachedActor( &GetImplementation(actor) );
1569 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1570 if( NULL != mDynamicsData )
1572 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1573 if( mDynamicsData->joints.end() != it )
1575 DynamicsJointPtr joint( it->second );
1576 joint->Connect(*mStage);
1582 void Actor::AttachedActorOffStage( Dali::Actor actor )
1584 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1588 ActorPtr attachedActor( &GetImplementation(actor) );
1590 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1591 if( NULL != mDynamicsData )
1593 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1594 if( mDynamicsData->joints.end() != it )
1596 DynamicsJointPtr joint( it->second );
1597 joint->Disconnect(*mStage);
1603 void Actor::ConnectDynamics()
1605 if( NULL != mDynamicsData && mDynamicsData->body )
1607 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1609 mDynamicsData->body->Connect(*mStage);
1611 // Connect all joints where attachedActor is also on stage
1612 if( !mDynamicsData->joints.empty() )
1614 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1615 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1617 for( ; it != endIt; ++it )
1619 Actor* attachedActor( it->first );
1620 if( NULL != attachedActor && attachedActor->OnStage() )
1622 DynamicsJointPtr joint( it->second );
1624 joint->Connect(*mStage);
1632 void Actor::DisconnectDynamics()
1634 if( NULL != mDynamicsData && mDynamicsData->body )
1638 mDynamicsData->body->Disconnect(*mStage);
1640 // Disconnect all joints
1641 if( !mDynamicsData->joints.empty() )
1643 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1644 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1646 for( ; it != endIt; ++it )
1648 DynamicsJointPtr joint( it->second );
1650 joint->Disconnect(*mStage);
1657 #endif // DYNAMICS_SUPPORT
1659 void Actor::SetOverlay(bool enable)
1661 // Setting STENCIL will override OVERLAY
1662 if( DrawMode::STENCIL != mDrawMode )
1664 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1668 bool Actor::IsOverlay() const
1670 return ( DrawMode::OVERLAY == mDrawMode );
1673 void Actor::SetDrawMode( DrawMode::Type drawMode )
1675 // this flag is not animatable so keep the value
1676 mDrawMode = drawMode;
1679 // mNode is being used in a separate thread; queue a message to set the value
1680 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1684 DrawMode::Type Actor::GetDrawMode() const
1689 bool Actor::ScreenToLocal( float& localX,
1692 float screenY ) const
1694 // only valid when on-stage
1697 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1699 Vector2 converted( screenX, screenY );
1701 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1702 const int taskCount = taskList.GetTaskCount();
1703 for( int i = taskCount - 1; i >= 0; --i )
1705 Dali::RenderTask task = taskList.GetTask( i );
1706 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1708 // found a task where this conversion was ok so return
1716 bool Actor::ScreenToLocal( RenderTask& renderTask,
1720 float screenY ) const
1722 bool retval = false;
1723 // only valid when on-stage
1726 CameraActor* camera = renderTask.GetCameraActor();
1730 renderTask.GetViewport( viewport );
1732 // need to translate coordinates to render tasks coordinate space
1733 Vector2 converted( screenX, screenY );
1734 if( renderTask.TranslateCoordinates( converted ) )
1736 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1743 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1744 const Matrix& projectionMatrix,
1745 const Viewport& viewport,
1749 float screenY ) const
1751 // Early-out if mNode is NULL
1757 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1759 // Calculate the ModelView matrix
1760 Matrix modelView(false/*don't init*/);
1761 // need to use the components as world matrix is only updated for actors that need it
1762 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1763 Matrix::Multiply(modelView, modelView, viewMatrix);
1765 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1766 Matrix invertedMvp(false/*don't init*/);
1767 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1768 bool success = invertedMvp.Invert();
1770 // Convert to GL coordinates
1771 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1776 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1783 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1789 if (XyPlaneIntersect(nearPos, farPos, local))
1791 Vector3 size = GetCurrentSize();
1792 localX = local.x + size.x * 0.5f;
1793 localY = local.y + size.y * 0.5f;
1804 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1807 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1809 Mathematical Formulation
1811 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1813 ( p - c ) dot ( p - c ) = r^2
1815 Given a ray with a point of origin 'o', and a direction vector 'd':
1817 ray(t) = o + td, t >= 0
1819 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1821 (o + td - c ) dot ( o + td - c ) = r^2
1823 To solve for t we first expand the above into a more recognisable quadratic equation form
1825 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1834 B = 2( o - c ) dot d
1835 C = ( o - c ) dot ( o - c ) - r^2
1837 which can be solved using a standard quadratic formula.
1839 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1841 Practical Simplification
1843 In a renderer, we often differentiate between world space and object space. In the object space
1844 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1845 into object space, the mathematical solution presented above can be simplified significantly.
1847 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1851 and we can find the t at which the (transformed) ray intersects the sphere by
1853 ( o + td ) dot ( o + td ) = r^2
1855 According to the reasoning above, we expand the above quadratic equation into the general form
1859 which now has coefficients:
1866 // Early out if mNode is NULL
1872 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1874 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1875 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1876 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1877 rayOrigin.y - translation.y,
1878 rayOrigin.z - translation.z);
1880 // Compute the radius is not needed, square radius it's enough.
1881 const Vector3& size( mNode->GetSize( bufferIndex ) );
1883 // Scale the sphere.
1884 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1886 const float width = size.width * scale.width;
1887 const float height = size.height * scale.height;
1889 float squareSphereRadius = 0.5f * ( width * width + height * height );
1891 float a = rayDir.Dot( rayDir ); // a
1892 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1893 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1895 return ( b2*b2 - a*c ) >= 0.f;
1898 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1905 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1907 // Transforms the ray to the local reference system.
1909 // Calculate the inverse of Model matrix
1910 Matrix invModelMatrix(false/*don't init*/);
1911 // need to use the components as world matrix is only updated for actors that need it
1912 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1914 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1915 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1917 // Test with the actor's XY plane (Normal = 0 0 1 1).
1919 float a = -rayOriginLocal.z;
1920 float b = rayDirLocal.z;
1922 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1924 // Ray travels distance * rayDirLocal to intersect with plane.
1927 const Vector3& size = mNode->GetSize( bufferIndex );
1929 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1930 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1932 // Test with the actor's geometry.
1933 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1940 void Actor::SetLeaveRequired(bool required)
1942 mLeaveRequired = required;
1945 bool Actor::GetLeaveRequired() const
1947 return mLeaveRequired;
1950 void Actor::SetKeyboardFocusable( bool focusable )
1952 mKeyboardFocusable = focusable;
1955 bool Actor::IsKeyboardFocusable() const
1957 return mKeyboardFocusable;
1960 bool Actor::GetTouchRequired() const
1962 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1965 bool Actor::GetMouseWheelEventRequired() const
1967 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1970 bool Actor::IsHittable() const
1972 return IsSensitive() &&
1974 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1978 void Actor::AddGestureDetector( GestureDetector& detector )
1980 if ( NULL == mGestureData )
1982 mGestureData = new GestureData;
1985 const Gesture::Type type( detector.GetType() );
1990 mGestureData->AddDetector< PanGestureDetector, PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
1994 case Gesture::Pinch:
1996 mGestureData->AddDetector< PinchGestureDetector, PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
2000 case Gesture::LongPress:
2002 mGestureData->AddDetector< LongPressGestureDetector, LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
2008 mGestureData->AddDetector< TapGestureDetector, TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
2014 void Actor::RemoveGestureDetector( GestureDetector& detector )
2016 if ( NULL != mGestureData )
2018 switch ( detector.GetType() )
2022 mGestureData->RemoveDetector< PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
2026 case Gesture::Pinch:
2028 mGestureData->RemoveDetector< PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
2032 case Gesture::LongPress:
2034 mGestureData->RemoveDetector< LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
2040 mGestureData->RemoveDetector< TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
2045 if ( mGestureData->Empty() )
2047 delete mGestureData;
2048 mGestureData = NULL;
2053 bool Actor::IsGestureRequred( Gesture::Type type ) const
2055 bool required( false );
2056 if ( NULL != mGestureData )
2058 required = type & mGestureData->gesturesRequired;
2063 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
2065 bool consumed = false;
2067 if ( !mTouchedSignalV2.Empty() )
2069 Dali::Actor handle( this );
2070 consumed = mTouchedSignalV2.Emit( handle, event );
2075 // Notification for derived classes
2076 consumed = OnTouchEvent( event );
2082 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
2084 bool consumed = false;
2086 if ( !mMouseWheelEventSignalV2.Empty() )
2088 Dali::Actor handle( this );
2089 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
2094 // Notification for derived classes
2095 consumed = OnMouseWheelEvent(event);
2101 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
2103 return mTouchedSignalV2;
2106 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
2108 return mMouseWheelEventSignalV2;
2111 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
2113 return mSetSizeSignalV2;
2116 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
2118 return mOnStageSignalV2;
2121 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
2123 return mOffStageSignalV2;
2126 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2128 bool connected( true );
2129 Actor* actor = dynamic_cast<Actor*>(object);
2131 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
2133 actor->TouchedSignal().Connect( tracker, functor );
2135 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
2137 actor->MouseWheelEventSignal().Connect( tracker, functor );
2139 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
2141 actor->SetSizeSignal().Connect( tracker, functor );
2143 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
2145 actor->OnStageSignal().Connect( tracker, functor );
2147 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
2149 actor->OffStageSignal().Connect( tracker, functor );
2153 // signalName does not match any signal
2160 Actor::Actor( DerivedType derivedType )
2165 mParentOrigin( NULL ),
2166 mAnchorPoint( NULL ),
2167 #ifdef DYNAMICS_SUPPORT
2168 mDynamicsData( NULL ),
2170 mGestureData( NULL ),
2174 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2175 mIsRoot( ROOT_LAYER == derivedType ),
2176 mIsRenderable( RENDERABLE == derivedType ),
2177 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2178 mIsOnStage( false ),
2179 mIsDynamicsRoot(false),
2181 mLeaveRequired( false ),
2182 mKeyboardFocusable( false ),
2183 mDerivedRequiresTouch( false ),
2184 mDerivedRequiresMouseWheelEvent( false ),
2185 mOnStageSignalled( false ),
2186 mInheritRotation( true ),
2187 mInheritScale( true ),
2188 mDrawMode( DrawMode::NORMAL ),
2189 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2190 mColorMode( Node::DEFAULT_COLOR_MODE )
2194 void Actor::Initialize()
2196 mStage = Stage::GetCurrent();
2199 SceneGraph::Node* node = CreateNode();
2201 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2202 mNode = node; // Keep raw-pointer to Node
2204 if(!mDefaultPropertyLookup)
2206 mDefaultPropertyLookup = new DefaultPropertyLookup();
2208 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2210 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2221 // Remove mParent pointers from children even if we're destroying core,
2222 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2225 ActorConstIter endIter = mChildren->end();
2226 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2228 Actor& actor = GetImplementation( *iter );
2229 actor.SetParent( NULL );
2234 // Guard to allow handle destruction after Core has been destroyed
2235 if( Stage::IsInstalled() )
2239 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2240 mNode = NULL; // Node is about to be destroyed
2246 #ifdef DYNAMICS_SUPPORT
2248 delete mDynamicsData;
2251 // Cleanup optional gesture data
2252 delete mGestureData;
2254 // Cleanup optional parent origin and anchor
2255 delete mParentOrigin;
2256 delete mAnchorPoint;
2259 void Actor::ConnectToStage( Stage& stage )
2261 // This container is used instead of walking the Actor hierachy.
2262 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2263 ActorContainer connectionList;
2265 // This stage is atomic i.e. not interrupted by user callbacks
2266 RecursiveConnectToStage( stage, connectionList );
2268 // Notify applications about the newly connected actors.
2269 const ActorIter endIter = connectionList.end();
2270 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2272 Actor& actor = GetImplementation(*iter);
2273 actor.NotifyStageConnection();
2277 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2279 DALI_ASSERT_ALWAYS( !OnStage() );
2283 ConnectToSceneGraph();
2285 // Notification for internal derived classes
2286 OnStageConnectionInternal();
2288 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2289 connectionList.push_back( Dali::Actor(this) );
2291 // Recursively connect children
2294 ActorConstIter endIter = mChildren->end();
2295 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2297 Actor& actor = GetImplementation( *iter );
2298 actor.RecursiveConnectToStage( stage, connectionList );
2304 * This method is called when the Actor is connected to the Stage.
2305 * The parent must have added its Node to the scene-graph.
2306 * The child must connect its Node to the parent's Node.
2307 * This is resursive; the child calls ConnectToStage() for its children.
2309 void Actor::ConnectToSceneGraph()
2311 DALI_ASSERT_DEBUG( mNode != NULL);
2312 DALI_ASSERT_DEBUG( mParent != NULL);
2313 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2317 // Reparent Node in next Update
2318 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2323 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2327 // Effects can only be applied when the node is on-stage
2328 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2331 // Notify shader effect
2332 mShaderEffect->Connect();
2335 // Notify attachment
2338 mAttachment->Connect();
2341 #ifdef DYNAMICS_SUPPORT
2343 if( NULL != mDynamicsData )
2349 // Notification for ProxyObject::Observers
2353 void Actor::NotifyStageConnection()
2355 // Actors can be removed (in a callback), before the on-stage stage is reported.
2356 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2357 if ( OnStage() && !mOnStageSignalled )
2359 // Notification for external (CustomActor) derived classes
2360 OnStageConnectionExternal();
2362 if ( !mOnStageSignalV2.Empty() )
2364 Dali::Actor handle( this );
2365 mOnStageSignalV2.Emit( handle );
2368 // Guard against Remove during callbacks
2371 mOnStageSignalled = true; // signal required next time Actor is removed
2376 void Actor::DisconnectFromStage()
2378 // This container is used instead of walking the Actor hierachy.
2379 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2380 ActorContainer disconnectionList;
2382 // This stage is atomic i.e. not interrupted by user callbacks
2383 RecursiveDisconnectFromStage( disconnectionList );
2385 // Notify applications about the newly disconnected actors.
2386 const ActorIter endIter = disconnectionList.end();
2387 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2389 Actor& actor = GetImplementation(*iter);
2390 actor.NotifyStageDisconnection();
2394 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2396 DALI_ASSERT_ALWAYS( OnStage() );
2398 // Recursively disconnect children
2401 ActorConstIter endIter = mChildren->end();
2402 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2404 Actor& actor = GetImplementation( *iter );
2405 actor.RecursiveDisconnectFromStage( disconnectionList );
2409 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2410 disconnectionList.push_back( Dali::Actor(this) );
2412 // Notification for internal derived classes
2413 OnStageDisconnectionInternal();
2415 DisconnectFromSceneGraph();
2421 * This method is called by an actor or its parent, before a node removal message is sent.
2422 * This is recursive; the child calls DisconnectFromStage() for its children.
2424 void Actor::DisconnectFromSceneGraph()
2426 // Notification for ProxyObject::Observers
2427 OnSceneObjectRemove();
2429 // Notify shader effect
2432 mShaderEffect->Disconnect();
2435 // Notify attachment
2438 mAttachment->Disconnect();
2441 #ifdef DYNAMICS_SUPPORT
2443 if( NULL != mDynamicsData )
2445 DisconnectDynamics();
2450 void Actor::NotifyStageDisconnection()
2452 // Actors can be added (in a callback), before the off-stage state is reported.
2453 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2454 // only do this step if there is a stage, i.e. Core is not being shut down
2455 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2457 // Notification for external (CustomeActor) derived classes
2458 OnStageDisconnectionExternal();
2460 if( !mOffStageSignalV2.Empty() )
2462 Dali::Actor handle( this );
2463 mOffStageSignalV2.Emit( handle );
2466 // Guard against Add during callbacks
2469 mOnStageSignalled = false; // signal required next time Actor is added
2474 bool Actor::IsNodeConnected() const
2476 bool connected( false );
2481 if( mNode->IsRoot() || mNode->GetParent() )
2490 bool Actor::IsSceneObjectRemovable() const
2495 unsigned int Actor::GetDefaultPropertyCount() const
2497 return DEFAULT_PROPERTY_COUNT;
2500 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2502 indices.reserve( DEFAULT_PROPERTY_COUNT );
2504 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2506 indices.push_back( i );
2510 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2512 if( index < DEFAULT_PROPERTY_COUNT )
2514 return DEFAULT_PROPERTY_DETAILS[index].name;
2518 // index out of range..return empty string
2519 return String::EMPTY;
2523 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2525 Property::Index index = Property::INVALID_INDEX;
2527 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2529 // Look for name in default properties
2530 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2531 if ( mDefaultPropertyLookup->end() != result )
2533 index = result->second;
2539 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2541 if( index < DEFAULT_PROPERTY_COUNT )
2543 return DEFAULT_PROPERTY_DETAILS[index].writable;
2551 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2553 if( index < DEFAULT_PROPERTY_COUNT )
2555 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2563 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2565 if( index < DEFAULT_PROPERTY_COUNT )
2567 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2575 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2577 if( index < DEFAULT_PROPERTY_COUNT )
2579 return DEFAULT_PROPERTY_DETAILS[index].type;
2583 // index out of range...return Property::NONE
2584 return Property::NONE;
2588 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2592 case Dali::Actor::PARENT_ORIGIN:
2594 SetParentOrigin( property.Get<Vector3>() );
2598 case Dali::Actor::PARENT_ORIGIN_X:
2600 SetParentOriginX( property.Get<float>() );
2604 case Dali::Actor::PARENT_ORIGIN_Y:
2606 SetParentOriginY( property.Get<float>() );
2610 case Dali::Actor::PARENT_ORIGIN_Z:
2612 SetParentOriginZ( property.Get<float>() );
2616 case Dali::Actor::ANCHOR_POINT:
2618 SetAnchorPoint( property.Get<Vector3>() );
2622 case Dali::Actor::ANCHOR_POINT_X:
2624 SetAnchorPointX( property.Get<float>() );
2628 case Dali::Actor::ANCHOR_POINT_Y:
2630 SetAnchorPointY( property.Get<float>() );
2634 case Dali::Actor::ANCHOR_POINT_Z:
2636 SetAnchorPointZ( property.Get<float>() );
2640 case Dali::Actor::SIZE:
2642 SetSize( property.Get<Vector3>() );
2646 case Dali::Actor::SIZE_WIDTH:
2648 SetWidth( property.Get<float>() );
2652 case Dali::Actor::SIZE_HEIGHT:
2654 SetHeight( property.Get<float>() );
2658 case Dali::Actor::SIZE_DEPTH:
2660 SetDepth( property.Get<float>() );
2664 case Dali::Actor::POSITION:
2666 SetPosition( property.Get<Vector3>() );
2670 case Dali::Actor::POSITION_X:
2672 SetX( property.Get<float>() );
2676 case Dali::Actor::POSITION_Y:
2678 SetY( property.Get<float>() );
2682 case Dali::Actor::POSITION_Z:
2684 SetZ( property.Get<float>() );
2688 case Dali::Actor::ROTATION:
2690 SetRotation( property.Get<Quaternion>() );
2694 case Dali::Actor::SCALE:
2696 SetScale( property.Get<Vector3>() );
2700 case Dali::Actor::SCALE_X:
2702 SetScaleX( property.Get<float>() );
2706 case Dali::Actor::SCALE_Y:
2708 SetScaleY( property.Get<float>() );
2712 case Dali::Actor::SCALE_Z:
2714 SetScaleZ( property.Get<float>() );
2718 case Dali::Actor::VISIBLE:
2720 SetVisible( property.Get<bool>() );
2724 case Dali::Actor::COLOR:
2726 SetColor( property.Get<Vector4>() );
2730 case Dali::Actor::COLOR_RED:
2732 SetColorRed( property.Get<float>() );
2736 case Dali::Actor::COLOR_GREEN:
2738 SetColorGreen( property.Get<float>() );
2742 case Dali::Actor::COLOR_BLUE:
2744 SetColorBlue( property.Get<float>() );
2748 case Dali::Actor::COLOR_ALPHA:
2750 SetOpacity( property.Get<float>() );
2754 case Dali::Actor::NAME:
2756 SetName( property.Get<std::string>() );
2760 case Dali::Actor::SENSITIVE:
2762 SetSensitive( property.Get<bool>() );
2766 case Dali::Actor::LEAVE_REQUIRED:
2768 SetLeaveRequired( property.Get<bool>() );
2772 case Dali::Actor::INHERIT_SHADER_EFFECT:
2774 SetInheritShaderEffect( property.Get<bool>() );
2778 case Dali::Actor::INHERIT_ROTATION:
2780 SetInheritRotation( property.Get<bool>() );
2784 case Dali::Actor::INHERIT_SCALE:
2786 SetInheritScale( property.Get<bool>() );
2790 case Dali::Actor::COLOR_MODE:
2792 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2796 case Dali::Actor::POSITION_INHERITANCE:
2798 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2802 case Dali::Actor::DRAW_MODE:
2804 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2810 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2816 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2818 // TODO: This should be deprecated
2819 OnPropertySet(index, value);
2821 if(entry.IsAnimatable())
2823 // TODO: ADD MATRIX & MATRIX3 types
2825 switch ( entry.type )
2827 case Property::BOOLEAN:
2829 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2830 DALI_ASSERT_DEBUG( NULL != property );
2832 // property is being used in a separate thread; queue a message to set the property
2833 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2838 case Property::FLOAT:
2840 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2841 DALI_ASSERT_DEBUG( NULL != property );
2843 // property is being used in a separate thread; queue a message to set the property
2844 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2849 case Property::VECTOR2:
2851 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2852 DALI_ASSERT_DEBUG( NULL != property );
2854 // property is being used in a separate thread; queue a message to set the property
2855 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2860 case Property::VECTOR3:
2862 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2863 DALI_ASSERT_DEBUG( NULL != property );
2865 // property is being used in a separate thread; queue a message to set the property
2866 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2871 case Property::VECTOR4:
2873 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2874 DALI_ASSERT_DEBUG( NULL != property );
2876 // property is being used in a separate thread; queue a message to set the property
2877 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2882 case Property::ROTATION:
2884 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2885 DALI_ASSERT_DEBUG( NULL != property );
2887 // property is being used in a separate thread; queue a message to set the property
2888 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2895 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2902 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2904 Property::Value value;
2908 case Dali::Actor::PARENT_ORIGIN:
2910 value = GetCurrentParentOrigin();
2914 case Dali::Actor::PARENT_ORIGIN_X:
2916 value = GetCurrentParentOrigin().x;
2920 case Dali::Actor::PARENT_ORIGIN_Y:
2922 value = GetCurrentParentOrigin().y;
2926 case Dali::Actor::PARENT_ORIGIN_Z:
2928 value = GetCurrentParentOrigin().z;
2932 case Dali::Actor::ANCHOR_POINT:
2934 value = GetCurrentAnchorPoint();
2938 case Dali::Actor::ANCHOR_POINT_X:
2940 value = GetCurrentAnchorPoint().x;
2944 case Dali::Actor::ANCHOR_POINT_Y:
2946 value = GetCurrentAnchorPoint().y;
2950 case Dali::Actor::ANCHOR_POINT_Z:
2952 value = GetCurrentAnchorPoint().z;
2956 case Dali::Actor::SIZE:
2958 value = GetCurrentSize();
2962 case Dali::Actor::SIZE_WIDTH:
2964 value = GetCurrentSize().width;
2968 case Dali::Actor::SIZE_HEIGHT:
2970 value = GetCurrentSize().height;
2974 case Dali::Actor::SIZE_DEPTH:
2976 value = GetCurrentSize().depth;
2980 case Dali::Actor::POSITION:
2982 value = GetCurrentPosition();
2986 case Dali::Actor::POSITION_X:
2988 value = GetCurrentPosition().x;
2992 case Dali::Actor::POSITION_Y:
2994 value = GetCurrentPosition().y;
2998 case Dali::Actor::POSITION_Z:
3000 value = GetCurrentPosition().z;
3004 case Dali::Actor::WORLD_POSITION:
3006 value = GetCurrentWorldPosition();
3010 case Dali::Actor::WORLD_POSITION_X:
3012 value = GetCurrentWorldPosition().x;
3016 case Dali::Actor::WORLD_POSITION_Y:
3018 value = GetCurrentWorldPosition().y;
3022 case Dali::Actor::WORLD_POSITION_Z:
3024 value = GetCurrentWorldPosition().z;
3028 case Dali::Actor::ROTATION:
3030 value = GetCurrentRotation();
3034 case Dali::Actor::WORLD_ROTATION:
3036 value = GetCurrentWorldRotation();
3040 case Dali::Actor::SCALE:
3042 value = GetCurrentScale();
3046 case Dali::Actor::SCALE_X:
3048 value = GetCurrentScale().x;
3052 case Dali::Actor::SCALE_Y:
3054 value = GetCurrentScale().y;
3058 case Dali::Actor::SCALE_Z:
3060 value = GetCurrentScale().z;
3064 case Dali::Actor::WORLD_SCALE:
3066 value = GetCurrentWorldScale();
3070 case Dali::Actor::VISIBLE:
3072 value = IsVisible();
3076 case Dali::Actor::COLOR:
3078 value = GetCurrentColor();
3082 case Dali::Actor::COLOR_RED:
3084 value = GetCurrentColor().r;
3088 case Dali::Actor::COLOR_GREEN:
3090 value = GetCurrentColor().g;
3094 case Dali::Actor::COLOR_BLUE:
3096 value = GetCurrentColor().b;
3100 case Dali::Actor::COLOR_ALPHA:
3102 value = GetCurrentColor().a;
3106 case Dali::Actor::WORLD_COLOR:
3108 value = GetCurrentWorldColor();
3112 case Dali::Actor::WORLD_MATRIX:
3114 value = GetCurrentWorldMatrix();
3118 case Dali::Actor::NAME:
3124 case Dali::Actor::SENSITIVE:
3126 value = IsSensitive();
3130 case Dali::Actor::LEAVE_REQUIRED:
3132 value = GetLeaveRequired();
3136 case Dali::Actor::INHERIT_SHADER_EFFECT:
3138 value = GetInheritShaderEffect();
3142 case Dali::Actor::INHERIT_ROTATION:
3144 value = IsRotationInherited();
3148 case Dali::Actor::INHERIT_SCALE:
3150 value = IsScaleInherited();
3154 case Dali::Actor::COLOR_MODE:
3156 value = Scripting::GetColorMode( GetColorMode() );
3160 case Dali::Actor::POSITION_INHERITANCE:
3162 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3166 case Dali::Actor::DRAW_MODE:
3168 value = Scripting::GetDrawMode( GetDrawMode() );
3174 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3182 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3186 // mNode is being used in a separate thread; queue a message to add the property
3187 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3191 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3193 // This method should only return an object connected to the scene-graph
3194 return OnStage() ? mNode : NULL;
3197 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3199 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3201 const PropertyBase* property( NULL );
3203 // This method should only return a property of an object connected to the scene-graph
3209 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3211 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3213 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3215 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3217 else if( NULL != mNode )
3221 case Dali::Actor::SIZE:
3222 property = &mNode->mSize;
3225 case Dali::Actor::SIZE_WIDTH:
3226 property = &mNode->mSize;
3229 case Dali::Actor::SIZE_HEIGHT:
3230 property = &mNode->mSize;
3233 case Dali::Actor::SIZE_DEPTH:
3234 property = &mNode->mSize;
3237 case Dali::Actor::POSITION:
3238 property = &mNode->mPosition;
3241 case Dali::Actor::POSITION_X:
3242 property = &mNode->mPosition;
3245 case Dali::Actor::POSITION_Y:
3246 property = &mNode->mPosition;
3249 case Dali::Actor::POSITION_Z:
3250 property = &mNode->mPosition;
3253 case Dali::Actor::ROTATION:
3254 property = &mNode->mRotation;
3257 case Dali::Actor::SCALE:
3258 property = &mNode->mScale;
3261 case Dali::Actor::SCALE_X:
3262 property = &mNode->mScale;
3265 case Dali::Actor::SCALE_Y:
3266 property = &mNode->mScale;
3269 case Dali::Actor::SCALE_Z:
3270 property = &mNode->mScale;
3273 case Dali::Actor::VISIBLE:
3274 property = &mNode->mVisible;
3277 case Dali::Actor::COLOR:
3278 property = &mNode->mColor;
3281 case Dali::Actor::COLOR_RED:
3282 property = &mNode->mColor;
3285 case Dali::Actor::COLOR_GREEN:
3286 property = &mNode->mColor;
3289 case Dali::Actor::COLOR_BLUE:
3290 property = &mNode->mColor;
3293 case Dali::Actor::COLOR_ALPHA:
3294 property = &mNode->mColor;
3305 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3307 const PropertyInputImpl* property( NULL );
3309 // This method should only return a property of an object connected to the scene-graph
3315 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3317 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3319 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3321 property = entry->second.GetSceneGraphProperty();
3323 else if( NULL != mNode )
3327 case Dali::Actor::PARENT_ORIGIN:
3328 property = &mNode->mParentOrigin;
3331 case Dali::Actor::PARENT_ORIGIN_X:
3332 property = &mNode->mParentOrigin;
3335 case Dali::Actor::PARENT_ORIGIN_Y:
3336 property = &mNode->mParentOrigin;
3339 case Dali::Actor::PARENT_ORIGIN_Z:
3340 property = &mNode->mParentOrigin;
3343 case Dali::Actor::ANCHOR_POINT:
3344 property = &mNode->mAnchorPoint;
3347 case Dali::Actor::ANCHOR_POINT_X:
3348 property = &mNode->mAnchorPoint;
3351 case Dali::Actor::ANCHOR_POINT_Y:
3352 property = &mNode->mAnchorPoint;
3355 case Dali::Actor::ANCHOR_POINT_Z:
3356 property = &mNode->mAnchorPoint;
3359 case Dali::Actor::SIZE:
3360 property = &mNode->mSize;
3363 case Dali::Actor::SIZE_WIDTH:
3364 property = &mNode->mSize;
3367 case Dali::Actor::SIZE_HEIGHT:
3368 property = &mNode->mSize;
3371 case Dali::Actor::SIZE_DEPTH:
3372 property = &mNode->mSize;
3375 case Dali::Actor::POSITION:
3376 property = &mNode->mPosition;
3379 case Dali::Actor::POSITION_X:
3380 property = &mNode->mPosition;
3383 case Dali::Actor::POSITION_Y:
3384 property = &mNode->mPosition;
3387 case Dali::Actor::POSITION_Z:
3388 property = &mNode->mPosition;
3391 case Dali::Actor::WORLD_POSITION:
3392 property = &mNode->mWorldPosition;
3395 case Dali::Actor::WORLD_POSITION_X:
3396 property = &mNode->mWorldPosition;
3399 case Dali::Actor::WORLD_POSITION_Y:
3400 property = &mNode->mWorldPosition;
3403 case Dali::Actor::WORLD_POSITION_Z:
3404 property = &mNode->mWorldPosition;
3407 case Dali::Actor::ROTATION:
3408 property = &mNode->mRotation;
3411 case Dali::Actor::WORLD_ROTATION:
3412 property = &mNode->mWorldRotation;
3415 case Dali::Actor::SCALE:
3416 property = &mNode->mScale;
3419 case Dali::Actor::SCALE_X:
3420 property = &mNode->mScale;
3423 case Dali::Actor::SCALE_Y:
3424 property = &mNode->mScale;
3427 case Dali::Actor::SCALE_Z:
3428 property = &mNode->mScale;
3431 case Dali::Actor::WORLD_SCALE:
3432 property = &mNode->mWorldScale;
3435 case Dali::Actor::VISIBLE:
3436 property = &mNode->mVisible;
3439 case Dali::Actor::COLOR:
3440 property = &mNode->mColor;
3443 case Dali::Actor::COLOR_RED:
3444 property = &mNode->mColor;
3447 case Dali::Actor::COLOR_GREEN:
3448 property = &mNode->mColor;
3451 case Dali::Actor::COLOR_BLUE:
3452 property = &mNode->mColor;
3455 case Dali::Actor::COLOR_ALPHA:
3456 property = &mNode->mColor;
3459 case Dali::Actor::WORLD_COLOR:
3460 property = &mNode->mWorldColor;
3463 case Dali::Actor::WORLD_MATRIX:
3464 property = &mNode->mWorldMatrix;
3475 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3477 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3481 case Dali::Actor::PARENT_ORIGIN_X:
3482 case Dali::Actor::ANCHOR_POINT_X:
3483 case Dali::Actor::SIZE_WIDTH:
3484 case Dali::Actor::POSITION_X:
3485 case Dali::Actor::SCALE_X:
3486 case Dali::Actor::COLOR_RED:
3487 case Dali::Actor::WORLD_POSITION_X:
3493 case Dali::Actor::PARENT_ORIGIN_Y:
3494 case Dali::Actor::ANCHOR_POINT_Y:
3495 case Dali::Actor::SIZE_HEIGHT:
3496 case Dali::Actor::POSITION_Y:
3497 case Dali::Actor::SCALE_Y:
3498 case Dali::Actor::COLOR_GREEN:
3499 case Dali::Actor::WORLD_POSITION_Y:
3505 case Dali::Actor::PARENT_ORIGIN_Z:
3506 case Dali::Actor::ANCHOR_POINT_Z:
3507 case Dali::Actor::SIZE_DEPTH:
3508 case Dali::Actor::POSITION_Z:
3509 case Dali::Actor::SCALE_Z:
3510 case Dali::Actor::COLOR_BLUE:
3511 case Dali::Actor::WORLD_POSITION_Z:
3517 case Dali::Actor::COLOR_ALPHA:
3530 return componentIndex;
3533 void Actor::SetParent(Actor* parent)
3537 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3541 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3544 StagePtr stage = parent->mStage;
3546 // Instruct each actor to create a corresponding node in the scene graph
3547 ConnectToStage(*stage);
3550 else // parent being set to NULL
3552 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3556 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3559 DALI_ASSERT_ALWAYS(mNode != NULL);
3563 // Disconnect the Node & its children from the scene-graph.
3564 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3567 // Instruct each actor to discard pointers to the scene-graph
3568 DisconnectFromStage();
3573 SceneGraph::Node* Actor::CreateNode() const
3578 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3581 Actor* actor = dynamic_cast<Actor*>(object);
3585 if(Dali::Actor::ACTION_SHOW == actionName)
3587 actor->SetVisible(true);
3590 else if(Dali::Actor::ACTION_HIDE == actionName)
3592 actor->SetVisible(false);
3600 } // namespace Internal