2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/common/constants.h>
29 #include <dali/public-api/math/vector2.h>
30 #include <dali/public-api/math/vector3.h>
31 #include <dali/public-api/math/radian.h>
32 #include <dali/public-api/object/type-registry.h>
33 #include <dali/public-api/scripting/scripting.h>
35 #include <dali/internal/common/internal-constants.h>
36 #include <dali/internal/event/render-tasks/render-task-impl.h>
37 #include <dali/internal/event/actors/camera-actor-impl.h>
38 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
39 #include <dali/internal/event/common/property-index-ranges.h>
40 #include <dali/internal/event/common/stage-impl.h>
41 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
42 #include <dali/internal/event/animation/constraint-impl.h>
43 #include <dali/internal/event/common/projection.h>
44 #include <dali/internal/update/common/animatable-property.h>
45 #include <dali/internal/update/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
59 using Dali::Internal::SceneGraph::Node;
60 using Dali::Internal::SceneGraph::AnimatableProperty;
61 using Dali::Internal::SceneGraph::PropertyBase;
66 const Property::Index Actor::PARENT_ORIGIN = 0;
67 const Property::Index Actor::PARENT_ORIGIN_X = 1;
68 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
69 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
70 const Property::Index Actor::ANCHOR_POINT = 4;
71 const Property::Index Actor::ANCHOR_POINT_X = 5;
72 const Property::Index Actor::ANCHOR_POINT_Y = 6;
73 const Property::Index Actor::ANCHOR_POINT_Z = 7;
74 const Property::Index Actor::SIZE = 8;
75 const Property::Index Actor::SIZE_WIDTH = 9;
76 const Property::Index Actor::SIZE_HEIGHT = 10;
77 const Property::Index Actor::SIZE_DEPTH = 11;
78 const Property::Index Actor::POSITION = 12;
79 const Property::Index Actor::POSITION_X = 13;
80 const Property::Index Actor::POSITION_Y = 14;
81 const Property::Index Actor::POSITION_Z = 15;
82 const Property::Index Actor::WORLD_POSITION = 16;
83 const Property::Index Actor::WORLD_POSITION_X = 17;
84 const Property::Index Actor::WORLD_POSITION_Y = 18;
85 const Property::Index Actor::WORLD_POSITION_Z = 19;
86 const Property::Index Actor::ROTATION = 20;
87 const Property::Index Actor::WORLD_ROTATION = 21;
88 const Property::Index Actor::SCALE = 22;
89 const Property::Index Actor::SCALE_X = 23;
90 const Property::Index Actor::SCALE_Y = 24;
91 const Property::Index Actor::SCALE_Z = 25;
92 const Property::Index Actor::WORLD_SCALE = 26;
93 const Property::Index Actor::VISIBLE = 27;
94 const Property::Index Actor::COLOR = 28;
95 const Property::Index Actor::COLOR_RED = 29;
96 const Property::Index Actor::COLOR_GREEN = 30;
97 const Property::Index Actor::COLOR_BLUE = 31;
98 const Property::Index Actor::COLOR_ALPHA = 32;
99 const Property::Index Actor::WORLD_COLOR = 33;
100 const Property::Index Actor::WORLD_MATRIX = 34;
101 const Property::Index Actor::NAME = 35;
102 const Property::Index Actor::SENSITIVE = 36;
103 const Property::Index Actor::LEAVE_REQUIRED = 37;
104 const Property::Index Actor::INHERIT_ROTATION = 38;
105 const Property::Index Actor::INHERIT_SCALE = 39;
106 const Property::Index Actor::COLOR_MODE = 40;
107 const Property::Index Actor::POSITION_INHERITANCE = 41;
108 const Property::Index Actor::DRAW_MODE = 42;
109 const Property::Index Actor::SIZE_MODE = 43;
110 const Property::Index Actor::SIZE_MODE_FACTOR = 44;
112 namespace // unnamed namespace
116 * We want to discourage the use of property strings (minimize string comparisons),
117 * particularly for the default properties.
119 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
121 // Name Type writable animatable constraint-input
122 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
123 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
124 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
125 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
126 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
127 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
128 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
129 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
130 { "size", Property::VECTOR3, true, true, true }, // SIZE
131 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
132 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
133 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
134 { "position", Property::VECTOR3, true, true, true }, // POSITION
135 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
136 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
137 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
138 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
139 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
140 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
141 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
142 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
143 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
144 { "scale", Property::VECTOR3, true, true, true }, // SCALE
145 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
146 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
147 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
148 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
149 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
150 { "color", Property::VECTOR4, true, true, true }, // COLOR
151 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
152 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
153 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
154 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
155 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
156 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
157 { "name", Property::STRING, true, false, false }, // NAME
158 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
159 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
160 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
161 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
162 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
163 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
164 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
165 { "size-mode", Property::STRING, true, false, false }, // SIZE_MODE
166 { "size-mode-factor", Property::VECTOR3, true, false, false }, // SIZE_MODE_FACTOR
168 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
170 // Enumeration to/from text conversion tables:
171 const Scripting::StringEnum< SizeMode > SIZE_MODE_TABLE[] =
173 { "USE_OWN_SIZE", USE_OWN_SIZE },
174 { "SIZE_EQUAL_TO_PARENT", SIZE_EQUAL_TO_PARENT },
175 { "SIZE_RELATIVE_TO_PARENT", SIZE_RELATIVE_TO_PARENT },
176 { "SIZE_FIXED_OFFSET_FROM_PARENT", SIZE_FIXED_OFFSET_FROM_PARENT },
178 const unsigned int SIZE_MODE_TABLE_COUNT = sizeof( SIZE_MODE_TABLE ) / sizeof( SIZE_MODE_TABLE[0] );
180 } // unnamed namespace
185 unsigned int Actor::mActorCounter = 0;
186 ActorContainer Actor::mNullChildren;
188 #ifdef DYNAMICS_SUPPORT
190 // Encapsulate actor related dynamics data
193 DynamicsData( Actor* slotOwner )
194 : slotDelegate( slotOwner )
198 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
199 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
201 DynamicsBodyPtr body;
202 JointContainer joints;
203 ReferencedJointContainer referencedJoints;
205 SlotDelegate< Actor > slotDelegate;
208 #endif // DYNAMICS_SUPPORT
215 const char* const SIGNAL_TOUCHED = "touched";
216 const char* const SIGNAL_HOVERED = "hovered";
217 const char* const SIGNAL_MOUSE_WHEEL_EVENT = "mouse-wheel-event";
218 const char* const SIGNAL_ON_STAGE = "on-stage";
219 const char* const SIGNAL_OFF_STAGE = "off-stage";
223 const char* const ACTION_SHOW = "show";
224 const char* const ACTION_HIDE = "hide";
226 BaseHandle CreateActor()
228 return Dali::Actor::New();
231 TypeRegistration mType( typeid( Dali::Actor ), typeid( Dali::Handle ), CreateActor );
233 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
234 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
235 SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
236 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
238 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
239 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
243 ActorPtr Actor::New()
245 ActorPtr actor( new Actor( BASIC ) );
247 // Second-phase construction
253 const std::string& Actor::GetName() const
258 void Actor::SetName(const std::string& name)
264 // ATTENTION: string for debug purposes is not thread safe.
265 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
269 unsigned int Actor::GetId() const
274 void Actor::Attach( ActorAttachment& attachment )
276 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
280 attachment.Connect();
283 mAttachment = ActorAttachmentPtr(&attachment);
286 ActorAttachmentPtr Actor::GetAttachment()
291 bool Actor::OnStage() const
296 Dali::Layer Actor::GetLayer()
300 // Short-circuit for Layer derived actors
303 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
306 // Find the immediate Layer parent
307 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
309 if( parent->IsLayer() )
311 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
318 void Actor::Add(Actor& child)
320 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
321 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
325 mChildren = new ActorContainer;
328 Actor* const oldParent( child.mParent );
330 // child might already be ours
331 if( this != oldParent )
333 // if we already have parent, unparent us first
336 oldParent->Remove( child ); // This causes OnChildRemove callback
339 // Guard against Add() during previous OnChildRemove callback
340 if ( !child.mParent )
342 // Do this first, since user callbacks from within SetParent() may need to remove child
343 mChildren->push_back(Dali::Actor(&child));
345 // SetParent asserts that child can be added
346 child.SetParent(this);
348 // Notification for derived classes
354 void Actor::Insert(unsigned int index, Actor& child)
356 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
357 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
361 mChildren = new ActorContainer;
364 Actor* const oldParent( child.mParent );
366 // since an explicit position has been given, always insert, even if already a child
369 oldParent->Remove( child ); // This causes OnChildRemove callback
372 // Guard against Add() during previous OnChildRemove callback
373 if ( !child.mParent )
375 // Do this first, since user callbacks from within SetParent() may need to remove child
376 if (index < GetChildCount())
378 ActorIter it = mChildren->begin();
379 std::advance(it, index);
380 mChildren->insert(it, Dali::Actor(&child));
384 mChildren->push_back(Dali::Actor(&child));
386 // SetParent asserts that child can be added
387 child.SetParent(this, index);
389 // Notification for derived classes
394 void Actor::Remove(Actor& child)
396 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
406 // Find the child in mChildren, and unparent it
407 ActorIter end = mChildren->end();
408 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
410 Actor& actor = GetImplementation(*iter);
412 if( &actor == &child )
414 // Keep handle for OnChildRemove notification
415 removed = Dali::Actor( &actor );
417 // Do this first, since user callbacks from within SetParent() may need to add the child
418 mChildren->erase(iter);
420 DALI_ASSERT_DEBUG( actor.GetParent() == this );
421 actor.SetParent( NULL );
429 // Notification for derived classes
430 OnChildRemove( GetImplementation(removed) );
434 void Actor::Unparent()
438 mParent->Remove( *this );
442 unsigned int Actor::GetChildCount() const
444 return ( NULL != mChildren ) ? mChildren->size() : 0;
447 Dali::Actor Actor::GetChildAt(unsigned int index) const
449 DALI_ASSERT_ALWAYS( index < GetChildCount() );
451 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
454 ActorContainer Actor::GetChildren()
456 if( NULL != mChildren )
461 // return copy of mNullChildren
462 return mNullChildren;
465 const ActorContainer& Actor::GetChildren() const
467 if( NULL != mChildren )
472 // return const reference to mNullChildren
473 return mNullChildren;
476 ActorPtr Actor::FindChildByName(const std::string& actorName)
479 if (actorName == mName)
485 ActorIter end = mChildren->end();
486 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
488 child = GetImplementation(*iter).FindChildByName(actorName);
499 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
501 Dali::Actor child = DoGetChildByAlias(actorAlias);
503 // If not found then search by name.
506 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
509 child = Dali::Actor(child_ptr.Get());
516 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
518 Dali::Actor child = GetChildByAlias(actorAlias);
520 if (!child && mChildren )
522 ActorIter end = mChildren->end();
523 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
525 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
537 ActorPtr Actor::FindChildById(const unsigned int id)
546 ActorIter end = mChildren->end();
547 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
549 child = GetImplementation(*iter).FindChildById(id);
560 void Actor::SetParentOrigin( const Vector3& origin )
564 // mNode is being used in a separate thread; queue a message to set the value & base value
565 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
568 // Cache for event-thread access
571 // not allocated, check if different from default
572 if( ParentOrigin::DEFAULT != origin )
574 mParentOrigin = new Vector3( origin );
579 // check if different from current costs more than just set
580 *mParentOrigin = origin;
584 void Actor::SetParentOriginX( float x )
586 const Vector3& current = GetCurrentParentOrigin();
588 SetParentOrigin( Vector3( x, current.y, current.z ) );
591 void Actor::SetParentOriginY( float y )
593 const Vector3& current = GetCurrentParentOrigin();
595 SetParentOrigin( Vector3( current.x, y, current.z ) );
598 void Actor::SetParentOriginZ( float z )
600 const Vector3& current = GetCurrentParentOrigin();
602 SetParentOrigin( Vector3( current.x, current.y, z ) );
605 const Vector3& Actor::GetCurrentParentOrigin() const
607 // Cached for event-thread access
608 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
611 void Actor::SetAnchorPoint(const Vector3& anchor)
615 // mNode is being used in a separate thread; queue a message to set the value & base value
616 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
619 // Cache for event-thread access
622 // not allocated, check if different from default
623 if( AnchorPoint::DEFAULT != anchor )
625 mAnchorPoint = new Vector3( anchor );
630 // check if different from current costs more than just set
631 *mAnchorPoint = anchor;
635 void Actor::SetAnchorPointX( float x )
637 const Vector3& current = GetCurrentAnchorPoint();
639 SetAnchorPoint( Vector3( x, current.y, current.z ) );
642 void Actor::SetAnchorPointY( float y )
644 const Vector3& current = GetCurrentAnchorPoint();
646 SetAnchorPoint( Vector3( current.x, y, current.z ) );
649 void Actor::SetAnchorPointZ( float z )
651 const Vector3& current = GetCurrentAnchorPoint();
653 SetAnchorPoint( Vector3( current.x, current.y, z ) );
656 const Vector3& Actor::GetCurrentAnchorPoint() const
658 // Cached for event-thread access
659 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
662 void Actor::SetPosition(float x, float y)
664 SetPosition(Vector3(x, y, 0.0f));
667 void Actor::SetPosition(float x, float y, float z)
669 SetPosition(Vector3(x, y, z));
672 void Actor::SetPosition(const Vector3& position)
676 // mNode is being used in a separate thread; queue a message to set the value & base value
677 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
681 void Actor::SetX(float x)
685 // mNode is being used in a separate thread; queue a message to set the value & base value
686 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
690 void Actor::SetY(float y)
694 // mNode is being used in a separate thread; queue a message to set the value & base value
695 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
699 void Actor::SetZ(float z)
703 // mNode is being used in a separate thread; queue a message to set the value & base value
704 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
708 void Actor::MoveBy(const Vector3& distance)
712 // mNode is being used in a separate thread; queue a message to set the value & base value
713 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
717 const Vector3& Actor::GetCurrentPosition() const
721 // mNode is being used in a separate thread; copy the value from the previous update
722 return mNode->GetPosition(mStage->GetEventBufferIndex());
725 return Vector3::ZERO;
728 const Vector3& Actor::GetCurrentWorldPosition() const
732 // mNode is being used in a separate thread; copy the value from the previous update
733 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
736 return Vector3::ZERO;
739 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
741 // this flag is not animatable so keep the value
742 mPositionInheritanceMode = mode;
745 // mNode is being used in a separate thread; queue a message to set the value
746 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
750 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
752 // Cached for event-thread access
753 return mPositionInheritanceMode;
756 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
758 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
759 normalizedAxis.Normalize();
761 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
763 SetRotation(rotation);
766 void Actor::SetRotation(const Quaternion& rotation)
770 // mNode is being used in a separate thread; queue a message to set the value & base value
771 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
775 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
779 // mNode is being used in a separate thread; queue a message to set the value & base value
780 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
784 void Actor::RotateBy(const Quaternion& relativeRotation)
788 // mNode is being used in a separate thread; queue a message to set the value & base value
789 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
793 const Quaternion& Actor::GetCurrentRotation() const
797 // mNode is being used in a separate thread; copy the value from the previous update
798 return mNode->GetRotation(mStage->GetEventBufferIndex());
801 return Quaternion::IDENTITY;
804 const Quaternion& Actor::GetCurrentWorldRotation() const
808 // mNode is being used in a separate thread; copy the value from the previous update
809 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
812 return Quaternion::IDENTITY;
815 void Actor::SetScale(float scale)
817 SetScale(Vector3(scale, scale, scale));
820 void Actor::SetScale(float x, float y, float z)
822 SetScale(Vector3(x, y, z));
825 void Actor::SetScale(const Vector3& scale)
829 // mNode is being used in a separate thread; queue a message to set the value & base value
830 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
834 void Actor::SetScaleX( float x )
838 // mNode is being used in a separate thread; queue a message to set the value & base value
839 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
843 void Actor::SetScaleY( float y )
847 // mNode is being used in a separate thread; queue a message to set the value & base value
848 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
852 void Actor::SetScaleZ( float z )
856 // mNode is being used in a separate thread; queue a message to set the value & base value
857 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
861 void Actor::SetInitialVolume(const Vector3& volume)
865 // mNode is being used in a separate thread; queue a message to set the value
866 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
870 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
874 // mNode is being used in a separate thread; queue a message to set the value
875 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
879 bool Actor::GetTransmitGeometryScaling() const
883 // mNode is being used in a separate thread; copy the value from the previous update
884 return mNode->GetTransmitGeometryScaling();
890 void Actor::ScaleBy(const Vector3& relativeScale)
894 // mNode is being used in a separate thread; queue a message to set the value & base value
895 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
899 const Vector3& Actor::GetCurrentScale() const
903 // mNode is being used in a separate thread; copy the value from the previous update
904 return mNode->GetScale(mStage->GetEventBufferIndex());
910 const Vector3& Actor::GetCurrentWorldScale() const
914 // mNode is being used in a separate thread; copy the value from the previous update
915 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
921 void Actor::SetInheritScale( bool inherit )
923 // non animateable so keep local copy
924 mInheritScale = inherit;
927 // mNode is being used in a separate thread; queue a message to set the value
928 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
932 bool Actor::IsScaleInherited() const
934 return mInheritScale;
937 Matrix Actor::GetCurrentWorldMatrix() const
941 // World matrix is no longer updated unless there is something observing the node.
942 // Need to calculate it from node's world position, rotation and scale:
943 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
944 Matrix worldMatrix(false);
945 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
946 mNode->GetWorldRotation( updateBufferIndex ),
947 mNode->GetWorldPosition( updateBufferIndex ) );
951 return Matrix::IDENTITY;
954 void Actor::SetVisible(bool visible)
958 // mNode is being used in a separate thread; queue a message to set the value & base value
959 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
963 bool Actor::IsVisible() const
967 // mNode is being used in a separate thread; copy the value from the previous update
968 return mNode->IsVisible( mStage->GetEventBufferIndex() );
974 void Actor::SetOpacity(float opacity)
978 // mNode is being used in a separate thread; queue a message to set the value & base value
979 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
983 void Actor::OpacityBy(float relativeOpacity)
987 // mNode is being used in a separate thread; queue a message to set the value & base value
988 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
992 float Actor::GetCurrentOpacity() const
996 // mNode is being used in a separate thread; copy the value from the previous update
997 return mNode->GetOpacity(mStage->GetEventBufferIndex());
1003 const Vector4& Actor::GetCurrentWorldColor() const
1007 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
1010 return Color::WHITE;
1013 void Actor::SetColor(const Vector4& color)
1017 // mNode is being used in a separate thread; queue a message to set the value & base value
1018 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1022 void Actor::SetColorRed( float red )
1026 // mNode is being used in a separate thread; queue a message to set the value & base value
1027 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1031 void Actor::SetColorGreen( float green )
1035 // mNode is being used in a separate thread; queue a message to set the value & base value
1036 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1040 void Actor::SetColorBlue( float blue )
1044 // mNode is being used in a separate thread; queue a message to set the value & base value
1045 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1049 void Actor::ColorBy(const Vector4& relativeColor)
1053 // mNode is being used in a separate thread; queue a message to set the value & base value
1054 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1058 const Vector4& Actor::GetCurrentColor() const
1062 // mNode is being used in a separate thread; copy the value from the previous update
1063 return mNode->GetColor(mStage->GetEventBufferIndex());
1066 return Color::WHITE;
1069 void Actor::SetInheritRotation(bool inherit)
1071 // non animateable so keep local copy
1072 mInheritRotation = inherit;
1075 // mNode is being used in a separate thread; queue a message to set the value
1076 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1080 bool Actor::IsRotationInherited() const
1082 return mInheritRotation;
1085 void Actor::SetSizeMode(SizeMode mode)
1087 // non animateable so keep local copy
1091 // mNode is being used in a separate thread; queue a message to set the value
1092 SetSizeModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
1096 void Actor::SetSizeModeFactor(const Vector3& factor)
1098 // non animateable so keep local copy
1099 mSizeModeFactor = factor;
1102 // mNode is being used in a separate thread; queue a message to set the value
1103 SetSizeModeFactorMessage( mStage->GetUpdateInterface(), *mNode, factor );
1107 SizeMode Actor::GetSizeMode() const
1112 const Vector3& Actor::GetSizeModeFactor() const
1114 return mSizeModeFactor;
1117 void Actor::SetColorMode(ColorMode colorMode)
1119 // non animateable so keep local copy
1120 mColorMode = colorMode;
1123 // mNode is being used in a separate thread; queue a message to set the value
1124 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1128 ColorMode Actor::GetColorMode() const
1130 // we have cached copy
1134 void Actor::SetSize(float width, float height)
1136 SetSize( Vector2( width, height ) );
1139 void Actor::SetSize(float width, float height, float depth)
1141 SetSize( Vector3( width, height, depth ) );
1144 void Actor::SetSize(const Vector2& size)
1146 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1149 float Actor::CalculateSizeZ( const Vector2& size ) const
1151 return std::min( size.width, size.height );
1154 void Actor::SetSize(const Vector3& size)
1160 // mNode is being used in a separate thread; queue a message to set the value & base value
1161 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1163 // Notification for derived classes
1168 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1172 // Notify deriving classes
1173 OnSizeAnimation( animation, targetSize );
1176 void Actor::SetWidth( float width )
1180 // mNode is being used in a separate thread; queue a message to set the value & base value
1181 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1185 void Actor::SetHeight( float height )
1189 // mNode is being used in a separate thread; queue a message to set the value & base value
1190 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1194 void Actor::SetDepth( float depth )
1198 // mNode is being used in a separate thread; queue a message to set the value & base value
1199 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1203 const Vector3& Actor::GetSize() const
1208 const Vector3& Actor::GetCurrentSize() const
1212 // mNode is being used in a separate thread; copy the value from the previous update
1213 return mNode->GetSize( mStage->GetEventBufferIndex() );
1216 return Vector3::ZERO;
1219 Vector3 Actor::GetNaturalSize() const
1221 // It is up to deriving classes to return the appropriate natural size
1222 return Vector3( 0.0f, 0.0f, 0.0f );
1226 #ifdef DYNAMICS_SUPPORT
1228 //--------------- Dynamics ---------------
1230 void Actor::DisableDynamics()
1232 if( NULL != mDynamicsData )
1234 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1236 // ensure dynamics object are disconnected from scene
1237 DisconnectDynamics();
1239 // delete joint owned by this actor
1240 while( !mDynamicsData->joints.empty() )
1242 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1245 // delete other joints referencing this actor
1246 while( !mDynamicsData->referencedJoints.empty() )
1248 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1249 ActorPtr jointOwner( joint->GetActor( true ) );
1252 jointOwner->RemoveDynamicsJoint( joint );
1256 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1259 // delete the DynamicsBody object
1260 mDynamicsData->body.Reset();
1262 // Discard Dynamics data structure
1263 delete mDynamicsData;
1264 mDynamicsData = NULL;
1268 DynamicsBodyPtr Actor::GetDynamicsBody() const
1270 DynamicsBodyPtr body;
1272 if( NULL != mDynamicsData )
1274 body = mDynamicsData->body;
1280 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1282 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1284 if( NULL == mDynamicsData )
1286 mDynamicsData = new DynamicsData( this );
1289 if( !mDynamicsData->body )
1291 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1295 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1298 if( mParent == world->GetRootActor().Get() )
1300 mDynamicsData->body->Connect(*mStage);
1306 return mDynamicsData->body;
1309 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1311 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1312 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1315 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1317 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1318 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1320 DynamicsJointPtr joint;
1322 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1326 if( NULL != mDynamicsData )
1328 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1330 if( mDynamicsData->joints.end() != it )
1332 // use existing joint
1338 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1339 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1343 bodyA = EnableDynamics( new DynamicsBodyConfig );
1348 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1351 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1352 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1354 if( OnStage() && attachedActor->OnStage() )
1356 joint->Connect(*mStage);
1359 attachedActor->ReferenceJoint( joint );
1361 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1362 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1369 const int Actor::GetNumberOfJoints() const
1371 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1374 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1376 DynamicsJointPtr joint;
1378 if( NULL != mDynamicsData )
1380 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1382 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1384 for( int i = 0; i < index; ++i )
1396 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1398 DynamicsJointPtr joint;
1400 if( NULL != mDynamicsData )
1402 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1404 if( mDynamicsData->joints.end() != it )
1406 // use existing joint
1414 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1416 if( NULL != mDynamicsData )
1418 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1419 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1421 for( ; it != endIt; ++it )
1423 if( it->second == joint.Get() )
1425 ActorPtr attachedActor( it->first );
1427 if( OnStage() && attachedActor && attachedActor->OnStage() )
1429 joint->Disconnect(*mStage);
1434 attachedActor->ReleaseJoint( joint );
1435 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1436 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1439 mDynamicsData->joints.erase(it);
1446 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1448 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1450 if( NULL != mDynamicsData )
1452 mDynamicsData->referencedJoints.push_back(joint);
1456 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1458 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1460 if( NULL != mDynamicsData )
1462 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1464 if( it != mDynamicsData->referencedJoints.end() )
1466 mDynamicsData->referencedJoints.erase( it );
1471 void Actor::SetDynamicsRoot(bool flag)
1473 if( mIsDynamicsRoot != flag )
1475 mIsDynamicsRoot = flag;
1477 if( OnStage() && mChildren )
1479 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1480 ActorIter end = mChildren->end();
1481 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1483 Actor& child = GetImplementation(*iter);
1485 if( child.GetDynamicsBody() )
1487 if( mIsDynamicsRoot )
1489 child.ConnectDynamics();
1493 child.DisconnectDynamics();
1501 bool Actor::IsDynamicsRoot() const
1503 return mIsDynamicsRoot;
1506 void Actor::AttachedActorOnStage( Dali::Actor actor )
1508 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1512 ActorPtr attachedActor( &GetImplementation(actor) );
1514 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1515 if( NULL != mDynamicsData )
1517 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1518 if( mDynamicsData->joints.end() != it )
1520 DynamicsJointPtr joint( it->second );
1521 joint->Connect(*mStage);
1527 void Actor::AttachedActorOffStage( Dali::Actor actor )
1529 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1533 ActorPtr attachedActor( &GetImplementation(actor) );
1535 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1536 if( NULL != mDynamicsData )
1538 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1539 if( mDynamicsData->joints.end() != it )
1541 DynamicsJointPtr joint( it->second );
1542 joint->Disconnect(*mStage);
1548 void Actor::ConnectDynamics()
1550 if( NULL != mDynamicsData && mDynamicsData->body )
1552 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1554 mDynamicsData->body->Connect(*mStage);
1556 // Connect all joints where attachedActor is also on stage
1557 if( !mDynamicsData->joints.empty() )
1559 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1560 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1562 for( ; it != endIt; ++it )
1564 Actor* attachedActor( it->first );
1565 if( NULL != attachedActor && attachedActor->OnStage() )
1567 DynamicsJointPtr joint( it->second );
1569 joint->Connect(*mStage);
1577 void Actor::DisconnectDynamics()
1579 if( NULL != mDynamicsData && mDynamicsData->body )
1583 mDynamicsData->body->Disconnect(*mStage);
1585 // Disconnect all joints
1586 if( !mDynamicsData->joints.empty() )
1588 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1589 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1591 for( ; it != endIt; ++it )
1593 DynamicsJointPtr joint( it->second );
1595 joint->Disconnect(*mStage);
1602 #endif // DYNAMICS_SUPPORT
1604 void Actor::SetOverlay(bool enable)
1606 // Setting STENCIL will override OVERLAY
1607 if( DrawMode::STENCIL != mDrawMode )
1609 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1613 bool Actor::IsOverlay() const
1615 return ( DrawMode::OVERLAY == mDrawMode );
1618 void Actor::SetDrawMode( DrawMode::Type drawMode )
1620 // this flag is not animatable so keep the value
1621 mDrawMode = drawMode;
1624 // mNode is being used in a separate thread; queue a message to set the value
1625 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1629 DrawMode::Type Actor::GetDrawMode() const
1634 bool Actor::ScreenToLocal( float& localX,
1637 float screenY ) const
1639 // only valid when on-stage
1642 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1644 Vector2 converted( screenX, screenY );
1646 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1647 const int taskCount = taskList.GetTaskCount();
1648 for( int i = taskCount - 1; i >= 0; --i )
1650 Dali::RenderTask task = taskList.GetTask( i );
1651 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1653 // found a task where this conversion was ok so return
1661 bool Actor::ScreenToLocal( RenderTask& renderTask,
1665 float screenY ) const
1667 bool retval = false;
1668 // only valid when on-stage
1671 CameraActor* camera = renderTask.GetCameraActor();
1675 renderTask.GetViewport( viewport );
1677 // need to translate coordinates to render tasks coordinate space
1678 Vector2 converted( screenX, screenY );
1679 if( renderTask.TranslateCoordinates( converted ) )
1681 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1688 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1689 const Matrix& projectionMatrix,
1690 const Viewport& viewport,
1694 float screenY ) const
1696 // Early-out if mNode is NULL
1702 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1704 // Calculate the ModelView matrix
1705 Matrix modelView(false/*don't init*/);
1706 // need to use the components as world matrix is only updated for actors that need it
1707 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1708 Matrix::Multiply(modelView, modelView, viewMatrix);
1710 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1711 Matrix invertedMvp(false/*don't init*/);
1712 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1713 bool success = invertedMvp.Invert();
1715 // Convert to GL coordinates
1716 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1721 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1728 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1734 if (XyPlaneIntersect(nearPos, farPos, local))
1736 Vector3 size = GetCurrentSize();
1737 localX = local.x + size.x * 0.5f;
1738 localY = local.y + size.y * 0.5f;
1749 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1752 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1754 Mathematical Formulation
1756 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1758 ( p - c ) dot ( p - c ) = r^2
1760 Given a ray with a point of origin 'o', and a direction vector 'd':
1762 ray(t) = o + td, t >= 0
1764 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1766 (o + td - c ) dot ( o + td - c ) = r^2
1768 To solve for t we first expand the above into a more recognisable quadratic equation form
1770 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1779 B = 2( o - c ) dot d
1780 C = ( o - c ) dot ( o - c ) - r^2
1782 which can be solved using a standard quadratic formula.
1784 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1786 Practical Simplification
1788 In a renderer, we often differentiate between world space and object space. In the object space
1789 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1790 into object space, the mathematical solution presented above can be simplified significantly.
1792 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1796 and we can find the t at which the (transformed) ray intersects the sphere by
1798 ( o + td ) dot ( o + td ) = r^2
1800 According to the reasoning above, we expand the above quadratic equation into the general form
1804 which now has coefficients:
1811 // Early out if mNode is NULL
1817 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1819 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1820 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1821 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1822 rayOrigin.y - translation.y,
1823 rayOrigin.z - translation.z);
1825 // Compute the radius is not needed, square radius it's enough.
1826 const Vector3& size( mNode->GetSize( bufferIndex ) );
1828 // Scale the sphere.
1829 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1831 const float width = size.width * scale.width;
1832 const float height = size.height * scale.height;
1834 float squareSphereRadius = 0.5f * ( width * width + height * height );
1836 float a = rayDir.Dot( rayDir ); // a
1837 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1838 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1840 return ( b2*b2 - a*c ) >= 0.f;
1843 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1850 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1852 // Transforms the ray to the local reference system.
1854 // Calculate the inverse of Model matrix
1855 Matrix invModelMatrix(false/*don't init*/);
1856 // need to use the components as world matrix is only updated for actors that need it
1857 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1859 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1860 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1862 // Test with the actor's XY plane (Normal = 0 0 1 1).
1864 float a = -rayOriginLocal.z;
1865 float b = rayDirLocal.z;
1867 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1869 // Ray travels distance * rayDirLocal to intersect with plane.
1872 const Vector3& size = mNode->GetSize( bufferIndex );
1874 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1875 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1877 // Test with the actor's geometry.
1878 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1885 void Actor::SetLeaveRequired(bool required)
1887 mLeaveRequired = required;
1890 bool Actor::GetLeaveRequired() const
1892 return mLeaveRequired;
1895 void Actor::SetKeyboardFocusable( bool focusable )
1897 mKeyboardFocusable = focusable;
1900 bool Actor::IsKeyboardFocusable() const
1902 return mKeyboardFocusable;
1905 bool Actor::GetTouchRequired() const
1907 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1910 bool Actor::GetHoverRequired() const
1912 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1915 bool Actor::GetMouseWheelEventRequired() const
1917 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1920 bool Actor::IsHittable() const
1922 return IsSensitive() &&
1924 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1928 ActorGestureData& Actor::GetGestureData()
1930 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1931 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1932 if ( NULL == mGestureData )
1934 mGestureData = new ActorGestureData;
1936 return *mGestureData;
1939 bool Actor::IsGestureRequred( Gesture::Type type ) const
1941 return mGestureData && mGestureData->IsGestureRequred( type );
1944 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1946 bool consumed = false;
1948 if ( !mTouchedSignal.Empty() )
1950 Dali::Actor handle( this );
1951 consumed = mTouchedSignal.Emit( handle, event );
1956 // Notification for derived classes
1957 consumed = OnTouchEvent( event );
1963 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1965 bool consumed = false;
1967 if ( !mHoveredSignal.Empty() )
1969 Dali::Actor handle( this );
1970 consumed = mHoveredSignal.Emit( handle, event );
1975 // Notification for derived classes
1976 consumed = OnHoverEvent( event );
1982 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1984 bool consumed = false;
1986 if ( !mMouseWheelEventSignal.Empty() )
1988 Dali::Actor handle( this );
1989 consumed = mMouseWheelEventSignal.Emit( handle, event );
1994 // Notification for derived classes
1995 consumed = OnMouseWheelEvent(event);
2001 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
2003 return mTouchedSignal;
2006 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
2008 return mHoveredSignal;
2011 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
2013 return mMouseWheelEventSignal;
2016 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
2018 return mOnStageSignal;
2021 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
2023 return mOffStageSignal;
2026 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2028 bool connected( true );
2029 Actor* actor = dynamic_cast<Actor*>( object );
2031 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
2033 actor->TouchedSignal().Connect( tracker, functor );
2035 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
2037 actor->HoveredSignal().Connect( tracker, functor );
2039 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
2041 actor->MouseWheelEventSignal().Connect( tracker, functor );
2043 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
2045 actor->OnStageSignal().Connect( tracker, functor );
2047 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
2049 actor->OffStageSignal().Connect( tracker, functor );
2053 // signalName does not match any signal
2060 Actor::Actor( DerivedType derivedType )
2065 mParentOrigin( NULL ),
2066 mAnchorPoint( NULL ),
2067 #ifdef DYNAMICS_SUPPORT
2068 mDynamicsData( NULL ),
2070 mGestureData( NULL ),
2072 mSize( 0.0f, 0.0f, 0.0f ),
2073 mSizeModeFactor( Vector3::ONE ),
2075 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2076 mIsRoot( ROOT_LAYER == derivedType ),
2077 mIsRenderable( RENDERABLE == derivedType ),
2078 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2079 mIsOnStage( false ),
2080 mIsDynamicsRoot(false),
2082 mLeaveRequired( false ),
2083 mKeyboardFocusable( false ),
2084 mDerivedRequiresTouch( false ),
2085 mDerivedRequiresHover( false ),
2086 mDerivedRequiresMouseWheelEvent( false ),
2087 mOnStageSignalled( false ),
2088 mInheritRotation( true ),
2089 mInheritScale( true ),
2090 mDrawMode( DrawMode::NORMAL ),
2091 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2092 mColorMode( Node::DEFAULT_COLOR_MODE ),
2093 mSizeMode( Node::DEFAULT_SIZE_MODE )
2097 void Actor::Initialize()
2099 mStage = Stage::GetCurrent();
2100 DALI_ASSERT_ALWAYS( mStage && "Stage doesn't exist" );
2103 SceneGraph::Node* node = CreateNode();
2105 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2106 mNode = node; // Keep raw-pointer to Node
2110 mStage->RegisterObject( this );
2115 // Remove mParent pointers from children even if we're destroying core,
2116 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2119 ActorConstIter endIter = mChildren->end();
2120 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2122 Actor& actor = GetImplementation( *iter );
2123 actor.SetParent( NULL );
2128 // Guard to allow handle destruction after Core has been destroyed
2129 if( Stage::IsInstalled() )
2133 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2134 mNode = NULL; // Node is about to be destroyed
2137 mStage->UnregisterObject( this );
2140 #ifdef DYNAMICS_SUPPORT
2142 delete mDynamicsData;
2145 // Cleanup optional gesture data
2146 delete mGestureData;
2148 // Cleanup optional parent origin and anchor
2149 delete mParentOrigin;
2150 delete mAnchorPoint;
2153 void Actor::ConnectToStage( int index )
2155 // This container is used instead of walking the Actor hierachy.
2156 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2157 ActorContainer connectionList;
2159 // This stage is atomic i.e. not interrupted by user callbacks
2160 RecursiveConnectToStage( connectionList, index );
2162 // Notify applications about the newly connected actors.
2163 const ActorIter endIter = connectionList.end();
2164 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2166 Actor& actor = GetImplementation(*iter);
2167 actor.NotifyStageConnection();
2171 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2173 DALI_ASSERT_ALWAYS( !OnStage() );
2177 ConnectToSceneGraph(index);
2179 // Notification for internal derived classes
2180 OnStageConnectionInternal();
2182 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2183 connectionList.push_back( Dali::Actor(this) );
2185 // Recursively connect children
2188 ActorConstIter endIter = mChildren->end();
2189 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2191 Actor& actor = GetImplementation( *iter );
2192 actor.RecursiveConnectToStage( connectionList );
2198 * This method is called when the Actor is connected to the Stage.
2199 * The parent must have added its Node to the scene-graph.
2200 * The child must connect its Node to the parent's Node.
2201 * This is resursive; the child calls ConnectToStage() for its children.
2203 void Actor::ConnectToSceneGraph(int index)
2205 DALI_ASSERT_DEBUG( mNode != NULL);
2206 DALI_ASSERT_DEBUG( mParent != NULL);
2207 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2211 // Reparent Node in next Update
2212 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2215 // Notify attachment
2218 mAttachment->Connect();
2221 #ifdef DYNAMICS_SUPPORT
2223 if( NULL != mDynamicsData )
2229 // Notification for Object::Observers
2233 void Actor::NotifyStageConnection()
2235 // Actors can be removed (in a callback), before the on-stage stage is reported.
2236 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2237 if ( OnStage() && !mOnStageSignalled )
2239 // Notification for external (CustomActor) derived classes
2240 OnStageConnectionExternal();
2242 if ( !mOnStageSignal.Empty() )
2244 Dali::Actor handle( this );
2245 mOnStageSignal.Emit( handle );
2248 // Guard against Remove during callbacks
2251 mOnStageSignalled = true; // signal required next time Actor is removed
2256 void Actor::DisconnectFromStage()
2258 // This container is used instead of walking the Actor hierachy.
2259 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2260 ActorContainer disconnectionList;
2262 // This stage is atomic i.e. not interrupted by user callbacks
2263 RecursiveDisconnectFromStage( disconnectionList );
2265 // Notify applications about the newly disconnected actors.
2266 const ActorIter endIter = disconnectionList.end();
2267 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2269 Actor& actor = GetImplementation(*iter);
2270 actor.NotifyStageDisconnection();
2274 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2276 DALI_ASSERT_ALWAYS( OnStage() );
2278 // Recursively disconnect children
2281 ActorConstIter endIter = mChildren->end();
2282 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2284 Actor& actor = GetImplementation( *iter );
2285 actor.RecursiveDisconnectFromStage( disconnectionList );
2289 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2290 disconnectionList.push_back( Dali::Actor(this) );
2292 // Notification for internal derived classes
2293 OnStageDisconnectionInternal();
2295 DisconnectFromSceneGraph();
2301 * This method is called by an actor or its parent, before a node removal message is sent.
2302 * This is recursive; the child calls DisconnectFromStage() for its children.
2304 void Actor::DisconnectFromSceneGraph()
2306 // Notification for Object::Observers
2307 OnSceneObjectRemove();
2309 // Notify attachment
2312 mAttachment->Disconnect();
2315 #ifdef DYNAMICS_SUPPORT
2317 if( NULL != mDynamicsData )
2319 DisconnectDynamics();
2324 void Actor::NotifyStageDisconnection()
2326 // Actors can be added (in a callback), before the off-stage state is reported.
2327 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2328 // only do this step if there is a stage, i.e. Core is not being shut down
2329 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2331 // Notification for external (CustomeActor) derived classes
2332 OnStageDisconnectionExternal();
2334 if( !mOffStageSignal.Empty() )
2336 Dali::Actor handle( this );
2337 mOffStageSignal.Emit( handle );
2340 // Guard against Add during callbacks
2343 mOnStageSignalled = false; // signal required next time Actor is added
2348 bool Actor::IsNodeConnected() const
2350 bool connected( false );
2355 if( mNode->IsRoot() || mNode->GetParent() )
2364 unsigned int Actor::GetDefaultPropertyCount() const
2366 return DEFAULT_PROPERTY_COUNT;
2369 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2371 indices.reserve( DEFAULT_PROPERTY_COUNT );
2373 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2375 indices.push_back( i );
2379 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2381 if( index < DEFAULT_PROPERTY_COUNT )
2383 return DEFAULT_PROPERTY_DETAILS[index].name;
2391 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2393 Property::Index index = Property::INVALID_INDEX;
2395 // Look for name in default properties
2396 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2398 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2399 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2409 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2411 if( index < DEFAULT_PROPERTY_COUNT )
2413 return DEFAULT_PROPERTY_DETAILS[index].writable;
2421 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2423 if( index < DEFAULT_PROPERTY_COUNT )
2425 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2433 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2435 if( index < DEFAULT_PROPERTY_COUNT )
2437 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2445 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2447 if( index < DEFAULT_PROPERTY_COUNT )
2449 return DEFAULT_PROPERTY_DETAILS[index].type;
2453 // index out of range...return Property::NONE
2454 return Property::NONE;
2458 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2462 case Dali::Actor::PARENT_ORIGIN:
2464 SetParentOrigin( property.Get<Vector3>() );
2468 case Dali::Actor::PARENT_ORIGIN_X:
2470 SetParentOriginX( property.Get<float>() );
2474 case Dali::Actor::PARENT_ORIGIN_Y:
2476 SetParentOriginY( property.Get<float>() );
2480 case Dali::Actor::PARENT_ORIGIN_Z:
2482 SetParentOriginZ( property.Get<float>() );
2486 case Dali::Actor::ANCHOR_POINT:
2488 SetAnchorPoint( property.Get<Vector3>() );
2492 case Dali::Actor::ANCHOR_POINT_X:
2494 SetAnchorPointX( property.Get<float>() );
2498 case Dali::Actor::ANCHOR_POINT_Y:
2500 SetAnchorPointY( property.Get<float>() );
2504 case Dali::Actor::ANCHOR_POINT_Z:
2506 SetAnchorPointZ( property.Get<float>() );
2510 case Dali::Actor::SIZE:
2512 SetSize( property.Get<Vector3>() );
2516 case Dali::Actor::SIZE_WIDTH:
2518 SetWidth( property.Get<float>() );
2522 case Dali::Actor::SIZE_HEIGHT:
2524 SetHeight( property.Get<float>() );
2528 case Dali::Actor::SIZE_DEPTH:
2530 SetDepth( property.Get<float>() );
2534 case Dali::Actor::POSITION:
2536 SetPosition( property.Get<Vector3>() );
2540 case Dali::Actor::POSITION_X:
2542 SetX( property.Get<float>() );
2546 case Dali::Actor::POSITION_Y:
2548 SetY( property.Get<float>() );
2552 case Dali::Actor::POSITION_Z:
2554 SetZ( property.Get<float>() );
2558 case Dali::Actor::ROTATION:
2560 SetRotation( property.Get<Quaternion>() );
2564 case Dali::Actor::SCALE:
2566 SetScale( property.Get<Vector3>() );
2570 case Dali::Actor::SCALE_X:
2572 SetScaleX( property.Get<float>() );
2576 case Dali::Actor::SCALE_Y:
2578 SetScaleY( property.Get<float>() );
2582 case Dali::Actor::SCALE_Z:
2584 SetScaleZ( property.Get<float>() );
2588 case Dali::Actor::VISIBLE:
2590 SetVisible( property.Get<bool>() );
2594 case Dali::Actor::COLOR:
2596 SetColor( property.Get<Vector4>() );
2600 case Dali::Actor::COLOR_RED:
2602 SetColorRed( property.Get<float>() );
2606 case Dali::Actor::COLOR_GREEN:
2608 SetColorGreen( property.Get<float>() );
2612 case Dali::Actor::COLOR_BLUE:
2614 SetColorBlue( property.Get<float>() );
2618 case Dali::Actor::COLOR_ALPHA:
2620 SetOpacity( property.Get<float>() );
2624 case Dali::Actor::NAME:
2626 SetName( property.Get<std::string>() );
2630 case Dali::Actor::SENSITIVE:
2632 SetSensitive( property.Get<bool>() );
2636 case Dali::Actor::LEAVE_REQUIRED:
2638 SetLeaveRequired( property.Get<bool>() );
2642 case Dali::Actor::INHERIT_ROTATION:
2644 SetInheritRotation( property.Get<bool>() );
2648 case Dali::Actor::SIZE_MODE:
2650 SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SIZE_MODE_TABLE, SIZE_MODE_TABLE_COUNT ) );
2654 case Dali::Actor::SIZE_MODE_FACTOR:
2656 SetSizeModeFactor( property.Get<Vector3>() );
2660 case Dali::Actor::INHERIT_SCALE:
2662 SetInheritScale( property.Get<bool>() );
2666 case Dali::Actor::COLOR_MODE:
2668 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2672 case Dali::Actor::POSITION_INHERITANCE:
2674 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2678 case Dali::Actor::DRAW_MODE:
2680 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2686 // this can happen in the case of a non-animatable default property so just do nothing
2692 // TODO: This method needs to be removed
2693 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2695 OnPropertySet(index, value);
2697 switch ( entry.type )
2699 case Property::BOOLEAN:
2701 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2702 DALI_ASSERT_DEBUG( NULL != property );
2704 // property is being used in a separate thread; queue a message to set the property
2705 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2710 case Property::FLOAT:
2712 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2713 DALI_ASSERT_DEBUG( NULL != property );
2715 // property is being used in a separate thread; queue a message to set the property
2716 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2721 case Property::INTEGER:
2723 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2724 DALI_ASSERT_DEBUG( NULL != property );
2726 // property is being used in a separate thread; queue a message to set the property
2727 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2732 case Property::VECTOR2:
2734 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2735 DALI_ASSERT_DEBUG( NULL != property );
2737 // property is being used in a separate thread; queue a message to set the property
2738 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2743 case Property::VECTOR3:
2745 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2746 DALI_ASSERT_DEBUG( NULL != property );
2748 // property is being used in a separate thread; queue a message to set the property
2749 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2754 case Property::VECTOR4:
2756 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2757 DALI_ASSERT_DEBUG( NULL != property );
2759 // property is being used in a separate thread; queue a message to set the property
2760 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2765 case Property::ROTATION:
2767 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2768 DALI_ASSERT_DEBUG( NULL != property );
2770 // property is being used in a separate thread; queue a message to set the property
2771 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2776 case Property::MATRIX:
2778 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2779 DALI_ASSERT_DEBUG( NULL != property );
2781 // property is being used in a separate thread; queue a message to set the property
2782 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2787 case Property::MATRIX3:
2789 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2790 DALI_ASSERT_DEBUG( NULL != property );
2792 // property is being used in a separate thread; queue a message to set the property
2793 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2800 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2806 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2808 Property::Value value;
2812 case Dali::Actor::PARENT_ORIGIN:
2814 value = GetCurrentParentOrigin();
2818 case Dali::Actor::PARENT_ORIGIN_X:
2820 value = GetCurrentParentOrigin().x;
2824 case Dali::Actor::PARENT_ORIGIN_Y:
2826 value = GetCurrentParentOrigin().y;
2830 case Dali::Actor::PARENT_ORIGIN_Z:
2832 value = GetCurrentParentOrigin().z;
2836 case Dali::Actor::ANCHOR_POINT:
2838 value = GetCurrentAnchorPoint();
2842 case Dali::Actor::ANCHOR_POINT_X:
2844 value = GetCurrentAnchorPoint().x;
2848 case Dali::Actor::ANCHOR_POINT_Y:
2850 value = GetCurrentAnchorPoint().y;
2854 case Dali::Actor::ANCHOR_POINT_Z:
2856 value = GetCurrentAnchorPoint().z;
2860 case Dali::Actor::SIZE:
2862 value = GetCurrentSize();
2866 case Dali::Actor::SIZE_WIDTH:
2868 value = GetCurrentSize().width;
2872 case Dali::Actor::SIZE_HEIGHT:
2874 value = GetCurrentSize().height;
2878 case Dali::Actor::SIZE_DEPTH:
2880 value = GetCurrentSize().depth;
2884 case Dali::Actor::POSITION:
2886 value = GetCurrentPosition();
2890 case Dali::Actor::POSITION_X:
2892 value = GetCurrentPosition().x;
2896 case Dali::Actor::POSITION_Y:
2898 value = GetCurrentPosition().y;
2902 case Dali::Actor::POSITION_Z:
2904 value = GetCurrentPosition().z;
2908 case Dali::Actor::WORLD_POSITION:
2910 value = GetCurrentWorldPosition();
2914 case Dali::Actor::WORLD_POSITION_X:
2916 value = GetCurrentWorldPosition().x;
2920 case Dali::Actor::WORLD_POSITION_Y:
2922 value = GetCurrentWorldPosition().y;
2926 case Dali::Actor::WORLD_POSITION_Z:
2928 value = GetCurrentWorldPosition().z;
2932 case Dali::Actor::ROTATION:
2934 value = GetCurrentRotation();
2938 case Dali::Actor::WORLD_ROTATION:
2940 value = GetCurrentWorldRotation();
2944 case Dali::Actor::SCALE:
2946 value = GetCurrentScale();
2950 case Dali::Actor::SCALE_X:
2952 value = GetCurrentScale().x;
2956 case Dali::Actor::SCALE_Y:
2958 value = GetCurrentScale().y;
2962 case Dali::Actor::SCALE_Z:
2964 value = GetCurrentScale().z;
2968 case Dali::Actor::WORLD_SCALE:
2970 value = GetCurrentWorldScale();
2974 case Dali::Actor::VISIBLE:
2976 value = IsVisible();
2980 case Dali::Actor::COLOR:
2982 value = GetCurrentColor();
2986 case Dali::Actor::COLOR_RED:
2988 value = GetCurrentColor().r;
2992 case Dali::Actor::COLOR_GREEN:
2994 value = GetCurrentColor().g;
2998 case Dali::Actor::COLOR_BLUE:
3000 value = GetCurrentColor().b;
3004 case Dali::Actor::COLOR_ALPHA:
3006 value = GetCurrentColor().a;
3010 case Dali::Actor::WORLD_COLOR:
3012 value = GetCurrentWorldColor();
3016 case Dali::Actor::WORLD_MATRIX:
3018 value = GetCurrentWorldMatrix();
3022 case Dali::Actor::NAME:
3028 case Dali::Actor::SENSITIVE:
3030 value = IsSensitive();
3034 case Dali::Actor::LEAVE_REQUIRED:
3036 value = GetLeaveRequired();
3040 case Dali::Actor::INHERIT_ROTATION:
3042 value = IsRotationInherited();
3046 case Dali::Actor::SIZE_MODE:
3048 value = Scripting::GetEnumerationName< SizeMode >( GetSizeMode(), SIZE_MODE_TABLE, SIZE_MODE_TABLE_COUNT );
3052 case Dali::Actor::SIZE_MODE_FACTOR:
3054 value = GetSizeModeFactor();
3058 case Dali::Actor::INHERIT_SCALE:
3060 value = IsScaleInherited();
3064 case Dali::Actor::COLOR_MODE:
3066 value = Scripting::GetColorMode( GetColorMode() );
3070 case Dali::Actor::POSITION_INHERITANCE:
3072 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3076 case Dali::Actor::DRAW_MODE:
3078 value = Scripting::GetDrawMode( GetDrawMode() );
3084 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3092 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3097 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3099 // This method should only return an object connected to the scene-graph
3100 return OnStage() ? mNode : NULL;
3103 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3105 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3107 const PropertyBase* property( NULL );
3109 // This method should only return a property of an object connected to the scene-graph
3115 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3117 CustomProperty* custom = FindCustomProperty( index );
3118 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3120 property = custom->GetSceneGraphProperty();
3122 else if( NULL != mNode )
3126 case Dali::Actor::SIZE:
3127 property = &mNode->mSize;
3130 case Dali::Actor::SIZE_WIDTH:
3131 property = &mNode->mSize;
3134 case Dali::Actor::SIZE_HEIGHT:
3135 property = &mNode->mSize;
3138 case Dali::Actor::SIZE_DEPTH:
3139 property = &mNode->mSize;
3142 case Dali::Actor::POSITION:
3143 property = &mNode->mPosition;
3146 case Dali::Actor::POSITION_X:
3147 property = &mNode->mPosition;
3150 case Dali::Actor::POSITION_Y:
3151 property = &mNode->mPosition;
3154 case Dali::Actor::POSITION_Z:
3155 property = &mNode->mPosition;
3158 case Dali::Actor::ROTATION:
3159 property = &mNode->mRotation;
3162 case Dali::Actor::SCALE:
3163 property = &mNode->mScale;
3166 case Dali::Actor::SCALE_X:
3167 property = &mNode->mScale;
3170 case Dali::Actor::SCALE_Y:
3171 property = &mNode->mScale;
3174 case Dali::Actor::SCALE_Z:
3175 property = &mNode->mScale;
3178 case Dali::Actor::VISIBLE:
3179 property = &mNode->mVisible;
3182 case Dali::Actor::COLOR:
3183 property = &mNode->mColor;
3186 case Dali::Actor::COLOR_RED:
3187 property = &mNode->mColor;
3190 case Dali::Actor::COLOR_GREEN:
3191 property = &mNode->mColor;
3194 case Dali::Actor::COLOR_BLUE:
3195 property = &mNode->mColor;
3198 case Dali::Actor::COLOR_ALPHA:
3199 property = &mNode->mColor;
3210 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3212 const PropertyInputImpl* property( NULL );
3214 // This method should only return a property of an object connected to the scene-graph
3220 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3222 CustomProperty* custom = FindCustomProperty( index );
3223 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3224 property = custom->GetSceneGraphProperty();
3226 else if( NULL != mNode )
3230 case Dali::Actor::PARENT_ORIGIN:
3231 property = &mNode->mParentOrigin;
3234 case Dali::Actor::PARENT_ORIGIN_X:
3235 property = &mNode->mParentOrigin;
3238 case Dali::Actor::PARENT_ORIGIN_Y:
3239 property = &mNode->mParentOrigin;
3242 case Dali::Actor::PARENT_ORIGIN_Z:
3243 property = &mNode->mParentOrigin;
3246 case Dali::Actor::ANCHOR_POINT:
3247 property = &mNode->mAnchorPoint;
3250 case Dali::Actor::ANCHOR_POINT_X:
3251 property = &mNode->mAnchorPoint;
3254 case Dali::Actor::ANCHOR_POINT_Y:
3255 property = &mNode->mAnchorPoint;
3258 case Dali::Actor::ANCHOR_POINT_Z:
3259 property = &mNode->mAnchorPoint;
3262 case Dali::Actor::SIZE:
3263 property = &mNode->mSize;
3266 case Dali::Actor::SIZE_WIDTH:
3267 property = &mNode->mSize;
3270 case Dali::Actor::SIZE_HEIGHT:
3271 property = &mNode->mSize;
3274 case Dali::Actor::SIZE_DEPTH:
3275 property = &mNode->mSize;
3278 case Dali::Actor::POSITION:
3279 property = &mNode->mPosition;
3282 case Dali::Actor::POSITION_X:
3283 property = &mNode->mPosition;
3286 case Dali::Actor::POSITION_Y:
3287 property = &mNode->mPosition;
3290 case Dali::Actor::POSITION_Z:
3291 property = &mNode->mPosition;
3294 case Dali::Actor::WORLD_POSITION:
3295 property = &mNode->mWorldPosition;
3298 case Dali::Actor::WORLD_POSITION_X:
3299 property = &mNode->mWorldPosition;
3302 case Dali::Actor::WORLD_POSITION_Y:
3303 property = &mNode->mWorldPosition;
3306 case Dali::Actor::WORLD_POSITION_Z:
3307 property = &mNode->mWorldPosition;
3310 case Dali::Actor::ROTATION:
3311 property = &mNode->mRotation;
3314 case Dali::Actor::WORLD_ROTATION:
3315 property = &mNode->mWorldRotation;
3318 case Dali::Actor::SCALE:
3319 property = &mNode->mScale;
3322 case Dali::Actor::SCALE_X:
3323 property = &mNode->mScale;
3326 case Dali::Actor::SCALE_Y:
3327 property = &mNode->mScale;
3330 case Dali::Actor::SCALE_Z:
3331 property = &mNode->mScale;
3334 case Dali::Actor::WORLD_SCALE:
3335 property = &mNode->mWorldScale;
3338 case Dali::Actor::VISIBLE:
3339 property = &mNode->mVisible;
3342 case Dali::Actor::COLOR:
3343 property = &mNode->mColor;
3346 case Dali::Actor::COLOR_RED:
3347 property = &mNode->mColor;
3350 case Dali::Actor::COLOR_GREEN:
3351 property = &mNode->mColor;
3354 case Dali::Actor::COLOR_BLUE:
3355 property = &mNode->mColor;
3358 case Dali::Actor::COLOR_ALPHA:
3359 property = &mNode->mColor;
3362 case Dali::Actor::WORLD_COLOR:
3363 property = &mNode->mWorldColor;
3366 case Dali::Actor::WORLD_MATRIX:
3367 property = &mNode->mWorldMatrix;
3378 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3380 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3384 case Dali::Actor::PARENT_ORIGIN_X:
3385 case Dali::Actor::ANCHOR_POINT_X:
3386 case Dali::Actor::SIZE_WIDTH:
3387 case Dali::Actor::POSITION_X:
3388 case Dali::Actor::SCALE_X:
3389 case Dali::Actor::COLOR_RED:
3390 case Dali::Actor::WORLD_POSITION_X:
3396 case Dali::Actor::PARENT_ORIGIN_Y:
3397 case Dali::Actor::ANCHOR_POINT_Y:
3398 case Dali::Actor::SIZE_HEIGHT:
3399 case Dali::Actor::POSITION_Y:
3400 case Dali::Actor::SCALE_Y:
3401 case Dali::Actor::COLOR_GREEN:
3402 case Dali::Actor::WORLD_POSITION_Y:
3408 case Dali::Actor::PARENT_ORIGIN_Z:
3409 case Dali::Actor::ANCHOR_POINT_Z:
3410 case Dali::Actor::SIZE_DEPTH:
3411 case Dali::Actor::POSITION_Z:
3412 case Dali::Actor::SCALE_Z:
3413 case Dali::Actor::COLOR_BLUE:
3414 case Dali::Actor::WORLD_POSITION_Z:
3420 case Dali::Actor::COLOR_ALPHA:
3433 return componentIndex;
3436 void Actor::SetParent(Actor* parent, int index)
3440 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3444 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3447 // Instruct each actor to create a corresponding node in the scene graph
3448 ConnectToStage( index );
3451 else // parent being set to NULL
3453 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3457 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3460 DALI_ASSERT_ALWAYS(mNode != NULL);
3464 // Disconnect the Node & its children from the scene-graph.
3465 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3468 // Instruct each actor to discard pointers to the scene-graph
3469 DisconnectFromStage();
3474 SceneGraph::Node* Actor::CreateNode() const
3479 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
3482 Actor* actor = dynamic_cast<Actor*>( object );
3486 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3488 actor->SetVisible(true);
3491 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3493 actor->SetVisible(false);
3501 } // namespace Internal