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 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2328 if( static_cast< unsigned int >( index ) < GetDefaultPropertyCount() )
2330 return DEFAULT_PROPERTY_NAMES[index];
2334 // index out of range..return empty string
2335 return INVALID_PROPERTY_NAME;
2339 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2341 Property::Index index = Property::INVALID_INDEX;
2343 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2345 // Look for name in default properties
2346 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2347 if ( mDefaultPropertyLookup->end() != result )
2349 index = result->second;
2355 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2357 // World-properties are not writable
2358 return ( Dali::Actor::WORLD_POSITION != index &&
2359 Dali::Actor::WORLD_POSITION_X != index &&
2360 Dali::Actor::WORLD_POSITION_Y != index &&
2361 Dali::Actor::WORLD_POSITION_Z != index &&
2362 Dali::Actor::WORLD_ROTATION != index &&
2363 Dali::Actor::WORLD_SCALE != index &&
2364 Dali::Actor::WORLD_COLOR != index &&
2365 Dali::Actor::WORLD_MATRIX != index);
2368 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2370 // ParentOrigin, AnchorPoint & World-properties are not animatable
2371 return ( Dali::Actor::PARENT_ORIGIN != index &&
2372 Dali::Actor::PARENT_ORIGIN_X != index &&
2373 Dali::Actor::PARENT_ORIGIN_Y != index &&
2374 Dali::Actor::PARENT_ORIGIN_Z != index &&
2375 Dali::Actor::ANCHOR_POINT != index &&
2376 Dali::Actor::ANCHOR_POINT_X != index &&
2377 Dali::Actor::ANCHOR_POINT_Y != index &&
2378 Dali::Actor::ANCHOR_POINT_Z != index &&
2379 Dali::Actor::WORLD_POSITION != index &&
2380 Dali::Actor::WORLD_POSITION_X != index &&
2381 Dali::Actor::WORLD_POSITION_Y != index &&
2382 Dali::Actor::WORLD_POSITION_Z != index &&
2383 Dali::Actor::WORLD_ROTATION != index &&
2384 Dali::Actor::WORLD_SCALE != index &&
2385 Dali::Actor::WORLD_COLOR != index &&
2386 Dali::Actor::WORLD_MATRIX != index);
2389 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2391 if( static_cast< unsigned int >( index ) < GetDefaultPropertyCount() )
2393 return DEFAULT_PROPERTY_TYPES[index];
2397 // index out of range...return Property::NONE
2398 return Property::NONE;
2402 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2404 // ProxyObject guarantees the property is writable and index is in range
2407 case Dali::Actor::PARENT_ORIGIN:
2409 SetParentOrigin( property.Get<Vector3>() );
2413 case Dali::Actor::PARENT_ORIGIN_X:
2415 SetParentOriginX( property.Get<float>() );
2419 case Dali::Actor::PARENT_ORIGIN_Y:
2421 SetParentOriginY( property.Get<float>() );
2425 case Dali::Actor::PARENT_ORIGIN_Z:
2427 SetParentOriginZ( property.Get<float>() );
2431 case Dali::Actor::ANCHOR_POINT:
2433 SetAnchorPoint( property.Get<Vector3>() );
2437 case Dali::Actor::ANCHOR_POINT_X:
2439 SetAnchorPointX( property.Get<float>() );
2443 case Dali::Actor::ANCHOR_POINT_Y:
2445 SetAnchorPointY( property.Get<float>() );
2449 case Dali::Actor::ANCHOR_POINT_Z:
2451 SetAnchorPointZ( property.Get<float>() );
2455 case Dali::Actor::SIZE:
2457 SetSize( property.Get<Vector3>() );
2461 case Dali::Actor::SIZE_WIDTH:
2463 SetWidth( property.Get<float>() );
2467 case Dali::Actor::SIZE_HEIGHT:
2469 SetHeight( property.Get<float>() );
2473 case Dali::Actor::SIZE_DEPTH:
2475 SetDepth( property.Get<float>() );
2479 case Dali::Actor::POSITION:
2481 SetPosition( property.Get<Vector3>() );
2485 case Dali::Actor::POSITION_X:
2487 SetX( property.Get<float>() );
2491 case Dali::Actor::POSITION_Y:
2493 SetY( property.Get<float>() );
2497 case Dali::Actor::POSITION_Z:
2499 SetZ( property.Get<float>() );
2503 case Dali::Actor::ROTATION:
2505 SetRotation( property.Get<Quaternion>() );
2509 case Dali::Actor::SCALE:
2511 SetScale( property.Get<Vector3>() );
2515 case Dali::Actor::SCALE_X:
2517 SetScaleX( property.Get<float>() );
2521 case Dali::Actor::SCALE_Y:
2523 SetScaleY( property.Get<float>() );
2527 case Dali::Actor::SCALE_Z:
2529 SetScaleZ( property.Get<float>() );
2533 case Dali::Actor::VISIBLE:
2535 SetVisible( property.Get<bool>() );
2539 case Dali::Actor::COLOR:
2541 SetColor( property.Get<Vector4>() );
2545 case Dali::Actor::COLOR_RED:
2547 SetColorRed( property.Get<float>() );
2551 case Dali::Actor::COLOR_GREEN:
2553 SetColorGreen( property.Get<float>() );
2557 case Dali::Actor::COLOR_BLUE:
2559 SetColorBlue( property.Get<float>() );
2563 case Dali::Actor::COLOR_ALPHA:
2565 SetOpacity( property.Get<float>() );
2569 case Dali::Actor::NAME:
2571 SetName( property.Get<std::string>() );
2577 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2583 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2585 // ProxyObject guarantees the index is in range
2587 OnPropertySet(index, value);
2589 if(entry.IsAnimatable())
2591 // TODO: ADD MATRIX & MATRIX3 types
2593 switch ( entry.type )
2595 case Property::BOOLEAN:
2597 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2598 DALI_ASSERT_DEBUG( NULL != property );
2600 // property is being used in a separate thread; queue a message to set the property
2601 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2606 case Property::FLOAT:
2608 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2609 DALI_ASSERT_DEBUG( NULL != property );
2611 // property is being used in a separate thread; queue a message to set the property
2612 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2617 case Property::VECTOR2:
2619 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2620 DALI_ASSERT_DEBUG( NULL != property );
2622 // property is being used in a separate thread; queue a message to set the property
2623 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2628 case Property::VECTOR3:
2630 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2631 DALI_ASSERT_DEBUG( NULL != property );
2633 // property is being used in a separate thread; queue a message to set the property
2634 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2639 case Property::VECTOR4:
2641 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2642 DALI_ASSERT_DEBUG( NULL != property );
2644 // property is being used in a separate thread; queue a message to set the property
2645 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2650 case Property::ROTATION:
2652 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2653 DALI_ASSERT_DEBUG( NULL != property );
2655 // property is being used in a separate thread; queue a message to set the property
2656 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2663 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2670 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2672 Property::Value value;
2674 // ProxyObject guarantees that index is within range
2677 case Dali::Actor::PARENT_ORIGIN:
2679 value = GetCurrentParentOrigin();
2683 case Dali::Actor::PARENT_ORIGIN_X:
2685 value = GetCurrentParentOrigin().x;
2689 case Dali::Actor::PARENT_ORIGIN_Y:
2691 value = GetCurrentParentOrigin().y;
2695 case Dali::Actor::PARENT_ORIGIN_Z:
2697 value = GetCurrentParentOrigin().z;
2701 case Dali::Actor::ANCHOR_POINT:
2703 value = GetCurrentAnchorPoint();
2707 case Dali::Actor::ANCHOR_POINT_X:
2709 value = GetCurrentAnchorPoint().x;
2713 case Dali::Actor::ANCHOR_POINT_Y:
2715 value = GetCurrentAnchorPoint().y;
2719 case Dali::Actor::ANCHOR_POINT_Z:
2721 value = GetCurrentAnchorPoint().z;
2725 case Dali::Actor::SIZE:
2727 value = GetCurrentSize();
2731 case Dali::Actor::SIZE_WIDTH:
2733 value = GetCurrentSize().width;
2737 case Dali::Actor::SIZE_HEIGHT:
2739 value = GetCurrentSize().height;
2743 case Dali::Actor::SIZE_DEPTH:
2745 value = GetCurrentSize().depth;
2749 case Dali::Actor::POSITION:
2751 value = GetCurrentPosition();
2755 case Dali::Actor::POSITION_X:
2757 value = GetCurrentPosition().x;
2761 case Dali::Actor::POSITION_Y:
2763 value = GetCurrentPosition().y;
2767 case Dali::Actor::POSITION_Z:
2769 value = GetCurrentPosition().z;
2773 case Dali::Actor::WORLD_POSITION:
2775 value = GetCurrentWorldPosition();
2779 case Dali::Actor::WORLD_POSITION_X:
2781 value = GetCurrentWorldPosition().x;
2785 case Dali::Actor::WORLD_POSITION_Y:
2787 value = GetCurrentWorldPosition().y;
2791 case Dali::Actor::WORLD_POSITION_Z:
2793 value = GetCurrentWorldPosition().z;
2797 case Dali::Actor::ROTATION:
2799 value = GetCurrentRotation();
2803 case Dali::Actor::WORLD_ROTATION:
2805 value = GetCurrentWorldRotation();
2809 case Dali::Actor::SCALE:
2811 value = GetCurrentScale();
2815 case Dali::Actor::SCALE_X:
2817 value = GetCurrentScale().x;
2821 case Dali::Actor::SCALE_Y:
2823 value = GetCurrentScale().y;
2827 case Dali::Actor::SCALE_Z:
2829 value = GetCurrentScale().z;
2833 case Dali::Actor::WORLD_SCALE:
2835 value = GetCurrentWorldScale();
2839 case Dali::Actor::VISIBLE:
2841 value = IsVisible();
2845 case Dali::Actor::COLOR:
2847 value = GetCurrentColor();
2851 case Dali::Actor::COLOR_RED:
2853 value = GetCurrentColor().r;
2857 case Dali::Actor::COLOR_GREEN:
2859 value = GetCurrentColor().g;
2863 case Dali::Actor::COLOR_BLUE:
2865 value = GetCurrentColor().b;
2869 case Dali::Actor::COLOR_ALPHA:
2871 value = GetCurrentColor().a;
2875 case Dali::Actor::WORLD_COLOR:
2877 value = GetCurrentWorldColor();
2881 case Dali::Actor::WORLD_MATRIX:
2883 value = GetCurrentWorldMatrix();
2887 case Dali::Actor::NAME:
2895 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2903 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2907 // mNode is being used in a separate thread; queue a message to add the property
2908 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2912 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2914 // This method should only return an object connected to the scene-graph
2915 return OnStage() ? mNode : NULL;
2918 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2920 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2922 const PropertyBase* property( NULL );
2924 // This method should only return a property of an object connected to the scene-graph
2930 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2932 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
2934 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
2936 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
2938 else if( NULL != mNode )
2942 case Dali::Actor::SIZE:
2943 property = &mNode->mSize;
2946 case Dali::Actor::SIZE_WIDTH:
2947 property = &mNode->mSize;
2950 case Dali::Actor::SIZE_HEIGHT:
2951 property = &mNode->mSize;
2954 case Dali::Actor::SIZE_DEPTH:
2955 property = &mNode->mSize;
2958 case Dali::Actor::POSITION:
2959 property = &mNode->mPosition;
2962 case Dali::Actor::POSITION_X:
2963 property = &mNode->mPosition;
2966 case Dali::Actor::POSITION_Y:
2967 property = &mNode->mPosition;
2970 case Dali::Actor::POSITION_Z:
2971 property = &mNode->mPosition;
2974 case Dali::Actor::ROTATION:
2975 property = &mNode->mRotation;
2978 case Dali::Actor::SCALE:
2979 property = &mNode->mScale;
2982 case Dali::Actor::SCALE_X:
2983 property = &mNode->mScale;
2986 case Dali::Actor::SCALE_Y:
2987 property = &mNode->mScale;
2990 case Dali::Actor::SCALE_Z:
2991 property = &mNode->mScale;
2994 case Dali::Actor::VISIBLE:
2995 property = &mNode->mVisible;
2998 case Dali::Actor::COLOR:
2999 property = &mNode->mColor;
3002 case Dali::Actor::COLOR_RED:
3003 property = &mNode->mColor;
3006 case Dali::Actor::COLOR_GREEN:
3007 property = &mNode->mColor;
3010 case Dali::Actor::COLOR_BLUE:
3011 property = &mNode->mColor;
3014 case Dali::Actor::COLOR_ALPHA:
3015 property = &mNode->mColor;
3026 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3028 const PropertyInputImpl* property( NULL );
3030 // This method should only return a property of an object connected to the scene-graph
3036 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3038 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3040 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3042 property = entry->second.GetSceneGraphProperty();
3044 else if( NULL != mNode )
3048 case Dali::Actor::PARENT_ORIGIN:
3049 property = &mNode->mParentOrigin;
3052 case Dali::Actor::PARENT_ORIGIN_X:
3053 property = &mNode->mParentOrigin;
3056 case Dali::Actor::PARENT_ORIGIN_Y:
3057 property = &mNode->mParentOrigin;
3060 case Dali::Actor::PARENT_ORIGIN_Z:
3061 property = &mNode->mParentOrigin;
3064 case Dali::Actor::ANCHOR_POINT:
3065 property = &mNode->mAnchorPoint;
3068 case Dali::Actor::ANCHOR_POINT_X:
3069 property = &mNode->mAnchorPoint;
3072 case Dali::Actor::ANCHOR_POINT_Y:
3073 property = &mNode->mAnchorPoint;
3076 case Dali::Actor::ANCHOR_POINT_Z:
3077 property = &mNode->mAnchorPoint;
3080 case Dali::Actor::SIZE:
3081 property = &mNode->mSize;
3084 case Dali::Actor::SIZE_WIDTH:
3085 property = &mNode->mSize;
3088 case Dali::Actor::SIZE_HEIGHT:
3089 property = &mNode->mSize;
3092 case Dali::Actor::SIZE_DEPTH:
3093 property = &mNode->mSize;
3096 case Dali::Actor::POSITION:
3097 property = &mNode->mPosition;
3100 case Dali::Actor::POSITION_X:
3101 property = &mNode->mPosition;
3104 case Dali::Actor::POSITION_Y:
3105 property = &mNode->mPosition;
3108 case Dali::Actor::POSITION_Z:
3109 property = &mNode->mPosition;
3112 case Dali::Actor::WORLD_POSITION:
3113 property = &mNode->mWorldPosition;
3116 case Dali::Actor::WORLD_POSITION_X:
3117 property = &mNode->mWorldPosition;
3120 case Dali::Actor::WORLD_POSITION_Y:
3121 property = &mNode->mWorldPosition;
3124 case Dali::Actor::WORLD_POSITION_Z:
3125 property = &mNode->mWorldPosition;
3128 case Dali::Actor::ROTATION:
3129 property = &mNode->mRotation;
3132 case Dali::Actor::WORLD_ROTATION:
3133 property = &mNode->mWorldRotation;
3136 case Dali::Actor::SCALE:
3137 property = &mNode->mScale;
3140 case Dali::Actor::SCALE_X:
3141 property = &mNode->mScale;
3144 case Dali::Actor::SCALE_Y:
3145 property = &mNode->mScale;
3148 case Dali::Actor::SCALE_Z:
3149 property = &mNode->mScale;
3152 case Dali::Actor::WORLD_SCALE:
3153 property = &mNode->mWorldScale;
3156 case Dali::Actor::VISIBLE:
3157 property = &mNode->mVisible;
3160 case Dali::Actor::COLOR:
3161 property = &mNode->mColor;
3164 case Dali::Actor::COLOR_RED:
3165 property = &mNode->mColor;
3168 case Dali::Actor::COLOR_GREEN:
3169 property = &mNode->mColor;
3172 case Dali::Actor::COLOR_BLUE:
3173 property = &mNode->mColor;
3176 case Dali::Actor::COLOR_ALPHA:
3177 property = &mNode->mColor;
3180 case Dali::Actor::WORLD_COLOR:
3181 property = &mNode->mWorldColor;
3184 case Dali::Actor::WORLD_MATRIX:
3185 property = &mNode->mWorldMatrix;
3196 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3198 int componentIndex( INVALID_PROPERTY_COMPONENT_INDEX );
3202 case Dali::Actor::PARENT_ORIGIN_X:
3203 case Dali::Actor::ANCHOR_POINT_X:
3204 case Dali::Actor::SIZE_WIDTH:
3205 case Dali::Actor::POSITION_X:
3206 case Dali::Actor::SCALE_X:
3207 case Dali::Actor::COLOR_RED:
3208 case Dali::Actor::WORLD_POSITION_X:
3214 case Dali::Actor::PARENT_ORIGIN_Y:
3215 case Dali::Actor::ANCHOR_POINT_Y:
3216 case Dali::Actor::SIZE_HEIGHT:
3217 case Dali::Actor::POSITION_Y:
3218 case Dali::Actor::SCALE_Y:
3219 case Dali::Actor::COLOR_GREEN:
3220 case Dali::Actor::WORLD_POSITION_Y:
3226 case Dali::Actor::PARENT_ORIGIN_Z:
3227 case Dali::Actor::ANCHOR_POINT_Z:
3228 case Dali::Actor::SIZE_DEPTH:
3229 case Dali::Actor::POSITION_Z:
3230 case Dali::Actor::SCALE_Z:
3231 case Dali::Actor::COLOR_BLUE:
3232 case Dali::Actor::WORLD_POSITION_Z:
3238 case Dali::Actor::COLOR_ALPHA:
3251 return componentIndex;
3254 void Actor::SetParent(Actor* parent)
3258 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3262 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3265 StagePtr stage = parent->mStage;
3267 // Instruct each actor to create a corresponding node in the scene graph
3268 ConnectToStage(*stage);
3271 else // parent being set to NULL
3273 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3277 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3280 DALI_ASSERT_ALWAYS(mNode != NULL);
3284 // Disconnect the Node & its children from the scene-graph.
3285 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3288 // Instruct each actor to discard pointers to the scene-graph
3289 DisconnectFromStage();
3294 SceneGraph::Node* Actor::CreateNode() const
3299 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3302 Actor* actor = dynamic_cast<Actor*>(object);
3306 if(Dali::Actor::ACTION_SHOW == actionName)
3308 actor->SetVisible(true);
3311 else if(Dali::Actor::ACTION_HIDE == actionName)
3313 actor->SetVisible(false);
3321 } // namespace Internal