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>
33 #include <dali/internal/common/internal-constants.h>
34 #include <dali/internal/event/render-tasks/render-task-impl.h>
35 #include <dali/internal/event/actors/camera-actor-impl.h>
36 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
37 #include <dali/internal/event/common/property-index-ranges.h>
38 #include <dali/internal/event/common/stage-impl.h>
39 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
40 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
41 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
42 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
43 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
44 #include <dali/internal/event/animation/constraint-impl.h>
45 #include <dali/internal/event/common/projection.h>
46 #include <dali/internal/update/common/animatable-property.h>
47 #include <dali/internal/update/common/property-owner-messages.h>
48 #include <dali/internal/update/nodes/node-messages.h>
49 #include <dali/internal/update/animation/scene-graph-constraint.h>
50 #include <dali/internal/event/effects/shader-effect-impl.h>
51 #include <dali/internal/common/message.h>
52 #include <dali/integration-api/debug.h>
55 #include <dali/internal/update/nodes/node-declarations.h>
57 using Dali::Internal::SceneGraph::Node;
58 using Dali::Internal::SceneGraph::AnimatableProperty;
59 using Dali::Internal::SceneGraph::PropertyBase;
60 using Dali::Internal::SceneGraph::Shader;
67 const Property::Index Actor::PARENT_ORIGIN = 0;
68 const Property::Index Actor::PARENT_ORIGIN_X = 1;
69 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
70 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
71 const Property::Index Actor::ANCHOR_POINT = 4;
72 const Property::Index Actor::ANCHOR_POINT_X = 5;
73 const Property::Index Actor::ANCHOR_POINT_Y = 6;
74 const Property::Index Actor::ANCHOR_POINT_Z = 7;
75 const Property::Index Actor::SIZE = 8;
76 const Property::Index Actor::SIZE_WIDTH = 9;
77 const Property::Index Actor::SIZE_HEIGHT = 10;
78 const Property::Index Actor::SIZE_DEPTH = 11;
79 const Property::Index Actor::POSITION = 12;
80 const Property::Index Actor::POSITION_X = 13;
81 const Property::Index Actor::POSITION_Y = 14;
82 const Property::Index Actor::POSITION_Z = 15;
83 const Property::Index Actor::WORLD_POSITION = 16;
84 const Property::Index Actor::WORLD_POSITION_X = 17;
85 const Property::Index Actor::WORLD_POSITION_Y = 18;
86 const Property::Index Actor::WORLD_POSITION_Z = 19;
87 const Property::Index Actor::ROTATION = 20;
88 const Property::Index Actor::WORLD_ROTATION = 21;
89 const Property::Index Actor::SCALE = 22;
90 const Property::Index Actor::SCALE_X = 23;
91 const Property::Index Actor::SCALE_Y = 24;
92 const Property::Index Actor::SCALE_Z = 25;
93 const Property::Index Actor::WORLD_SCALE = 26;
94 const Property::Index Actor::VISIBLE = 27;
95 const Property::Index Actor::COLOR = 28;
96 const Property::Index Actor::COLOR_RED = 29;
97 const Property::Index Actor::COLOR_GREEN = 30;
98 const Property::Index Actor::COLOR_BLUE = 31;
99 const Property::Index Actor::COLOR_ALPHA = 32;
100 const Property::Index Actor::WORLD_COLOR = 33;
101 const Property::Index Actor::WORLD_MATRIX = 34;
102 const Property::Index Actor::NAME = 35;
104 namespace // unnamed namespace
107 /// An empty string returned for invalid property name lookups
108 const std::string INVALID_PROPERTY_NAME;
111 * We want to discourage the use of property strings (minimize string comparisons),
112 * particularly for the default properties.
114 const std::string DEFAULT_PROPERTY_NAMES[] =
153 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_NAMES ) / sizeof( std::string );
155 const Property::Type DEFAULT_PROPERTY_TYPES[DEFAULT_PROPERTY_COUNT] =
157 Property::VECTOR3, // PARENT_ORIGIN
158 Property::FLOAT, // PARENT_ORIGIN_X
159 Property::FLOAT, // PARENT_ORIGIN_Y
160 Property::FLOAT, // PARENT_ORIGIN_Z
161 Property::VECTOR3, // ANCHOR_POINT
162 Property::FLOAT, // ANCHOR_POINT_X
163 Property::FLOAT, // ANCHOR_POINT_Y
164 Property::FLOAT, // ANCHOR_POINT_Z
165 Property::VECTOR3, // SIZE
166 Property::FLOAT, // SIZE_WIDTH
167 Property::FLOAT, // SIZE_HEIGHT
168 Property::FLOAT, // SIZE_DEPTH
169 Property::VECTOR3, // POSITION
170 Property::FLOAT, // POSITION_X
171 Property::FLOAT, // POSITION_Y
172 Property::FLOAT, // POSITION_Z
173 Property::VECTOR3, // WORLD_POSITION
174 Property::FLOAT, // WORLD_POSITION_X
175 Property::FLOAT, // WORLD_POSITION_Y
176 Property::FLOAT, // WORLD_POSITION_Z
177 Property::ROTATION, // ROTATION
178 Property::ROTATION, // WORLD_ROTATION
179 Property::VECTOR3, // SCALE
180 Property::FLOAT, // SCALE_X
181 Property::FLOAT, // SCALE_Y
182 Property::FLOAT, // SCALE_Z
183 Property::VECTOR3, // WORLD_SCALE
184 Property::BOOLEAN, // VISIBLE
185 Property::VECTOR4, // COLOR
186 Property::FLOAT, // COLOR_RED
187 Property::FLOAT, // COLOR_GREEN
188 Property::FLOAT, // COLOR_BLUE
189 Property::FLOAT, // COLOR_ALPHA
190 Property::VECTOR4, // WORLD_COLOR
191 Property::MATRIX, // WORLD_MATRIX
192 Property::STRING, // NAME
195 } // unnamed namespace
200 unsigned int Actor::mActorCounter = 0;
201 ActorContainer Actor::mNullChildren;
203 // Encapsulate actor related dynamics data
206 DynamicsData( Actor* slotOwner )
207 : slotDelegate( slotOwner )
211 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
212 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
214 DynamicsBodyPtr body;
215 JointContainer joints;
216 ReferencedJointContainer referencedJoints;
218 SlotDelegate< Actor > slotDelegate;
224 using namespace Dali;
226 BaseHandle CreateActor()
228 return Dali::Actor::New();
231 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
233 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
234 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
235 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
236 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
238 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
239 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
243 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
245 ActorPtr Actor::New()
247 ActorPtr actor( new Actor( BASIC ) );
249 // Second-phase construction
255 const std::string& Actor::GetName() const
260 void Actor::SetName(const std::string& name)
266 // ATTENTION: string for debug purposes is not thread safe.
267 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
271 unsigned int Actor::GetId() const
276 void Actor::Attach( ActorAttachment& attachment )
278 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
282 attachment.Connect();
285 mAttachment = ActorAttachmentPtr(&attachment);
288 ActorAttachmentPtr Actor::GetAttachment()
293 bool Actor::OnStage() const
298 Dali::Layer Actor::GetLayer()
302 // Short-circuit for Layer derived actors
305 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
308 // Find the immediate Layer parent
309 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
311 if( parent->IsLayer() )
313 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
320 void Actor::Add(Actor& child)
322 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
323 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
327 mChildren = new ActorContainer;
330 Actor* const oldParent( child.mParent );
332 // child might already be ours
333 if( this != oldParent )
335 // if we already have parent, unparent us first
338 oldParent->Remove( child ); // This causes OnChildRemove callback
341 // Guard against Add() during previous OnChildRemove callback
342 if ( !child.mParent )
344 // Do this first, since user callbacks from within SetParent() may need to remove child
345 mChildren->push_back(Dali::Actor(&child));
347 // SetParent asserts that child can be added
348 child.SetParent(this);
350 // Notification for derived classes
356 void Actor::Remove(Actor& child)
358 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
368 // Find the child in mChildren, and unparent it
369 ActorIter end = mChildren->end();
370 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
372 Actor& actor = GetImplementation(*iter);
374 if( &actor == &child )
376 // Keep handle for OnChildRemove notification
377 removed = Dali::Actor( &actor );
379 // Do this first, since user callbacks from within SetParent() may need to add the child
380 mChildren->erase(iter);
382 DALI_ASSERT_DEBUG( actor.GetParent() == this );
383 actor.SetParent( NULL );
391 // Notification for derived classes
392 OnChildRemove( GetImplementation(removed) );
396 void Actor::Unparent()
400 mParent->Remove( *this );
404 unsigned int Actor::GetChildCount() const
406 return ( NULL != mChildren ) ? mChildren->size() : 0;
409 Dali::Actor Actor::GetChildAt(unsigned int index) const
411 DALI_ASSERT_ALWAYS( index < GetChildCount() );
413 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
416 ActorContainer Actor::GetChildren()
418 if( NULL != mChildren )
423 // return copy of mNullChildren
424 return mNullChildren;
427 const ActorContainer& Actor::GetChildren() const
429 if( NULL != mChildren )
434 // return const reference to mNullChildren
435 return mNullChildren;
438 ActorPtr Actor::FindChildByName(const std::string& actorName)
441 if (actorName == mName)
447 ActorIter end = mChildren->end();
448 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
450 child = GetImplementation(*iter).FindChildByName(actorName);
461 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
463 Dali::Actor child = DoGetChildByAlias(actorAlias);
465 // If not found then search by name.
468 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
471 child = Dali::Actor(child_ptr.Get());
478 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
480 Dali::Actor child = GetChildByAlias(actorAlias);
482 if (!child && mChildren )
484 ActorIter end = mChildren->end();
485 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
487 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
499 ActorPtr Actor::FindChildById(const unsigned int id)
508 ActorIter end = mChildren->end();
509 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
511 child = GetImplementation(*iter).FindChildById(id);
522 void Actor::SetParentOrigin( const Vector3& origin )
526 // mNode is being used in a separate thread; queue a message to set the value & base value
527 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
530 // Cache for event-thread access
533 // not allocated, check if different from default
534 if( ParentOrigin::DEFAULT != origin )
536 mParentOrigin = new Vector3( origin );
541 // check if different from current costs more than just set
542 *mParentOrigin = origin;
546 void Actor::SetParentOriginX( float x )
548 const Vector3& current = GetCurrentParentOrigin();
550 SetParentOrigin( Vector3( x, current.y, current.z ) );
553 void Actor::SetParentOriginY( float y )
555 const Vector3& current = GetCurrentParentOrigin();
557 SetParentOrigin( Vector3( current.x, y, current.z ) );
560 void Actor::SetParentOriginZ( float z )
562 const Vector3& current = GetCurrentParentOrigin();
564 SetParentOrigin( Vector3( current.x, current.y, z ) );
567 const Vector3& Actor::GetCurrentParentOrigin() const
569 // Cached for event-thread access
570 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
573 void Actor::SetAnchorPoint(const Vector3& anchor)
577 // mNode is being used in a separate thread; queue a message to set the value & base value
578 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
581 // Cache for event-thread access
584 // not allocated, check if different from default
585 if( AnchorPoint::DEFAULT != anchor )
587 mAnchorPoint = new Vector3( anchor );
592 // check if different from current costs more than just set
593 *mAnchorPoint = anchor;
597 void Actor::SetAnchorPointX( float x )
599 const Vector3& current = GetCurrentAnchorPoint();
601 SetAnchorPoint( Vector3( x, current.y, current.z ) );
604 void Actor::SetAnchorPointY( float y )
606 const Vector3& current = GetCurrentAnchorPoint();
608 SetAnchorPoint( Vector3( current.x, y, current.z ) );
611 void Actor::SetAnchorPointZ( float z )
613 const Vector3& current = GetCurrentAnchorPoint();
615 SetAnchorPoint( Vector3( current.x, current.y, z ) );
618 const Vector3& Actor::GetCurrentAnchorPoint() const
620 // Cached for event-thread access
621 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
624 void Actor::SetPosition(float x, float y)
626 SetPosition(Vector3(x, y, 0.0f));
629 void Actor::SetPosition(float x, float y, float z)
631 SetPosition(Vector3(x, y, z));
634 void Actor::SetPosition(const Vector3& position)
638 // mNode is being used in a separate thread; queue a message to set the value & base value
639 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
643 void Actor::SetX(float x)
647 // mNode is being used in a separate thread; queue a message to set the value & base value
648 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
652 void Actor::SetY(float y)
656 // mNode is being used in a separate thread; queue a message to set the value & base value
657 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
661 void Actor::SetZ(float z)
665 // mNode is being used in a separate thread; queue a message to set the value & base value
666 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
670 void Actor::MoveBy(const Vector3& distance)
674 // mNode is being used in a separate thread; queue a message to set the value & base value
675 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
679 const Vector3& Actor::GetCurrentPosition() const
683 // mNode is being used in a separate thread; copy the value from the previous update
684 return mNode->GetPosition(mStage->GetEventBufferIndex());
687 return Vector3::ZERO;
690 const Vector3& Actor::GetCurrentWorldPosition() const
694 // mNode is being used in a separate thread; copy the value from the previous update
695 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
698 return Vector3::ZERO;
701 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
703 // this flag is not animatable so keep the value
704 mPositionInheritanceMode = mode;
707 // mNode is being used in a separate thread; queue a message to set the value
708 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
712 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
714 // Cached for event-thread access
715 return mPositionInheritanceMode;
718 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
720 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
721 normalizedAxis.Normalize();
723 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
725 SetRotation(rotation);
728 void Actor::SetRotation(const Quaternion& rotation)
732 // mNode is being used in a separate thread; queue a message to set the value & base value
733 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
737 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
741 // mNode is being used in a separate thread; queue a message to set the value & base value
742 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
746 void Actor::RotateBy(const Quaternion& relativeRotation)
750 // mNode is being used in a separate thread; queue a message to set the value & base value
751 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
755 const Quaternion& Actor::GetCurrentRotation() const
759 // mNode is being used in a separate thread; copy the value from the previous update
760 return mNode->GetRotation(mStage->GetEventBufferIndex());
763 return Quaternion::IDENTITY;
766 const Quaternion& Actor::GetCurrentWorldRotation() const
770 // mNode is being used in a separate thread; copy the value from the previous update
771 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
774 return Quaternion::IDENTITY;
777 void Actor::SetScale(float scale)
779 SetScale(Vector3(scale, scale, scale));
782 void Actor::SetScale(float x, float y, float z)
784 SetScale(Vector3(x, y, z));
787 void Actor::SetScale(const Vector3& scale)
791 // mNode is being used in a separate thread; queue a message to set the value & base value
792 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
796 void Actor::SetScaleX( float x )
800 // mNode is being used in a separate thread; queue a message to set the value & base value
801 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
805 void Actor::SetScaleY( float y )
809 // mNode is being used in a separate thread; queue a message to set the value & base value
810 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
814 void Actor::SetScaleZ( float z )
818 // mNode is being used in a separate thread; queue a message to set the value & base value
819 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
823 void Actor::SetInitialVolume(const Vector3& volume)
827 // mNode is being used in a separate thread; queue a message to set the value
828 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
832 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
836 // mNode is being used in a separate thread; queue a message to set the value
837 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
841 bool Actor::GetTransmitGeometryScaling() const
845 // mNode is being used in a separate thread; copy the value from the previous update
846 return mNode->GetTransmitGeometryScaling();
852 void Actor::ScaleBy(const Vector3& relativeScale)
856 // mNode is being used in a separate thread; queue a message to set the value & base value
857 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
861 const Vector3& Actor::GetCurrentScale() const
865 // mNode is being used in a separate thread; copy the value from the previous update
866 return mNode->GetScale(mStage->GetEventBufferIndex());
872 const Vector3& Actor::GetCurrentWorldScale() const
876 // mNode is being used in a separate thread; copy the value from the previous update
877 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
883 void Actor::SetInheritScale( bool inherit )
885 // non animateable so keep local copy
886 mInheritScale = inherit;
889 // mNode is being used in a separate thread; queue a message to set the value
890 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
894 bool Actor::IsScaleInherited() const
896 return mInheritScale;
899 Matrix Actor::GetCurrentWorldMatrix() const
903 // World matrix is no longer updated unless there is something observing the node.
904 // Need to calculate it from node's world position, rotation and scale:
905 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
906 Matrix worldMatrix(false);
907 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
908 mNode->GetWorldRotation( updateBufferIndex ),
909 mNode->GetWorldPosition( updateBufferIndex ) );
913 return Matrix::IDENTITY;
916 void Actor::SetVisible(bool visible)
920 // mNode is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
925 bool Actor::IsVisible() const
929 // mNode is being used in a separate thread; copy the value from the previous update
930 return mNode->IsVisible( mStage->GetEventBufferIndex() );
936 void Actor::SetOpacity(float opacity)
940 // mNode is being used in a separate thread; queue a message to set the value & base value
941 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
945 void Actor::OpacityBy(float relativeOpacity)
949 // mNode is being used in a separate thread; queue a message to set the value & base value
950 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
954 float Actor::GetCurrentOpacity() const
958 // mNode is being used in a separate thread; copy the value from the previous update
959 return mNode->GetOpacity(mStage->GetEventBufferIndex());
965 const Vector4& Actor::GetCurrentWorldColor() const
969 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
975 void Actor::SetColor(const Vector4& color)
979 // mNode is being used in a separate thread; queue a message to set the value & base value
980 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
984 void Actor::SetColorRed( float red )
988 // mNode is being used in a separate thread; queue a message to set the value & base value
989 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
993 void Actor::SetColorGreen( float green )
997 // mNode is being used in a separate thread; queue a message to set the value & base value
998 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1002 void Actor::SetColorBlue( float blue )
1006 // mNode is being used in a separate thread; queue a message to set the value & base value
1007 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1011 void Actor::ColorBy(const Vector4& relativeColor)
1015 // mNode is being used in a separate thread; queue a message to set the value & base value
1016 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1020 const Vector4& Actor::GetCurrentColor() const
1024 // mNode is being used in a separate thread; copy the value from the previous update
1025 return mNode->GetColor(mStage->GetEventBufferIndex());
1028 return Color::WHITE;
1031 void Actor::SetInheritRotation(bool inherit)
1033 // non animateable so keep local copy
1034 mInheritRotation = inherit;
1037 // mNode is being used in a separate thread; queue a message to set the value
1038 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1042 bool Actor::IsRotationInherited() const
1044 return mInheritRotation;
1047 void Actor::SetColorMode(ColorMode colorMode)
1049 // non animateable so keep local copy
1050 mColorMode = colorMode;
1053 // mNode is being used in a separate thread; queue a message to set the value
1054 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1058 ColorMode Actor::GetColorMode() const
1060 // we have cached copy
1064 void Actor::SetSize(float width, float height)
1066 SetSize( Vector2( width, height ) );
1069 void Actor::SetSize(float width, float height, float depth)
1071 SetSize( Vector3( width, height, depth ) );
1074 void Actor::SetSize(const Vector2& size)
1076 Vector3 volume( size );
1077 volume.z = std::min( size.width, size.height );
1081 void Actor::SetSize(const Vector3& size)
1085 // mNode is being used in a separate thread; queue a message to set the value & base value
1086 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1088 // Notification for derived classes
1091 // Emit signal for application developer
1093 if( !mSetSizeSignalV2.Empty() )
1095 Dali::Actor handle( this );
1096 mSetSizeSignalV2.Emit( handle, size );
1101 void Actor::SetWidth( float width )
1105 // mNode is being used in a separate thread; queue a message to set the value & base value
1106 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1110 void Actor::SetHeight( float height )
1114 // mNode is being used in a separate thread; queue a message to set the value & base value
1115 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1119 void Actor::SetDepth( float depth )
1123 // mNode is being used in a separate thread; queue a message to set the value & base value
1124 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1128 const Vector3& Actor::GetCurrentSize() const
1132 // mNode is being used in a separate thread; copy the value from the previous update
1133 return mNode->GetSize( mStage->GetEventBufferIndex() );
1136 return Vector3::ZERO;
1139 void Actor::SetInheritShaderEffect(bool inherit)
1143 // mNode is being used in a separate thread; queue a message to set the value
1144 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1148 bool Actor::GetInheritShaderEffect() const
1152 // mNode is being used in a separate thread; copy the value from the previous update
1153 return mNode->GetInheritShader();
1159 void Actor::SetShaderEffect(ShaderEffect& effect)
1165 mShaderEffect->Disconnect();
1168 mShaderEffect = ShaderEffectPtr(&effect);
1170 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1174 // mNode is being used in a separate thread; queue a message to apply shader
1175 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1178 mShaderEffect->Connect();
1182 mShaderEffect = ShaderEffectPtr(&effect);
1184 // Effects can only be applied when the Node is connected to scene-graph
1187 ShaderEffectPtr Actor::GetShaderEffect() const
1189 return mShaderEffect;
1192 void Actor::RemoveShaderEffect()
1198 // mNode is being used in a separate thread; queue a message to remove shader
1199 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1202 // Notify shader effect
1205 mShaderEffect->Disconnect();
1209 mShaderEffect.Reset();
1212 //--------------- Dynamics ---------------
1214 void Actor::DisableDynamics()
1216 if( NULL != mDynamicsData )
1218 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1220 // ensure dynamics object are disconnected from scene
1221 DisconnectDynamics();
1223 // delete joint owned by this actor
1224 while( !mDynamicsData->joints.empty() )
1226 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1229 // delete other joints referencing this actor
1230 while( !mDynamicsData->referencedJoints.empty() )
1232 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1233 ActorPtr jointOwner( joint->GetActor( true ) );
1236 jointOwner->RemoveDynamicsJoint( joint );
1240 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1243 // delete the DynamicsBody object
1244 mDynamicsData->body.Reset();
1246 // Discard Dynamics data structure
1247 delete mDynamicsData;
1248 mDynamicsData = NULL;
1252 DynamicsBodyPtr Actor::GetDynamicsBody() const
1254 DynamicsBodyPtr body;
1256 if( NULL != mDynamicsData )
1258 body = mDynamicsData->body;
1264 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1266 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1268 if( NULL == mDynamicsData )
1270 mDynamicsData = new DynamicsData( this );
1273 if( !mDynamicsData->body )
1275 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1279 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1282 if( mParent == world->GetRootActor().Get() )
1284 mDynamicsData->body->Connect(*mStage);
1290 return mDynamicsData->body;
1293 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1295 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1296 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1299 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1301 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1302 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1304 DynamicsJointPtr joint;
1306 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1310 if( NULL != mDynamicsData )
1312 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1314 if( mDynamicsData->joints.end() != it )
1316 // use existing joint
1322 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1323 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1327 bodyA = EnableDynamics( new DynamicsBodyConfig );
1332 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1335 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1336 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1338 if( OnStage() && attachedActor->OnStage() )
1340 joint->Connect(*mStage);
1343 attachedActor->ReferenceJoint( joint );
1345 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1346 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1353 const int Actor::GetNumberOfJoints() const
1355 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1358 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1360 DynamicsJointPtr joint;
1362 if( NULL != mDynamicsData )
1364 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1366 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1368 for( int i = 0; i < index; ++i )
1380 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1382 DynamicsJointPtr joint;
1384 if( NULL != mDynamicsData )
1386 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1388 if( mDynamicsData->joints.end() != it )
1390 // use existing joint
1398 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1400 if( NULL != mDynamicsData )
1402 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1403 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1405 for( ; it != endIt; ++it )
1407 if( it->second == joint.Get() )
1409 ActorPtr attachedActor( it->first );
1411 if( OnStage() && attachedActor && attachedActor->OnStage() )
1413 joint->Disconnect(*mStage);
1418 attachedActor->ReleaseJoint( joint );
1419 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1420 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1423 mDynamicsData->joints.erase(it);
1430 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1432 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1434 if( NULL != mDynamicsData )
1436 mDynamicsData->referencedJoints.push_back(joint);
1440 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1442 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1444 if( NULL != mDynamicsData )
1446 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1448 if( it != mDynamicsData->referencedJoints.end() )
1450 mDynamicsData->referencedJoints.erase( it );
1455 void Actor::SetDynamicsRoot(bool flag)
1457 if( mIsDynamicsRoot != flag )
1459 mIsDynamicsRoot = flag;
1461 if( OnStage() && mChildren )
1463 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1464 ActorIter end = mChildren->end();
1465 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1467 Actor& child = GetImplementation(*iter);
1469 if( child.GetDynamicsBody() )
1471 if( mIsDynamicsRoot )
1473 child.ConnectDynamics();
1477 child.DisconnectDynamics();
1485 bool Actor::IsDynamicsRoot() const
1487 return mIsDynamicsRoot;
1490 void Actor::AttachedActorOnStage( Dali::Actor actor )
1492 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1496 ActorPtr attachedActor( &GetImplementation(actor) );
1498 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1499 if( NULL != mDynamicsData )
1501 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1502 if( mDynamicsData->joints.end() != it )
1504 DynamicsJointPtr joint( it->second );
1505 joint->Connect(*mStage);
1511 void Actor::AttachedActorOffStage( Dali::Actor actor )
1513 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1517 ActorPtr attachedActor( &GetImplementation(actor) );
1519 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1520 if( NULL != mDynamicsData )
1522 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1523 if( mDynamicsData->joints.end() != it )
1525 DynamicsJointPtr joint( it->second );
1526 joint->Disconnect(*mStage);
1532 void Actor::ConnectDynamics()
1534 if( NULL != mDynamicsData && mDynamicsData->body )
1536 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1538 mDynamicsData->body->Connect(*mStage);
1540 // Connect all joints where attachedActor is also on stage
1541 if( !mDynamicsData->joints.empty() )
1543 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1544 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1546 for( ; it != endIt; ++it )
1548 Actor* attachedActor( it->first );
1549 if( NULL != attachedActor && attachedActor->OnStage() )
1551 DynamicsJointPtr joint( it->second );
1553 joint->Connect(*mStage);
1561 void Actor::DisconnectDynamics()
1563 if( NULL != mDynamicsData && mDynamicsData->body )
1567 mDynamicsData->body->Disconnect(*mStage);
1569 // Disconnect all joints
1570 if( !mDynamicsData->joints.empty() )
1572 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1573 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1575 for( ; it != endIt; ++it )
1577 DynamicsJointPtr joint( it->second );
1579 joint->Disconnect(*mStage);
1586 void Actor::SetOverlay(bool enable)
1588 // Setting STENCIL will override OVERLAY
1589 if( DrawMode::STENCIL != mDrawMode )
1591 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1595 bool Actor::IsOverlay() const
1597 return ( DrawMode::OVERLAY == mDrawMode );
1600 void Actor::SetDrawMode( DrawMode::Type drawMode )
1602 // this flag is not animatable so keep the value
1603 mDrawMode = drawMode;
1606 // mNode is being used in a separate thread; queue a message to set the value
1607 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1611 DrawMode::Type Actor::GetDrawMode() const
1616 bool Actor::ScreenToLocal( float& localX,
1619 float screenY ) const
1621 // only valid when on-stage
1624 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1626 Vector2 converted( screenX, screenY );
1628 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1629 const int taskCount = taskList.GetTaskCount();
1630 for( int i = taskCount - 1; i >= 0; --i )
1632 Dali::RenderTask task = taskList.GetTask( i );
1633 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1635 // found a task where this conversion was ok so return
1643 bool Actor::ScreenToLocal( RenderTask& renderTask,
1647 float screenY ) const
1649 bool retval = false;
1650 // only valid when on-stage
1653 CameraActor* camera = renderTask.GetCameraActor();
1657 renderTask.GetViewport( viewport );
1659 // need to translate coordinates to render tasks coordinate space
1660 Vector2 converted( screenX, screenY );
1661 if( renderTask.TranslateCoordinates( converted ) )
1663 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1670 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1671 const Matrix& projectionMatrix,
1672 const Viewport& viewport,
1676 float screenY ) const
1678 // Early-out if mNode is NULL
1684 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1686 // Calculate the ModelView matrix
1687 Matrix modelView(false/*don't init*/);
1688 // need to use the components as world matrix is only updated for actors that need it
1689 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1690 Matrix::Multiply(modelView, modelView, viewMatrix);
1692 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1693 Matrix invertedMvp(false/*don't init*/);
1694 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1695 bool success = invertedMvp.Invert();
1697 // Convert to GL coordinates
1698 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1703 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1710 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1716 if (XyPlaneIntersect(nearPos, farPos, local))
1718 Vector3 size = GetCurrentSize();
1719 localX = local.x + size.x * 0.5f;
1720 localY = local.y + size.y * 0.5f;
1731 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1734 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1736 Mathematical Formulation
1738 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1740 ( p - c ) dot ( p - c ) = r^2
1742 Given a ray with a point of origin 'o', and a direction vector 'd':
1744 ray(t) = o + td, t >= 0
1746 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1748 (o + td - c ) dot ( o + td - c ) = r^2
1750 To solve for t we first expand the above into a more recognisable quadratic equation form
1752 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1761 B = 2( o - c ) dot d
1762 C = ( o - c ) dot ( o - c ) - r^2
1764 which can be solved using a standard quadratic formula.
1766 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1768 Practical Simplification
1770 In a renderer, we often differentiate between world space and object space. In the object space
1771 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1772 into object space, the mathematical solution presented above can be simplified significantly.
1774 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1778 and we can find the t at which the (transformed) ray intersects the sphere by
1780 ( o + td ) dot ( o + td ) = r^2
1782 According to the reasoning above, we expand the above quadratic equation into the general form
1786 which now has coefficients:
1793 // Early out if mNode is NULL
1799 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1801 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1802 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1803 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1804 rayOrigin.y - translation.y,
1805 rayOrigin.z - translation.z);
1807 // Compute the radius is not needed, square radius it's enough.
1808 const Vector3& size( mNode->GetSize( bufferIndex ) );
1810 // Scale the sphere.
1811 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1813 const float width = size.width * scale.width;
1814 const float height = size.height * scale.height;
1816 float squareSphereRadius = 0.5f * ( width * width + height * height );
1818 float a = rayDir.Dot( rayDir ); // a
1819 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1820 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1822 return ( b2*b2 - a*c ) >= 0.f;
1825 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1832 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1834 // Transforms the ray to the local reference system.
1836 // Calculate the inverse of Model matrix
1837 Matrix invModelMatrix(false/*don't init*/);
1838 // need to use the components as world matrix is only updated for actors that need it
1839 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1841 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1842 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1844 // Test with the actor's XY plane (Normal = 0 0 1 1).
1846 float a = -rayOriginLocal.z;
1847 float b = rayDirLocal.z;
1849 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1851 // Ray travels distance * rayDirLocal to intersect with plane.
1854 const Vector3& size = mNode->GetSize( bufferIndex );
1856 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1857 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1859 // Test with the actor's geometry.
1860 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1867 void Actor::SetLeaveRequired(bool required)
1869 mLeaveRequired = required;
1872 bool Actor::GetLeaveRequired() const
1874 return mLeaveRequired;
1877 void Actor::SetKeyboardFocusable( bool focusable )
1879 mKeyboardFocusable = focusable;
1882 bool Actor::IsKeyboardFocusable() const
1884 return mKeyboardFocusable;
1887 bool Actor::GetTouchRequired() const
1889 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1892 bool Actor::GetMouseWheelEventRequired() const
1894 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1897 bool Actor::IsHittable() const
1899 return IsSensitive() &&
1901 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1905 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1907 bool consumed = false;
1909 if ( !mTouchedSignalV2.Empty() )
1911 Dali::Actor handle( this );
1912 consumed = mTouchedSignalV2.Emit( handle, event );
1917 // Notification for derived classes
1918 consumed = OnTouchEvent( event );
1924 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1926 bool consumed = false;
1928 if ( !mMouseWheelEventSignalV2.Empty() )
1930 Dali::Actor handle( this );
1931 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1936 // Notification for derived classes
1937 consumed = OnMouseWheelEvent(event);
1943 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1945 return mTouchedSignalV2;
1948 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1950 return mMouseWheelEventSignalV2;
1953 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1955 return mSetSizeSignalV2;
1958 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1960 return mOnStageSignalV2;
1963 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1965 return mOffStageSignalV2;
1968 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1970 bool connected( true );
1971 Actor* actor = dynamic_cast<Actor*>(object);
1973 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1975 actor->TouchedSignal().Connect( tracker, functor );
1977 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1979 actor->MouseWheelEventSignal().Connect( tracker, functor );
1981 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1983 actor->SetSizeSignal().Connect( tracker, functor );
1985 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1987 actor->OnStageSignal().Connect( tracker, functor );
1989 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1991 actor->OffStageSignal().Connect( tracker, functor );
1995 // signalName does not match any signal
2002 Actor::Actor( DerivedType derivedType )
2003 : mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2005 mIsRoot( ROOT_LAYER == derivedType ),
2006 mIsRenderable( RENDERABLE == derivedType ),
2007 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2008 mIsOnStage( false ),
2009 mIsDynamicsRoot(false),
2011 mLeaveRequired( false ),
2012 mKeyboardFocusable( false ),
2013 mDerivedRequiresTouch( false ),
2014 mDerivedRequiresMouseWheelEvent( false ),
2015 mOnStageSignalled( false ),
2016 mInheritRotation( true ),
2017 mInheritScale( true ),
2018 mDrawMode( DrawMode::NORMAL ),
2019 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2020 mColorMode( Node::DEFAULT_COLOR_MODE ),
2024 mParentOrigin( NULL ),
2025 mAnchorPoint( NULL ),
2026 mDynamicsData( NULL )
2030 void Actor::Initialize()
2032 mStage = Stage::GetCurrent();
2035 SceneGraph::Node* node = CreateNode();
2037 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2038 mNode = node; // Keep raw-pointer to Node
2040 if(!mDefaultPropertyLookup)
2042 mDefaultPropertyLookup = new DefaultPropertyLookup();
2044 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2046 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_NAMES[i]] = i;
2057 // Remove mParent pointers from children even if we're destroying core,
2058 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2061 ActorConstIter endIter = mChildren->end();
2062 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2064 Actor& actor = GetImplementation( *iter );
2065 actor.SetParent( NULL );
2070 // Guard to allow handle destruction after Core has been destroyed
2071 if( Stage::IsInstalled() )
2075 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2076 mNode = NULL; // Node is about to be destroyed
2083 delete mDynamicsData;
2084 // Cleanup optional parent origin and anchor
2085 delete mParentOrigin;
2086 delete mAnchorPoint;
2089 void Actor::ConnectToStage( Stage& stage )
2091 // This container is used instead of walking the Actor hierachy.
2092 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2093 ActorContainer connectionList;
2095 // This stage is atomic i.e. not interrupted by user callbacks
2096 RecursiveConnectToStage( stage, connectionList );
2098 // Notify applications about the newly connected actors.
2099 const ActorIter endIter = connectionList.end();
2100 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2102 Actor& actor = GetImplementation(*iter);
2103 actor.NotifyStageConnection();
2107 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2109 DALI_ASSERT_ALWAYS( !OnStage() );
2113 ConnectToSceneGraph();
2115 // Notification for internal derived classes
2116 OnStageConnectionInternal();
2118 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2119 connectionList.push_back( Dali::Actor(this) );
2121 // Recursively connect children
2124 ActorConstIter endIter = mChildren->end();
2125 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2127 Actor& actor = GetImplementation( *iter );
2128 actor.RecursiveConnectToStage( stage, connectionList );
2134 * This method is called when the Actor is connected to the Stage.
2135 * The parent must have added its Node to the scene-graph.
2136 * The child must connect its Node to the parent's Node.
2137 * This is resursive; the child calls ConnectToStage() for its children.
2139 void Actor::ConnectToSceneGraph()
2141 DALI_ASSERT_DEBUG( mNode != NULL);
2142 DALI_ASSERT_DEBUG( mParent != NULL);
2143 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2147 // Reparent Node in next Update
2148 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2153 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2157 // Effects can only be applied when the node is on-stage
2158 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2161 // Notify shader effect
2162 mShaderEffect->Connect();
2165 // Notify attachment
2168 mAttachment->Connect();
2172 if( NULL != mDynamicsData )
2177 // Notification for ProxyObject::Observers
2181 void Actor::NotifyStageConnection()
2183 // Actors can be removed (in a callback), before the on-stage stage is reported.
2184 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2185 if ( OnStage() && !mOnStageSignalled )
2187 // Notification for external (CustomActor) derived classes
2188 OnStageConnectionExternal();
2190 if ( !mOnStageSignalV2.Empty() )
2192 Dali::Actor handle( this );
2193 mOnStageSignalV2.Emit( handle );
2196 // Guard against Remove during callbacks
2199 mOnStageSignalled = true; // signal required next time Actor is removed
2204 void Actor::DisconnectFromStage()
2206 // This container is used instead of walking the Actor hierachy.
2207 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2208 ActorContainer disconnectionList;
2210 // This stage is atomic i.e. not interrupted by user callbacks
2211 RecursiveDisconnectFromStage( disconnectionList );
2213 // Notify applications about the newly disconnected actors.
2214 const ActorIter endIter = disconnectionList.end();
2215 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2217 Actor& actor = GetImplementation(*iter);
2218 actor.NotifyStageDisconnection();
2222 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2224 DALI_ASSERT_ALWAYS( OnStage() );
2226 // Recursively disconnect children
2229 ActorConstIter endIter = mChildren->end();
2230 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2232 Actor& actor = GetImplementation( *iter );
2233 actor.RecursiveDisconnectFromStage( disconnectionList );
2237 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2238 disconnectionList.push_back( Dali::Actor(this) );
2240 // Notification for internal derived classes
2241 OnStageDisconnectionInternal();
2243 DisconnectFromSceneGraph();
2249 * This method is called by an actor or its parent, before a node removal message is sent.
2250 * This is recursive; the child calls DisconnectFromStage() for its children.
2252 void Actor::DisconnectFromSceneGraph()
2254 // Notification for ProxyObject::Observers
2255 OnSceneObjectRemove();
2257 // Notify shader effect
2260 mShaderEffect->Disconnect();
2263 // Notify attachment
2266 mAttachment->Disconnect();
2270 if( NULL != mDynamicsData )
2272 DisconnectDynamics();
2276 void Actor::NotifyStageDisconnection()
2278 // Actors can be added (in a callback), before the off-stage state is reported.
2279 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2280 // only do this step if there is a stage, i.e. Core is not being shut down
2281 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2283 // Notification for external (CustomeActor) derived classes
2284 OnStageDisconnectionExternal();
2286 if( !mOffStageSignalV2.Empty() )
2288 Dali::Actor handle( this );
2289 mOffStageSignalV2.Emit( handle );
2292 // Guard against Add during callbacks
2295 mOnStageSignalled = false; // signal required next time Actor is added
2300 bool Actor::IsNodeConnected() const
2302 bool connected( false );
2307 if( mNode->IsRoot() || mNode->GetParent() )
2316 bool Actor::IsSceneObjectRemovable() const
2321 unsigned int Actor::GetDefaultPropertyCount() const
2323 return DEFAULT_PROPERTY_COUNT;
2326 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2328 indices.reserve( DEFAULT_PROPERTY_COUNT );
2330 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2332 indices.push_back( i );
2336 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2338 if( index < DEFAULT_PROPERTY_COUNT )
2340 return DEFAULT_PROPERTY_NAMES[index];
2344 // index out of range..return empty string
2345 return INVALID_PROPERTY_NAME;
2349 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2351 Property::Index index = Property::INVALID_INDEX;
2353 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2355 // Look for name in default properties
2356 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2357 if ( mDefaultPropertyLookup->end() != result )
2359 index = result->second;
2365 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2367 // World-properties are not writable
2368 return ( Dali::Actor::WORLD_POSITION != index &&
2369 Dali::Actor::WORLD_POSITION_X != index &&
2370 Dali::Actor::WORLD_POSITION_Y != index &&
2371 Dali::Actor::WORLD_POSITION_Z != index &&
2372 Dali::Actor::WORLD_ROTATION != index &&
2373 Dali::Actor::WORLD_SCALE != index &&
2374 Dali::Actor::WORLD_COLOR != index &&
2375 Dali::Actor::WORLD_MATRIX != index);
2378 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2380 // ParentOrigin, AnchorPoint & World-properties are not animatable
2381 return ( Dali::Actor::PARENT_ORIGIN != index &&
2382 Dali::Actor::PARENT_ORIGIN_X != index &&
2383 Dali::Actor::PARENT_ORIGIN_Y != index &&
2384 Dali::Actor::PARENT_ORIGIN_Z != index &&
2385 Dali::Actor::ANCHOR_POINT != index &&
2386 Dali::Actor::ANCHOR_POINT_X != index &&
2387 Dali::Actor::ANCHOR_POINT_Y != index &&
2388 Dali::Actor::ANCHOR_POINT_Z != index &&
2389 Dali::Actor::WORLD_POSITION != index &&
2390 Dali::Actor::WORLD_POSITION_X != index &&
2391 Dali::Actor::WORLD_POSITION_Y != index &&
2392 Dali::Actor::WORLD_POSITION_Z != index &&
2393 Dali::Actor::WORLD_ROTATION != index &&
2394 Dali::Actor::WORLD_SCALE != index &&
2395 Dali::Actor::WORLD_COLOR != index &&
2396 Dali::Actor::WORLD_MATRIX != index);
2399 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2401 if( index < DEFAULT_PROPERTY_COUNT )
2403 return DEFAULT_PROPERTY_TYPES[index];
2407 // index out of range...return Property::NONE
2408 return Property::NONE;
2412 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2416 case Dali::Actor::PARENT_ORIGIN:
2418 SetParentOrigin( property.Get<Vector3>() );
2422 case Dali::Actor::PARENT_ORIGIN_X:
2424 SetParentOriginX( property.Get<float>() );
2428 case Dali::Actor::PARENT_ORIGIN_Y:
2430 SetParentOriginY( property.Get<float>() );
2434 case Dali::Actor::PARENT_ORIGIN_Z:
2436 SetParentOriginZ( property.Get<float>() );
2440 case Dali::Actor::ANCHOR_POINT:
2442 SetAnchorPoint( property.Get<Vector3>() );
2446 case Dali::Actor::ANCHOR_POINT_X:
2448 SetAnchorPointX( property.Get<float>() );
2452 case Dali::Actor::ANCHOR_POINT_Y:
2454 SetAnchorPointY( property.Get<float>() );
2458 case Dali::Actor::ANCHOR_POINT_Z:
2460 SetAnchorPointZ( property.Get<float>() );
2464 case Dali::Actor::SIZE:
2466 SetSize( property.Get<Vector3>() );
2470 case Dali::Actor::SIZE_WIDTH:
2472 SetWidth( property.Get<float>() );
2476 case Dali::Actor::SIZE_HEIGHT:
2478 SetHeight( property.Get<float>() );
2482 case Dali::Actor::SIZE_DEPTH:
2484 SetDepth( property.Get<float>() );
2488 case Dali::Actor::POSITION:
2490 SetPosition( property.Get<Vector3>() );
2494 case Dali::Actor::POSITION_X:
2496 SetX( property.Get<float>() );
2500 case Dali::Actor::POSITION_Y:
2502 SetY( property.Get<float>() );
2506 case Dali::Actor::POSITION_Z:
2508 SetZ( property.Get<float>() );
2512 case Dali::Actor::ROTATION:
2514 SetRotation( property.Get<Quaternion>() );
2518 case Dali::Actor::SCALE:
2520 SetScale( property.Get<Vector3>() );
2524 case Dali::Actor::SCALE_X:
2526 SetScaleX( property.Get<float>() );
2530 case Dali::Actor::SCALE_Y:
2532 SetScaleY( property.Get<float>() );
2536 case Dali::Actor::SCALE_Z:
2538 SetScaleZ( property.Get<float>() );
2542 case Dali::Actor::VISIBLE:
2544 SetVisible( property.Get<bool>() );
2548 case Dali::Actor::COLOR:
2550 SetColor( property.Get<Vector4>() );
2554 case Dali::Actor::COLOR_RED:
2556 SetColorRed( property.Get<float>() );
2560 case Dali::Actor::COLOR_GREEN:
2562 SetColorGreen( property.Get<float>() );
2566 case Dali::Actor::COLOR_BLUE:
2568 SetColorBlue( property.Get<float>() );
2572 case Dali::Actor::COLOR_ALPHA:
2574 SetOpacity( property.Get<float>() );
2578 case Dali::Actor::NAME:
2580 SetName( property.Get<std::string>() );
2586 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2592 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2594 // TODO: This should be deprecated
2595 OnPropertySet(index, value);
2597 if(entry.IsAnimatable())
2599 // TODO: ADD MATRIX & MATRIX3 types
2601 switch ( entry.type )
2603 case Property::BOOLEAN:
2605 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2606 DALI_ASSERT_DEBUG( NULL != property );
2608 // property is being used in a separate thread; queue a message to set the property
2609 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2614 case Property::FLOAT:
2616 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2617 DALI_ASSERT_DEBUG( NULL != property );
2619 // property is being used in a separate thread; queue a message to set the property
2620 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2625 case Property::VECTOR2:
2627 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2628 DALI_ASSERT_DEBUG( NULL != property );
2630 // property is being used in a separate thread; queue a message to set the property
2631 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2636 case Property::VECTOR3:
2638 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2639 DALI_ASSERT_DEBUG( NULL != property );
2641 // property is being used in a separate thread; queue a message to set the property
2642 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2647 case Property::VECTOR4:
2649 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2650 DALI_ASSERT_DEBUG( NULL != property );
2652 // property is being used in a separate thread; queue a message to set the property
2653 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2658 case Property::ROTATION:
2660 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2661 DALI_ASSERT_DEBUG( NULL != property );
2663 // property is being used in a separate thread; queue a message to set the property
2664 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2671 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2678 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2680 Property::Value value;
2684 case Dali::Actor::PARENT_ORIGIN:
2686 value = GetCurrentParentOrigin();
2690 case Dali::Actor::PARENT_ORIGIN_X:
2692 value = GetCurrentParentOrigin().x;
2696 case Dali::Actor::PARENT_ORIGIN_Y:
2698 value = GetCurrentParentOrigin().y;
2702 case Dali::Actor::PARENT_ORIGIN_Z:
2704 value = GetCurrentParentOrigin().z;
2708 case Dali::Actor::ANCHOR_POINT:
2710 value = GetCurrentAnchorPoint();
2714 case Dali::Actor::ANCHOR_POINT_X:
2716 value = GetCurrentAnchorPoint().x;
2720 case Dali::Actor::ANCHOR_POINT_Y:
2722 value = GetCurrentAnchorPoint().y;
2726 case Dali::Actor::ANCHOR_POINT_Z:
2728 value = GetCurrentAnchorPoint().z;
2732 case Dali::Actor::SIZE:
2734 value = GetCurrentSize();
2738 case Dali::Actor::SIZE_WIDTH:
2740 value = GetCurrentSize().width;
2744 case Dali::Actor::SIZE_HEIGHT:
2746 value = GetCurrentSize().height;
2750 case Dali::Actor::SIZE_DEPTH:
2752 value = GetCurrentSize().depth;
2756 case Dali::Actor::POSITION:
2758 value = GetCurrentPosition();
2762 case Dali::Actor::POSITION_X:
2764 value = GetCurrentPosition().x;
2768 case Dali::Actor::POSITION_Y:
2770 value = GetCurrentPosition().y;
2774 case Dali::Actor::POSITION_Z:
2776 value = GetCurrentPosition().z;
2780 case Dali::Actor::WORLD_POSITION:
2782 value = GetCurrentWorldPosition();
2786 case Dali::Actor::WORLD_POSITION_X:
2788 value = GetCurrentWorldPosition().x;
2792 case Dali::Actor::WORLD_POSITION_Y:
2794 value = GetCurrentWorldPosition().y;
2798 case Dali::Actor::WORLD_POSITION_Z:
2800 value = GetCurrentWorldPosition().z;
2804 case Dali::Actor::ROTATION:
2806 value = GetCurrentRotation();
2810 case Dali::Actor::WORLD_ROTATION:
2812 value = GetCurrentWorldRotation();
2816 case Dali::Actor::SCALE:
2818 value = GetCurrentScale();
2822 case Dali::Actor::SCALE_X:
2824 value = GetCurrentScale().x;
2828 case Dali::Actor::SCALE_Y:
2830 value = GetCurrentScale().y;
2834 case Dali::Actor::SCALE_Z:
2836 value = GetCurrentScale().z;
2840 case Dali::Actor::WORLD_SCALE:
2842 value = GetCurrentWorldScale();
2846 case Dali::Actor::VISIBLE:
2848 value = IsVisible();
2852 case Dali::Actor::COLOR:
2854 value = GetCurrentColor();
2858 case Dali::Actor::COLOR_RED:
2860 value = GetCurrentColor().r;
2864 case Dali::Actor::COLOR_GREEN:
2866 value = GetCurrentColor().g;
2870 case Dali::Actor::COLOR_BLUE:
2872 value = GetCurrentColor().b;
2876 case Dali::Actor::COLOR_ALPHA:
2878 value = GetCurrentColor().a;
2882 case Dali::Actor::WORLD_COLOR:
2884 value = GetCurrentWorldColor();
2888 case Dali::Actor::WORLD_MATRIX:
2890 value = GetCurrentWorldMatrix();
2894 case Dali::Actor::NAME:
2902 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2910 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2914 // mNode is being used in a separate thread; queue a message to add the property
2915 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2919 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2921 // This method should only return an object connected to the scene-graph
2922 return OnStage() ? mNode : NULL;
2925 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2927 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2929 const PropertyBase* property( NULL );
2931 // This method should only return a property of an object connected to the scene-graph
2937 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2939 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
2941 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
2943 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
2945 else if( NULL != mNode )
2949 case Dali::Actor::SIZE:
2950 property = &mNode->mSize;
2953 case Dali::Actor::SIZE_WIDTH:
2954 property = &mNode->mSize;
2957 case Dali::Actor::SIZE_HEIGHT:
2958 property = &mNode->mSize;
2961 case Dali::Actor::SIZE_DEPTH:
2962 property = &mNode->mSize;
2965 case Dali::Actor::POSITION:
2966 property = &mNode->mPosition;
2969 case Dali::Actor::POSITION_X:
2970 property = &mNode->mPosition;
2973 case Dali::Actor::POSITION_Y:
2974 property = &mNode->mPosition;
2977 case Dali::Actor::POSITION_Z:
2978 property = &mNode->mPosition;
2981 case Dali::Actor::ROTATION:
2982 property = &mNode->mRotation;
2985 case Dali::Actor::SCALE:
2986 property = &mNode->mScale;
2989 case Dali::Actor::SCALE_X:
2990 property = &mNode->mScale;
2993 case Dali::Actor::SCALE_Y:
2994 property = &mNode->mScale;
2997 case Dali::Actor::SCALE_Z:
2998 property = &mNode->mScale;
3001 case Dali::Actor::VISIBLE:
3002 property = &mNode->mVisible;
3005 case Dali::Actor::COLOR:
3006 property = &mNode->mColor;
3009 case Dali::Actor::COLOR_RED:
3010 property = &mNode->mColor;
3013 case Dali::Actor::COLOR_GREEN:
3014 property = &mNode->mColor;
3017 case Dali::Actor::COLOR_BLUE:
3018 property = &mNode->mColor;
3021 case Dali::Actor::COLOR_ALPHA:
3022 property = &mNode->mColor;
3033 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3035 const PropertyInputImpl* property( NULL );
3037 // This method should only return a property of an object connected to the scene-graph
3043 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3045 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3047 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3049 property = entry->second.GetSceneGraphProperty();
3051 else if( NULL != mNode )
3055 case Dali::Actor::PARENT_ORIGIN:
3056 property = &mNode->mParentOrigin;
3059 case Dali::Actor::PARENT_ORIGIN_X:
3060 property = &mNode->mParentOrigin;
3063 case Dali::Actor::PARENT_ORIGIN_Y:
3064 property = &mNode->mParentOrigin;
3067 case Dali::Actor::PARENT_ORIGIN_Z:
3068 property = &mNode->mParentOrigin;
3071 case Dali::Actor::ANCHOR_POINT:
3072 property = &mNode->mAnchorPoint;
3075 case Dali::Actor::ANCHOR_POINT_X:
3076 property = &mNode->mAnchorPoint;
3079 case Dali::Actor::ANCHOR_POINT_Y:
3080 property = &mNode->mAnchorPoint;
3083 case Dali::Actor::ANCHOR_POINT_Z:
3084 property = &mNode->mAnchorPoint;
3087 case Dali::Actor::SIZE:
3088 property = &mNode->mSize;
3091 case Dali::Actor::SIZE_WIDTH:
3092 property = &mNode->mSize;
3095 case Dali::Actor::SIZE_HEIGHT:
3096 property = &mNode->mSize;
3099 case Dali::Actor::SIZE_DEPTH:
3100 property = &mNode->mSize;
3103 case Dali::Actor::POSITION:
3104 property = &mNode->mPosition;
3107 case Dali::Actor::POSITION_X:
3108 property = &mNode->mPosition;
3111 case Dali::Actor::POSITION_Y:
3112 property = &mNode->mPosition;
3115 case Dali::Actor::POSITION_Z:
3116 property = &mNode->mPosition;
3119 case Dali::Actor::WORLD_POSITION:
3120 property = &mNode->mWorldPosition;
3123 case Dali::Actor::WORLD_POSITION_X:
3124 property = &mNode->mWorldPosition;
3127 case Dali::Actor::WORLD_POSITION_Y:
3128 property = &mNode->mWorldPosition;
3131 case Dali::Actor::WORLD_POSITION_Z:
3132 property = &mNode->mWorldPosition;
3135 case Dali::Actor::ROTATION:
3136 property = &mNode->mRotation;
3139 case Dali::Actor::WORLD_ROTATION:
3140 property = &mNode->mWorldRotation;
3143 case Dali::Actor::SCALE:
3144 property = &mNode->mScale;
3147 case Dali::Actor::SCALE_X:
3148 property = &mNode->mScale;
3151 case Dali::Actor::SCALE_Y:
3152 property = &mNode->mScale;
3155 case Dali::Actor::SCALE_Z:
3156 property = &mNode->mScale;
3159 case Dali::Actor::WORLD_SCALE:
3160 property = &mNode->mWorldScale;
3163 case Dali::Actor::VISIBLE:
3164 property = &mNode->mVisible;
3167 case Dali::Actor::COLOR:
3168 property = &mNode->mColor;
3171 case Dali::Actor::COLOR_RED:
3172 property = &mNode->mColor;
3175 case Dali::Actor::COLOR_GREEN:
3176 property = &mNode->mColor;
3179 case Dali::Actor::COLOR_BLUE:
3180 property = &mNode->mColor;
3183 case Dali::Actor::COLOR_ALPHA:
3184 property = &mNode->mColor;
3187 case Dali::Actor::WORLD_COLOR:
3188 property = &mNode->mWorldColor;
3191 case Dali::Actor::WORLD_MATRIX:
3192 property = &mNode->mWorldMatrix;
3203 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3205 int componentIndex( INVALID_PROPERTY_COMPONENT_INDEX );
3209 case Dali::Actor::PARENT_ORIGIN_X:
3210 case Dali::Actor::ANCHOR_POINT_X:
3211 case Dali::Actor::SIZE_WIDTH:
3212 case Dali::Actor::POSITION_X:
3213 case Dali::Actor::SCALE_X:
3214 case Dali::Actor::COLOR_RED:
3215 case Dali::Actor::WORLD_POSITION_X:
3221 case Dali::Actor::PARENT_ORIGIN_Y:
3222 case Dali::Actor::ANCHOR_POINT_Y:
3223 case Dali::Actor::SIZE_HEIGHT:
3224 case Dali::Actor::POSITION_Y:
3225 case Dali::Actor::SCALE_Y:
3226 case Dali::Actor::COLOR_GREEN:
3227 case Dali::Actor::WORLD_POSITION_Y:
3233 case Dali::Actor::PARENT_ORIGIN_Z:
3234 case Dali::Actor::ANCHOR_POINT_Z:
3235 case Dali::Actor::SIZE_DEPTH:
3236 case Dali::Actor::POSITION_Z:
3237 case Dali::Actor::SCALE_Z:
3238 case Dali::Actor::COLOR_BLUE:
3239 case Dali::Actor::WORLD_POSITION_Z:
3245 case Dali::Actor::COLOR_ALPHA:
3258 return componentIndex;
3261 void Actor::SetParent(Actor* parent)
3265 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3269 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3272 StagePtr stage = parent->mStage;
3274 // Instruct each actor to create a corresponding node in the scene graph
3275 ConnectToStage(*stage);
3278 else // parent being set to NULL
3280 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3284 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3287 DALI_ASSERT_ALWAYS(mNode != NULL);
3291 // Disconnect the Node & its children from the scene-graph.
3292 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3295 // Instruct each actor to discard pointers to the scene-graph
3296 DisconnectFromStage();
3301 SceneGraph::Node* Actor::CreateNode() const
3306 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3309 Actor* actor = dynamic_cast<Actor*>(object);
3313 if(Dali::Actor::ACTION_SHOW == actionName)
3315 actor->SetVisible(true);
3318 else if(Dali::Actor::ACTION_HIDE == actionName)
3320 actor->SetVisible(false);
3328 } // namespace Internal