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/common/property-owner-messages.h>
46 #include <dali/internal/update/nodes/node-messages.h>
47 #include <dali/internal/update/nodes/node-declarations.h>
48 #include <dali/internal/update/animation/scene-graph-constraint.h>
49 #include <dali/internal/event/effects/shader-effect-impl.h>
50 #include <dali/internal/common/message.h>
51 #include <dali/integration-api/debug.h>
53 #ifdef DYNAMICS_SUPPORT
54 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
60 #include <dali/internal/event/events/pan-gesture-detector-impl.h>
61 #include <dali/internal/event/events/pinch-gesture-detector-impl.h>
62 #include <dali/internal/event/events/long-press-gesture-detector-impl.h>
63 #include <dali/internal/event/events/tap-gesture-detector-impl.h>
65 using Dali::Internal::SceneGraph::Node;
66 using Dali::Internal::SceneGraph::AnimatableProperty;
67 using Dali::Internal::SceneGraph::PropertyBase;
68 using Dali::Internal::SceneGraph::Shader;
75 const Property::Index Actor::PARENT_ORIGIN = 0;
76 const Property::Index Actor::PARENT_ORIGIN_X = 1;
77 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
78 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
79 const Property::Index Actor::ANCHOR_POINT = 4;
80 const Property::Index Actor::ANCHOR_POINT_X = 5;
81 const Property::Index Actor::ANCHOR_POINT_Y = 6;
82 const Property::Index Actor::ANCHOR_POINT_Z = 7;
83 const Property::Index Actor::SIZE = 8;
84 const Property::Index Actor::SIZE_WIDTH = 9;
85 const Property::Index Actor::SIZE_HEIGHT = 10;
86 const Property::Index Actor::SIZE_DEPTH = 11;
87 const Property::Index Actor::POSITION = 12;
88 const Property::Index Actor::POSITION_X = 13;
89 const Property::Index Actor::POSITION_Y = 14;
90 const Property::Index Actor::POSITION_Z = 15;
91 const Property::Index Actor::WORLD_POSITION = 16;
92 const Property::Index Actor::WORLD_POSITION_X = 17;
93 const Property::Index Actor::WORLD_POSITION_Y = 18;
94 const Property::Index Actor::WORLD_POSITION_Z = 19;
95 const Property::Index Actor::ROTATION = 20;
96 const Property::Index Actor::WORLD_ROTATION = 21;
97 const Property::Index Actor::SCALE = 22;
98 const Property::Index Actor::SCALE_X = 23;
99 const Property::Index Actor::SCALE_Y = 24;
100 const Property::Index Actor::SCALE_Z = 25;
101 const Property::Index Actor::WORLD_SCALE = 26;
102 const Property::Index Actor::VISIBLE = 27;
103 const Property::Index Actor::COLOR = 28;
104 const Property::Index Actor::COLOR_RED = 29;
105 const Property::Index Actor::COLOR_GREEN = 30;
106 const Property::Index Actor::COLOR_BLUE = 31;
107 const Property::Index Actor::COLOR_ALPHA = 32;
108 const Property::Index Actor::WORLD_COLOR = 33;
109 const Property::Index Actor::WORLD_MATRIX = 34;
110 const Property::Index Actor::NAME = 35;
111 const Property::Index Actor::SENSITIVE = 36;
112 const Property::Index Actor::LEAVE_REQUIRED = 37;
113 const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
114 const Property::Index Actor::INHERIT_ROTATION = 39;
115 const Property::Index Actor::INHERIT_SCALE = 40;
116 const Property::Index Actor::COLOR_MODE = 41;
117 const Property::Index Actor::POSITION_INHERITANCE = 42;
118 const Property::Index Actor::DRAW_MODE = 43;
120 namespace // unnamed namespace
124 * We want to discourage the use of property strings (minimize string comparisons),
125 * particularly for the default properties.
127 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
129 // Name Type writable animatable constraint-input
130 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
131 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
132 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
133 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
134 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
135 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
136 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
137 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
138 { "size", Property::VECTOR3, true, true, true }, // SIZE
139 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
140 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
141 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
142 { "position", Property::VECTOR3, true, true, true }, // POSITION
143 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
144 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
145 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
146 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
147 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
148 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
149 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
150 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
151 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
152 { "scale", Property::VECTOR3, true, true, true }, // SCALE
153 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
154 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
155 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
156 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
157 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
158 { "color", Property::VECTOR4, true, true, true }, // COLOR
159 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
160 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
161 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
162 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
163 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
164 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
165 { "name", Property::STRING, true, false, false }, // NAME
166 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
167 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
168 { "inherit-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
169 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
170 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
171 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
172 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
173 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
175 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
177 } // unnamed namespace
182 unsigned int Actor::mActorCounter = 0;
183 ActorContainer Actor::mNullChildren;
185 // Encapsulate actor related gesture information
192 : gesturesRequired( Gesture::Type( 0 ) ),
193 panDetectors( NULL ),
194 pinchDetectors( NULL ),
195 longPressDetectors( NULL ),
206 delete pinchDetectors;
207 delete longPressDetectors;
212 * Checks if the containers in GestureData are empty
216 return !panDetectors &&
218 !longPressDetectors &&
223 * Template to add a detector to the appropriate container. Dynamically allocates the container
224 * only if it is used.
226 template< typename DetectorType, typename ContainerType >
227 void AddDetector( ContainerType*& containerPtr, GestureDetector* detector )
229 if ( NULL == containerPtr )
231 containerPtr = new ContainerType;
234 containerPtr->push_back( static_cast< DetectorType* >( detector ) );
235 gesturesRequired = Gesture::Type( gesturesRequired | detector->GetType() );
239 * Template to remove a detector from the appropriate container. Deletes the container if it is
240 * no longer required.
242 template< typename ContainerType >
243 void RemoveDetector( ContainerType*& containerPtr, GestureDetector* detector )
245 if ( NULL != containerPtr )
247 ContainerType& container( *containerPtr );
248 typename ContainerType::iterator match( std::remove( container.begin(), container.end(), detector ) );
249 DALI_ASSERT_DEBUG( match != container.end() && "Actor does not have the detector" );
250 container.erase( match, container.end() );
252 if ( container.empty() )
254 gesturesRequired = Gesture::Type( gesturesRequired & ~detector->GetType() );
261 Gesture::Type gesturesRequired;
263 PanGestureDetectorContainer* panDetectors;
264 PinchGestureDetectorContainer* pinchDetectors;
265 LongPressGestureDetectorContainer* longPressDetectors;
266 TapGestureDetectorContainer* tapDetectors;
269 #ifdef DYNAMICS_SUPPORT
271 // Encapsulate actor related dynamics data
274 DynamicsData( Actor* slotOwner )
275 : slotDelegate( slotOwner )
279 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
280 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
282 DynamicsBodyPtr body;
283 JointContainer joints;
284 ReferencedJointContainer referencedJoints;
286 SlotDelegate< Actor > slotDelegate;
289 #endif // DYNAMICS_SUPPORT
294 using namespace Dali;
296 BaseHandle CreateActor()
298 return Dali::Actor::New();
301 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
303 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
304 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
305 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
306 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
308 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
309 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
313 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
315 ActorPtr Actor::New()
317 ActorPtr actor( new Actor( BASIC ) );
319 // Second-phase construction
325 const std::string& Actor::GetName() const
330 void Actor::SetName(const std::string& name)
336 // ATTENTION: string for debug purposes is not thread safe.
337 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
341 unsigned int Actor::GetId() const
346 void Actor::Attach( ActorAttachment& attachment )
348 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
352 attachment.Connect();
355 mAttachment = ActorAttachmentPtr(&attachment);
358 ActorAttachmentPtr Actor::GetAttachment()
363 bool Actor::OnStage() const
368 Dali::Layer Actor::GetLayer()
372 // Short-circuit for Layer derived actors
375 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
378 // Find the immediate Layer parent
379 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
381 if( parent->IsLayer() )
383 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
390 void Actor::Add(Actor& child)
392 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
393 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
397 mChildren = new ActorContainer;
400 Actor* const oldParent( child.mParent );
402 // child might already be ours
403 if( this != oldParent )
405 // if we already have parent, unparent us first
408 oldParent->Remove( child ); // This causes OnChildRemove callback
411 // Guard against Add() during previous OnChildRemove callback
412 if ( !child.mParent )
414 // Do this first, since user callbacks from within SetParent() may need to remove child
415 mChildren->push_back(Dali::Actor(&child));
417 // SetParent asserts that child can be added
418 child.SetParent(this);
420 // Notification for derived classes
426 void Actor::Remove(Actor& child)
428 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
438 // Find the child in mChildren, and unparent it
439 ActorIter end = mChildren->end();
440 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
442 Actor& actor = GetImplementation(*iter);
444 if( &actor == &child )
446 // Keep handle for OnChildRemove notification
447 removed = Dali::Actor( &actor );
449 // Do this first, since user callbacks from within SetParent() may need to add the child
450 mChildren->erase(iter);
452 DALI_ASSERT_DEBUG( actor.GetParent() == this );
453 actor.SetParent( NULL );
461 // Notification for derived classes
462 OnChildRemove( GetImplementation(removed) );
466 void Actor::Unparent()
470 mParent->Remove( *this );
474 unsigned int Actor::GetChildCount() const
476 return ( NULL != mChildren ) ? mChildren->size() : 0;
479 Dali::Actor Actor::GetChildAt(unsigned int index) const
481 DALI_ASSERT_ALWAYS( index < GetChildCount() );
483 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
486 ActorContainer Actor::GetChildren()
488 if( NULL != mChildren )
493 // return copy of mNullChildren
494 return mNullChildren;
497 const ActorContainer& Actor::GetChildren() const
499 if( NULL != mChildren )
504 // return const reference to mNullChildren
505 return mNullChildren;
508 ActorPtr Actor::FindChildByName(const std::string& actorName)
511 if (actorName == mName)
517 ActorIter end = mChildren->end();
518 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
520 child = GetImplementation(*iter).FindChildByName(actorName);
531 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
533 Dali::Actor child = DoGetChildByAlias(actorAlias);
535 // If not found then search by name.
538 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
541 child = Dali::Actor(child_ptr.Get());
548 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
550 Dali::Actor child = GetChildByAlias(actorAlias);
552 if (!child && mChildren )
554 ActorIter end = mChildren->end();
555 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
557 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
569 ActorPtr Actor::FindChildById(const unsigned int id)
578 ActorIter end = mChildren->end();
579 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
581 child = GetImplementation(*iter).FindChildById(id);
592 void Actor::SetParentOrigin( const Vector3& origin )
596 // mNode is being used in a separate thread; queue a message to set the value & base value
597 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
600 // Cache for event-thread access
603 // not allocated, check if different from default
604 if( ParentOrigin::DEFAULT != origin )
606 mParentOrigin = new Vector3( origin );
611 // check if different from current costs more than just set
612 *mParentOrigin = origin;
616 void Actor::SetParentOriginX( float x )
618 const Vector3& current = GetCurrentParentOrigin();
620 SetParentOrigin( Vector3( x, current.y, current.z ) );
623 void Actor::SetParentOriginY( float y )
625 const Vector3& current = GetCurrentParentOrigin();
627 SetParentOrigin( Vector3( current.x, y, current.z ) );
630 void Actor::SetParentOriginZ( float z )
632 const Vector3& current = GetCurrentParentOrigin();
634 SetParentOrigin( Vector3( current.x, current.y, z ) );
637 const Vector3& Actor::GetCurrentParentOrigin() const
639 // Cached for event-thread access
640 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
643 void Actor::SetAnchorPoint(const Vector3& anchor)
647 // mNode is being used in a separate thread; queue a message to set the value & base value
648 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
651 // Cache for event-thread access
654 // not allocated, check if different from default
655 if( AnchorPoint::DEFAULT != anchor )
657 mAnchorPoint = new Vector3( anchor );
662 // check if different from current costs more than just set
663 *mAnchorPoint = anchor;
667 void Actor::SetAnchorPointX( float x )
669 const Vector3& current = GetCurrentAnchorPoint();
671 SetAnchorPoint( Vector3( x, current.y, current.z ) );
674 void Actor::SetAnchorPointY( float y )
676 const Vector3& current = GetCurrentAnchorPoint();
678 SetAnchorPoint( Vector3( current.x, y, current.z ) );
681 void Actor::SetAnchorPointZ( float z )
683 const Vector3& current = GetCurrentAnchorPoint();
685 SetAnchorPoint( Vector3( current.x, current.y, z ) );
688 const Vector3& Actor::GetCurrentAnchorPoint() const
690 // Cached for event-thread access
691 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
694 void Actor::SetPosition(float x, float y)
696 SetPosition(Vector3(x, y, 0.0f));
699 void Actor::SetPosition(float x, float y, float z)
701 SetPosition(Vector3(x, y, z));
704 void Actor::SetPosition(const Vector3& position)
708 // mNode is being used in a separate thread; queue a message to set the value & base value
709 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
713 void Actor::SetX(float x)
717 // mNode is being used in a separate thread; queue a message to set the value & base value
718 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
722 void Actor::SetY(float y)
726 // mNode is being used in a separate thread; queue a message to set the value & base value
727 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
731 void Actor::SetZ(float z)
735 // mNode is being used in a separate thread; queue a message to set the value & base value
736 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
740 void Actor::MoveBy(const Vector3& distance)
744 // mNode is being used in a separate thread; queue a message to set the value & base value
745 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
749 const Vector3& Actor::GetCurrentPosition() const
753 // mNode is being used in a separate thread; copy the value from the previous update
754 return mNode->GetPosition(mStage->GetEventBufferIndex());
757 return Vector3::ZERO;
760 const Vector3& Actor::GetCurrentWorldPosition() const
764 // mNode is being used in a separate thread; copy the value from the previous update
765 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
768 return Vector3::ZERO;
771 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
773 // this flag is not animatable so keep the value
774 mPositionInheritanceMode = mode;
777 // mNode is being used in a separate thread; queue a message to set the value
778 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
782 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
784 // Cached for event-thread access
785 return mPositionInheritanceMode;
788 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
790 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
791 normalizedAxis.Normalize();
793 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
795 SetRotation(rotation);
798 void Actor::SetRotation(const Quaternion& rotation)
802 // mNode is being used in a separate thread; queue a message to set the value & base value
803 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
807 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
811 // mNode is being used in a separate thread; queue a message to set the value & base value
812 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
816 void Actor::RotateBy(const Quaternion& relativeRotation)
820 // mNode is being used in a separate thread; queue a message to set the value & base value
821 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
825 const Quaternion& Actor::GetCurrentRotation() const
829 // mNode is being used in a separate thread; copy the value from the previous update
830 return mNode->GetRotation(mStage->GetEventBufferIndex());
833 return Quaternion::IDENTITY;
836 const Quaternion& Actor::GetCurrentWorldRotation() const
840 // mNode is being used in a separate thread; copy the value from the previous update
841 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
844 return Quaternion::IDENTITY;
847 void Actor::SetScale(float scale)
849 SetScale(Vector3(scale, scale, scale));
852 void Actor::SetScale(float x, float y, float z)
854 SetScale(Vector3(x, y, z));
857 void Actor::SetScale(const Vector3& scale)
861 // mNode is being used in a separate thread; queue a message to set the value & base value
862 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
866 void Actor::SetScaleX( float x )
870 // mNode is being used in a separate thread; queue a message to set the value & base value
871 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
875 void Actor::SetScaleY( float y )
879 // mNode is being used in a separate thread; queue a message to set the value & base value
880 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
884 void Actor::SetScaleZ( float z )
888 // mNode is being used in a separate thread; queue a message to set the value & base value
889 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
893 void Actor::SetInitialVolume(const Vector3& volume)
897 // mNode is being used in a separate thread; queue a message to set the value
898 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
902 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
906 // mNode is being used in a separate thread; queue a message to set the value
907 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
911 bool Actor::GetTransmitGeometryScaling() const
915 // mNode is being used in a separate thread; copy the value from the previous update
916 return mNode->GetTransmitGeometryScaling();
922 void Actor::ScaleBy(const Vector3& relativeScale)
926 // mNode is being used in a separate thread; queue a message to set the value & base value
927 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
931 const Vector3& Actor::GetCurrentScale() const
935 // mNode is being used in a separate thread; copy the value from the previous update
936 return mNode->GetScale(mStage->GetEventBufferIndex());
942 const Vector3& Actor::GetCurrentWorldScale() const
946 // mNode is being used in a separate thread; copy the value from the previous update
947 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
953 void Actor::SetInheritScale( bool inherit )
955 // non animateable so keep local copy
956 mInheritScale = inherit;
959 // mNode is being used in a separate thread; queue a message to set the value
960 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
964 bool Actor::IsScaleInherited() const
966 return mInheritScale;
969 Matrix Actor::GetCurrentWorldMatrix() const
973 // World matrix is no longer updated unless there is something observing the node.
974 // Need to calculate it from node's world position, rotation and scale:
975 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
976 Matrix worldMatrix(false);
977 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
978 mNode->GetWorldRotation( updateBufferIndex ),
979 mNode->GetWorldPosition( updateBufferIndex ) );
983 return Matrix::IDENTITY;
986 void Actor::SetVisible(bool visible)
990 // mNode is being used in a separate thread; queue a message to set the value & base value
991 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
995 bool Actor::IsVisible() const
999 // mNode is being used in a separate thread; copy the value from the previous update
1000 return mNode->IsVisible( mStage->GetEventBufferIndex() );
1006 void Actor::SetOpacity(float opacity)
1010 // mNode is being used in a separate thread; queue a message to set the value & base value
1011 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
1015 void Actor::OpacityBy(float relativeOpacity)
1019 // mNode is being used in a separate thread; queue a message to set the value & base value
1020 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
1024 float Actor::GetCurrentOpacity() const
1028 // mNode is being used in a separate thread; copy the value from the previous update
1029 return mNode->GetOpacity(mStage->GetEventBufferIndex());
1035 const Vector4& Actor::GetCurrentWorldColor() const
1039 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
1042 return Color::WHITE;
1045 void Actor::SetColor(const Vector4& color)
1049 // mNode is being used in a separate thread; queue a message to set the value & base value
1050 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1054 void Actor::SetColorRed( float red )
1058 // mNode is being used in a separate thread; queue a message to set the value & base value
1059 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1063 void Actor::SetColorGreen( float green )
1067 // mNode is being used in a separate thread; queue a message to set the value & base value
1068 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1072 void Actor::SetColorBlue( float blue )
1076 // mNode is being used in a separate thread; queue a message to set the value & base value
1077 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1081 void Actor::ColorBy(const Vector4& relativeColor)
1085 // mNode is being used in a separate thread; queue a message to set the value & base value
1086 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1090 const Vector4& Actor::GetCurrentColor() const
1094 // mNode is being used in a separate thread; copy the value from the previous update
1095 return mNode->GetColor(mStage->GetEventBufferIndex());
1098 return Color::WHITE;
1101 void Actor::SetInheritRotation(bool inherit)
1103 // non animateable so keep local copy
1104 mInheritRotation = inherit;
1107 // mNode is being used in a separate thread; queue a message to set the value
1108 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1112 bool Actor::IsRotationInherited() const
1114 return mInheritRotation;
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 Vector3 volume( size );
1147 volume.z = std::min( size.width, size.height );
1151 void Actor::SetSize(const Vector3& size)
1155 // mNode is being used in a separate thread; queue a message to set the value & base value
1156 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1158 // Notification for derived classes
1161 // Emit signal for application developer
1163 if( !mSetSizeSignalV2.Empty() )
1165 Dali::Actor handle( this );
1166 mSetSizeSignalV2.Emit( handle, size );
1171 void Actor::SetWidth( float width )
1175 // mNode is being used in a separate thread; queue a message to set the value & base value
1176 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1180 void Actor::SetHeight( float height )
1184 // mNode is being used in a separate thread; queue a message to set the value & base value
1185 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1189 void Actor::SetDepth( float depth )
1193 // mNode is being used in a separate thread; queue a message to set the value & base value
1194 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1198 const Vector3& Actor::GetCurrentSize() const
1202 // mNode is being used in a separate thread; copy the value from the previous update
1203 return mNode->GetSize( mStage->GetEventBufferIndex() );
1206 return Vector3::ZERO;
1209 void Actor::SetInheritShaderEffect(bool inherit)
1213 // mNode is being used in a separate thread; queue a message to set the value
1214 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1218 bool Actor::GetInheritShaderEffect() const
1222 // mNode is being used in a separate thread; copy the value from the previous update
1223 return mNode->GetInheritShader();
1229 void Actor::SetShaderEffect(ShaderEffect& effect)
1235 mShaderEffect->Disconnect();
1238 mShaderEffect = ShaderEffectPtr(&effect);
1240 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1244 // mNode is being used in a separate thread; queue a message to apply shader
1245 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1248 mShaderEffect->Connect();
1252 mShaderEffect = ShaderEffectPtr(&effect);
1254 // Effects can only be applied when the Node is connected to scene-graph
1257 ShaderEffectPtr Actor::GetShaderEffect() const
1259 return mShaderEffect;
1262 void Actor::RemoveShaderEffect()
1268 // mNode is being used in a separate thread; queue a message to remove shader
1269 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1272 // Notify shader effect
1275 mShaderEffect->Disconnect();
1279 mShaderEffect.Reset();
1282 #ifdef DYNAMICS_SUPPORT
1284 //--------------- Dynamics ---------------
1286 void Actor::DisableDynamics()
1288 if( NULL != mDynamicsData )
1290 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1292 // ensure dynamics object are disconnected from scene
1293 DisconnectDynamics();
1295 // delete joint owned by this actor
1296 while( !mDynamicsData->joints.empty() )
1298 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1301 // delete other joints referencing this actor
1302 while( !mDynamicsData->referencedJoints.empty() )
1304 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1305 ActorPtr jointOwner( joint->GetActor( true ) );
1308 jointOwner->RemoveDynamicsJoint( joint );
1312 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1315 // delete the DynamicsBody object
1316 mDynamicsData->body.Reset();
1318 // Discard Dynamics data structure
1319 delete mDynamicsData;
1320 mDynamicsData = NULL;
1324 DynamicsBodyPtr Actor::GetDynamicsBody() const
1326 DynamicsBodyPtr body;
1328 if( NULL != mDynamicsData )
1330 body = mDynamicsData->body;
1336 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1338 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1340 if( NULL == mDynamicsData )
1342 mDynamicsData = new DynamicsData( this );
1345 if( !mDynamicsData->body )
1347 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1351 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1354 if( mParent == world->GetRootActor().Get() )
1356 mDynamicsData->body->Connect(*mStage);
1362 return mDynamicsData->body;
1365 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1367 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1368 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1371 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1373 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1374 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1376 DynamicsJointPtr joint;
1378 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1382 if( NULL != mDynamicsData )
1384 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1386 if( mDynamicsData->joints.end() != it )
1388 // use existing joint
1394 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1395 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1399 bodyA = EnableDynamics( new DynamicsBodyConfig );
1404 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1407 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1408 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1410 if( OnStage() && attachedActor->OnStage() )
1412 joint->Connect(*mStage);
1415 attachedActor->ReferenceJoint( joint );
1417 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1418 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1425 const int Actor::GetNumberOfJoints() const
1427 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1430 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1432 DynamicsJointPtr joint;
1434 if( NULL != mDynamicsData )
1436 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1438 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1440 for( int i = 0; i < index; ++i )
1452 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1454 DynamicsJointPtr joint;
1456 if( NULL != mDynamicsData )
1458 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1460 if( mDynamicsData->joints.end() != it )
1462 // use existing joint
1470 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1472 if( NULL != mDynamicsData )
1474 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1475 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1477 for( ; it != endIt; ++it )
1479 if( it->second == joint.Get() )
1481 ActorPtr attachedActor( it->first );
1483 if( OnStage() && attachedActor && attachedActor->OnStage() )
1485 joint->Disconnect(*mStage);
1490 attachedActor->ReleaseJoint( joint );
1491 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1492 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1495 mDynamicsData->joints.erase(it);
1502 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1504 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1506 if( NULL != mDynamicsData )
1508 mDynamicsData->referencedJoints.push_back(joint);
1512 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1514 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1516 if( NULL != mDynamicsData )
1518 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1520 if( it != mDynamicsData->referencedJoints.end() )
1522 mDynamicsData->referencedJoints.erase( it );
1527 void Actor::SetDynamicsRoot(bool flag)
1529 if( mIsDynamicsRoot != flag )
1531 mIsDynamicsRoot = flag;
1533 if( OnStage() && mChildren )
1535 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1536 ActorIter end = mChildren->end();
1537 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1539 Actor& child = GetImplementation(*iter);
1541 if( child.GetDynamicsBody() )
1543 if( mIsDynamicsRoot )
1545 child.ConnectDynamics();
1549 child.DisconnectDynamics();
1557 bool Actor::IsDynamicsRoot() const
1559 return mIsDynamicsRoot;
1562 void Actor::AttachedActorOnStage( Dali::Actor actor )
1564 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1568 ActorPtr attachedActor( &GetImplementation(actor) );
1570 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1571 if( NULL != mDynamicsData )
1573 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1574 if( mDynamicsData->joints.end() != it )
1576 DynamicsJointPtr joint( it->second );
1577 joint->Connect(*mStage);
1583 void Actor::AttachedActorOffStage( Dali::Actor actor )
1585 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1589 ActorPtr attachedActor( &GetImplementation(actor) );
1591 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1592 if( NULL != mDynamicsData )
1594 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1595 if( mDynamicsData->joints.end() != it )
1597 DynamicsJointPtr joint( it->second );
1598 joint->Disconnect(*mStage);
1604 void Actor::ConnectDynamics()
1606 if( NULL != mDynamicsData && mDynamicsData->body )
1608 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1610 mDynamicsData->body->Connect(*mStage);
1612 // Connect all joints where attachedActor is also on stage
1613 if( !mDynamicsData->joints.empty() )
1615 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1616 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1618 for( ; it != endIt; ++it )
1620 Actor* attachedActor( it->first );
1621 if( NULL != attachedActor && attachedActor->OnStage() )
1623 DynamicsJointPtr joint( it->second );
1625 joint->Connect(*mStage);
1633 void Actor::DisconnectDynamics()
1635 if( NULL != mDynamicsData && mDynamicsData->body )
1639 mDynamicsData->body->Disconnect(*mStage);
1641 // Disconnect all joints
1642 if( !mDynamicsData->joints.empty() )
1644 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1645 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1647 for( ; it != endIt; ++it )
1649 DynamicsJointPtr joint( it->second );
1651 joint->Disconnect(*mStage);
1658 #endif // DYNAMICS_SUPPORT
1660 void Actor::SetOverlay(bool enable)
1662 // Setting STENCIL will override OVERLAY
1663 if( DrawMode::STENCIL != mDrawMode )
1665 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1669 bool Actor::IsOverlay() const
1671 return ( DrawMode::OVERLAY == mDrawMode );
1674 void Actor::SetDrawMode( DrawMode::Type drawMode )
1676 // this flag is not animatable so keep the value
1677 mDrawMode = drawMode;
1680 // mNode is being used in a separate thread; queue a message to set the value
1681 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1685 DrawMode::Type Actor::GetDrawMode() const
1690 bool Actor::ScreenToLocal( float& localX,
1693 float screenY ) const
1695 // only valid when on-stage
1698 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1700 Vector2 converted( screenX, screenY );
1702 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1703 const int taskCount = taskList.GetTaskCount();
1704 for( int i = taskCount - 1; i >= 0; --i )
1706 Dali::RenderTask task = taskList.GetTask( i );
1707 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1709 // found a task where this conversion was ok so return
1717 bool Actor::ScreenToLocal( RenderTask& renderTask,
1721 float screenY ) const
1723 bool retval = false;
1724 // only valid when on-stage
1727 CameraActor* camera = renderTask.GetCameraActor();
1731 renderTask.GetViewport( viewport );
1733 // need to translate coordinates to render tasks coordinate space
1734 Vector2 converted( screenX, screenY );
1735 if( renderTask.TranslateCoordinates( converted ) )
1737 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1744 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1745 const Matrix& projectionMatrix,
1746 const Viewport& viewport,
1750 float screenY ) const
1752 // Early-out if mNode is NULL
1758 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1760 // Calculate the ModelView matrix
1761 Matrix modelView(false/*don't init*/);
1762 // need to use the components as world matrix is only updated for actors that need it
1763 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1764 Matrix::Multiply(modelView, modelView, viewMatrix);
1766 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1767 Matrix invertedMvp(false/*don't init*/);
1768 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1769 bool success = invertedMvp.Invert();
1771 // Convert to GL coordinates
1772 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1777 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1784 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1790 if (XyPlaneIntersect(nearPos, farPos, local))
1792 Vector3 size = GetCurrentSize();
1793 localX = local.x + size.x * 0.5f;
1794 localY = local.y + size.y * 0.5f;
1805 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1808 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1810 Mathematical Formulation
1812 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1814 ( p - c ) dot ( p - c ) = r^2
1816 Given a ray with a point of origin 'o', and a direction vector 'd':
1818 ray(t) = o + td, t >= 0
1820 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1822 (o + td - c ) dot ( o + td - c ) = r^2
1824 To solve for t we first expand the above into a more recognisable quadratic equation form
1826 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1835 B = 2( o - c ) dot d
1836 C = ( o - c ) dot ( o - c ) - r^2
1838 which can be solved using a standard quadratic formula.
1840 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1842 Practical Simplification
1844 In a renderer, we often differentiate between world space and object space. In the object space
1845 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1846 into object space, the mathematical solution presented above can be simplified significantly.
1848 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1852 and we can find the t at which the (transformed) ray intersects the sphere by
1854 ( o + td ) dot ( o + td ) = r^2
1856 According to the reasoning above, we expand the above quadratic equation into the general form
1860 which now has coefficients:
1867 // Early out if mNode is NULL
1873 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1875 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1876 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1877 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1878 rayOrigin.y - translation.y,
1879 rayOrigin.z - translation.z);
1881 // Compute the radius is not needed, square radius it's enough.
1882 const Vector3& size( mNode->GetSize( bufferIndex ) );
1884 // Scale the sphere.
1885 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1887 const float width = size.width * scale.width;
1888 const float height = size.height * scale.height;
1890 float squareSphereRadius = 0.5f * ( width * width + height * height );
1892 float a = rayDir.Dot( rayDir ); // a
1893 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1894 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1896 return ( b2*b2 - a*c ) >= 0.f;
1899 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1906 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1908 // Transforms the ray to the local reference system.
1910 // Calculate the inverse of Model matrix
1911 Matrix invModelMatrix(false/*don't init*/);
1912 // need to use the components as world matrix is only updated for actors that need it
1913 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1915 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1916 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1918 // Test with the actor's XY plane (Normal = 0 0 1 1).
1920 float a = -rayOriginLocal.z;
1921 float b = rayDirLocal.z;
1923 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1925 // Ray travels distance * rayDirLocal to intersect with plane.
1928 const Vector3& size = mNode->GetSize( bufferIndex );
1930 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1931 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1933 // Test with the actor's geometry.
1934 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1941 void Actor::SetLeaveRequired(bool required)
1943 mLeaveRequired = required;
1946 bool Actor::GetLeaveRequired() const
1948 return mLeaveRequired;
1951 void Actor::SetKeyboardFocusable( bool focusable )
1953 mKeyboardFocusable = focusable;
1956 bool Actor::IsKeyboardFocusable() const
1958 return mKeyboardFocusable;
1961 bool Actor::GetTouchRequired() const
1963 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1966 bool Actor::GetMouseWheelEventRequired() const
1968 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1971 bool Actor::IsHittable() const
1973 return IsSensitive() &&
1975 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1979 void Actor::AddGestureDetector( GestureDetector& detector )
1981 if ( NULL == mGestureData )
1983 mGestureData = new GestureData;
1986 const Gesture::Type type( detector.GetType() );
1991 mGestureData->AddDetector< PanGestureDetector, PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
1995 case Gesture::Pinch:
1997 mGestureData->AddDetector< PinchGestureDetector, PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
2001 case Gesture::LongPress:
2003 mGestureData->AddDetector< LongPressGestureDetector, LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
2009 mGestureData->AddDetector< TapGestureDetector, TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
2015 void Actor::RemoveGestureDetector( GestureDetector& detector )
2017 if ( NULL != mGestureData )
2019 switch ( detector.GetType() )
2023 mGestureData->RemoveDetector< PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
2027 case Gesture::Pinch:
2029 mGestureData->RemoveDetector< PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
2033 case Gesture::LongPress:
2035 mGestureData->RemoveDetector< LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
2041 mGestureData->RemoveDetector< TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
2046 if ( mGestureData->Empty() )
2048 delete mGestureData;
2049 mGestureData = NULL;
2054 bool Actor::IsGestureRequred( Gesture::Type type ) const
2056 bool required( false );
2057 if ( NULL != mGestureData )
2059 required = type & mGestureData->gesturesRequired;
2064 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
2066 bool consumed = false;
2068 if ( !mTouchedSignalV2.Empty() )
2070 Dali::Actor handle( this );
2071 consumed = mTouchedSignalV2.Emit( handle, event );
2076 // Notification for derived classes
2077 consumed = OnTouchEvent( event );
2083 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
2085 bool consumed = false;
2087 if ( !mMouseWheelEventSignalV2.Empty() )
2089 Dali::Actor handle( this );
2090 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
2095 // Notification for derived classes
2096 consumed = OnMouseWheelEvent(event);
2102 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
2104 return mTouchedSignalV2;
2107 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
2109 return mMouseWheelEventSignalV2;
2112 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
2114 return mSetSizeSignalV2;
2117 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
2119 return mOnStageSignalV2;
2122 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
2124 return mOffStageSignalV2;
2127 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
2129 bool connected( true );
2130 Actor* actor = dynamic_cast<Actor*>(object);
2132 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
2134 actor->TouchedSignal().Connect( tracker, functor );
2136 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
2138 actor->MouseWheelEventSignal().Connect( tracker, functor );
2140 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
2142 actor->SetSizeSignal().Connect( tracker, functor );
2144 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
2146 actor->OnStageSignal().Connect( tracker, functor );
2148 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
2150 actor->OffStageSignal().Connect( tracker, functor );
2154 // signalName does not match any signal
2161 Actor::Actor( DerivedType derivedType )
2166 mParentOrigin( NULL ),
2167 mAnchorPoint( NULL ),
2168 #ifdef DYNAMICS_SUPPORT
2169 mDynamicsData( NULL ),
2171 mGestureData( NULL ),
2175 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2176 mIsRoot( ROOT_LAYER == derivedType ),
2177 mIsRenderable( RENDERABLE == derivedType ),
2178 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2179 mIsOnStage( false ),
2180 mIsDynamicsRoot(false),
2182 mLeaveRequired( false ),
2183 mKeyboardFocusable( false ),
2184 mDerivedRequiresTouch( false ),
2185 mDerivedRequiresMouseWheelEvent( false ),
2186 mOnStageSignalled( false ),
2187 mInheritRotation( true ),
2188 mInheritScale( true ),
2189 mDrawMode( DrawMode::NORMAL ),
2190 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2191 mColorMode( Node::DEFAULT_COLOR_MODE )
2195 void Actor::Initialize()
2197 mStage = Stage::GetCurrent();
2200 SceneGraph::Node* node = CreateNode();
2202 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2203 mNode = node; // Keep raw-pointer to Node
2205 if(!mDefaultPropertyLookup)
2207 mDefaultPropertyLookup = new DefaultPropertyLookup();
2209 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2211 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2222 // Remove mParent pointers from children even if we're destroying core,
2223 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2226 ActorConstIter endIter = mChildren->end();
2227 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2229 Actor& actor = GetImplementation( *iter );
2230 actor.SetParent( NULL );
2235 // Guard to allow handle destruction after Core has been destroyed
2236 if( Stage::IsInstalled() )
2240 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2241 mNode = NULL; // Node is about to be destroyed
2247 #ifdef DYNAMICS_SUPPORT
2249 delete mDynamicsData;
2252 // Cleanup optional gesture data
2253 delete mGestureData;
2255 // Cleanup optional parent origin and anchor
2256 delete mParentOrigin;
2257 delete mAnchorPoint;
2260 void Actor::ConnectToStage( Stage& stage )
2262 // This container is used instead of walking the Actor hierachy.
2263 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2264 ActorContainer connectionList;
2266 // This stage is atomic i.e. not interrupted by user callbacks
2267 RecursiveConnectToStage( stage, connectionList );
2269 // Notify applications about the newly connected actors.
2270 const ActorIter endIter = connectionList.end();
2271 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2273 Actor& actor = GetImplementation(*iter);
2274 actor.NotifyStageConnection();
2278 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2280 DALI_ASSERT_ALWAYS( !OnStage() );
2284 ConnectToSceneGraph();
2286 // Notification for internal derived classes
2287 OnStageConnectionInternal();
2289 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2290 connectionList.push_back( Dali::Actor(this) );
2292 // Recursively connect children
2295 ActorConstIter endIter = mChildren->end();
2296 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2298 Actor& actor = GetImplementation( *iter );
2299 actor.RecursiveConnectToStage( stage, connectionList );
2305 * This method is called when the Actor is connected to the Stage.
2306 * The parent must have added its Node to the scene-graph.
2307 * The child must connect its Node to the parent's Node.
2308 * This is resursive; the child calls ConnectToStage() for its children.
2310 void Actor::ConnectToSceneGraph()
2312 DALI_ASSERT_DEBUG( mNode != NULL);
2313 DALI_ASSERT_DEBUG( mParent != NULL);
2314 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2318 // Reparent Node in next Update
2319 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2324 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2328 // Effects can only be applied when the node is on-stage
2329 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2332 // Notify shader effect
2333 mShaderEffect->Connect();
2336 // Notify attachment
2339 mAttachment->Connect();
2342 #ifdef DYNAMICS_SUPPORT
2344 if( NULL != mDynamicsData )
2350 // Notification for ProxyObject::Observers
2354 void Actor::NotifyStageConnection()
2356 // Actors can be removed (in a callback), before the on-stage stage is reported.
2357 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2358 if ( OnStage() && !mOnStageSignalled )
2360 // Notification for external (CustomActor) derived classes
2361 OnStageConnectionExternal();
2363 if ( !mOnStageSignalV2.Empty() )
2365 Dali::Actor handle( this );
2366 mOnStageSignalV2.Emit( handle );
2369 // Guard against Remove during callbacks
2372 mOnStageSignalled = true; // signal required next time Actor is removed
2377 void Actor::DisconnectFromStage()
2379 // This container is used instead of walking the Actor hierachy.
2380 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2381 ActorContainer disconnectionList;
2383 // This stage is atomic i.e. not interrupted by user callbacks
2384 RecursiveDisconnectFromStage( disconnectionList );
2386 // Notify applications about the newly disconnected actors.
2387 const ActorIter endIter = disconnectionList.end();
2388 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2390 Actor& actor = GetImplementation(*iter);
2391 actor.NotifyStageDisconnection();
2395 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2397 DALI_ASSERT_ALWAYS( OnStage() );
2399 // Recursively disconnect children
2402 ActorConstIter endIter = mChildren->end();
2403 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2405 Actor& actor = GetImplementation( *iter );
2406 actor.RecursiveDisconnectFromStage( disconnectionList );
2410 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2411 disconnectionList.push_back( Dali::Actor(this) );
2413 // Notification for internal derived classes
2414 OnStageDisconnectionInternal();
2416 DisconnectFromSceneGraph();
2422 * This method is called by an actor or its parent, before a node removal message is sent.
2423 * This is recursive; the child calls DisconnectFromStage() for its children.
2425 void Actor::DisconnectFromSceneGraph()
2427 // Notification for ProxyObject::Observers
2428 OnSceneObjectRemove();
2430 // Notify shader effect
2433 mShaderEffect->Disconnect();
2436 // Notify attachment
2439 mAttachment->Disconnect();
2442 #ifdef DYNAMICS_SUPPORT
2444 if( NULL != mDynamicsData )
2446 DisconnectDynamics();
2451 void Actor::NotifyStageDisconnection()
2453 // Actors can be added (in a callback), before the off-stage state is reported.
2454 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2455 // only do this step if there is a stage, i.e. Core is not being shut down
2456 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2458 // Notification for external (CustomeActor) derived classes
2459 OnStageDisconnectionExternal();
2461 if( !mOffStageSignalV2.Empty() )
2463 Dali::Actor handle( this );
2464 mOffStageSignalV2.Emit( handle );
2467 // Guard against Add during callbacks
2470 mOnStageSignalled = false; // signal required next time Actor is added
2475 bool Actor::IsNodeConnected() const
2477 bool connected( false );
2482 if( mNode->IsRoot() || mNode->GetParent() )
2491 bool Actor::IsSceneObjectRemovable() const
2496 unsigned int Actor::GetDefaultPropertyCount() const
2498 return DEFAULT_PROPERTY_COUNT;
2501 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2503 indices.reserve( DEFAULT_PROPERTY_COUNT );
2505 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2507 indices.push_back( i );
2511 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2513 if( index < DEFAULT_PROPERTY_COUNT )
2515 return DEFAULT_PROPERTY_DETAILS[index].name;
2519 // index out of range..return empty string
2520 return String::EMPTY;
2524 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2526 Property::Index index = Property::INVALID_INDEX;
2528 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2530 // Look for name in default properties
2531 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2532 if ( mDefaultPropertyLookup->end() != result )
2534 index = result->second;
2540 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2542 if( index < DEFAULT_PROPERTY_COUNT )
2544 return DEFAULT_PROPERTY_DETAILS[index].writable;
2552 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2554 if( index < DEFAULT_PROPERTY_COUNT )
2556 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2564 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2566 if( index < DEFAULT_PROPERTY_COUNT )
2568 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2576 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2578 if( index < DEFAULT_PROPERTY_COUNT )
2580 return DEFAULT_PROPERTY_DETAILS[index].type;
2584 // index out of range...return Property::NONE
2585 return Property::NONE;
2589 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2593 case Dali::Actor::PARENT_ORIGIN:
2595 SetParentOrigin( property.Get<Vector3>() );
2599 case Dali::Actor::PARENT_ORIGIN_X:
2601 SetParentOriginX( property.Get<float>() );
2605 case Dali::Actor::PARENT_ORIGIN_Y:
2607 SetParentOriginY( property.Get<float>() );
2611 case Dali::Actor::PARENT_ORIGIN_Z:
2613 SetParentOriginZ( property.Get<float>() );
2617 case Dali::Actor::ANCHOR_POINT:
2619 SetAnchorPoint( property.Get<Vector3>() );
2623 case Dali::Actor::ANCHOR_POINT_X:
2625 SetAnchorPointX( property.Get<float>() );
2629 case Dali::Actor::ANCHOR_POINT_Y:
2631 SetAnchorPointY( property.Get<float>() );
2635 case Dali::Actor::ANCHOR_POINT_Z:
2637 SetAnchorPointZ( property.Get<float>() );
2641 case Dali::Actor::SIZE:
2643 SetSize( property.Get<Vector3>() );
2647 case Dali::Actor::SIZE_WIDTH:
2649 SetWidth( property.Get<float>() );
2653 case Dali::Actor::SIZE_HEIGHT:
2655 SetHeight( property.Get<float>() );
2659 case Dali::Actor::SIZE_DEPTH:
2661 SetDepth( property.Get<float>() );
2665 case Dali::Actor::POSITION:
2667 SetPosition( property.Get<Vector3>() );
2671 case Dali::Actor::POSITION_X:
2673 SetX( property.Get<float>() );
2677 case Dali::Actor::POSITION_Y:
2679 SetY( property.Get<float>() );
2683 case Dali::Actor::POSITION_Z:
2685 SetZ( property.Get<float>() );
2689 case Dali::Actor::ROTATION:
2691 SetRotation( property.Get<Quaternion>() );
2695 case Dali::Actor::SCALE:
2697 SetScale( property.Get<Vector3>() );
2701 case Dali::Actor::SCALE_X:
2703 SetScaleX( property.Get<float>() );
2707 case Dali::Actor::SCALE_Y:
2709 SetScaleY( property.Get<float>() );
2713 case Dali::Actor::SCALE_Z:
2715 SetScaleZ( property.Get<float>() );
2719 case Dali::Actor::VISIBLE:
2721 SetVisible( property.Get<bool>() );
2725 case Dali::Actor::COLOR:
2727 SetColor( property.Get<Vector4>() );
2731 case Dali::Actor::COLOR_RED:
2733 SetColorRed( property.Get<float>() );
2737 case Dali::Actor::COLOR_GREEN:
2739 SetColorGreen( property.Get<float>() );
2743 case Dali::Actor::COLOR_BLUE:
2745 SetColorBlue( property.Get<float>() );
2749 case Dali::Actor::COLOR_ALPHA:
2751 SetOpacity( property.Get<float>() );
2755 case Dali::Actor::NAME:
2757 SetName( property.Get<std::string>() );
2761 case Dali::Actor::SENSITIVE:
2763 SetSensitive( property.Get<bool>() );
2767 case Dali::Actor::LEAVE_REQUIRED:
2769 SetLeaveRequired( property.Get<bool>() );
2773 case Dali::Actor::INHERIT_SHADER_EFFECT:
2775 SetInheritShaderEffect( property.Get<bool>() );
2779 case Dali::Actor::INHERIT_ROTATION:
2781 SetInheritRotation( property.Get<bool>() );
2785 case Dali::Actor::INHERIT_SCALE:
2787 SetInheritScale( property.Get<bool>() );
2791 case Dali::Actor::COLOR_MODE:
2793 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2797 case Dali::Actor::POSITION_INHERITANCE:
2799 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2803 case Dali::Actor::DRAW_MODE:
2805 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2811 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2817 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2819 // TODO: This should be deprecated
2820 OnPropertySet(index, value);
2822 if(entry.IsAnimatable())
2824 // TODO: ADD MATRIX & MATRIX3 types
2826 switch ( entry.type )
2828 case Property::BOOLEAN:
2830 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2831 DALI_ASSERT_DEBUG( NULL != property );
2833 // property is being used in a separate thread; queue a message to set the property
2834 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2839 case Property::FLOAT:
2841 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2842 DALI_ASSERT_DEBUG( NULL != property );
2844 // property is being used in a separate thread; queue a message to set the property
2845 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2850 case Property::VECTOR2:
2852 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2853 DALI_ASSERT_DEBUG( NULL != property );
2855 // property is being used in a separate thread; queue a message to set the property
2856 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2861 case Property::VECTOR3:
2863 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2864 DALI_ASSERT_DEBUG( NULL != property );
2866 // property is being used in a separate thread; queue a message to set the property
2867 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2872 case Property::VECTOR4:
2874 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2875 DALI_ASSERT_DEBUG( NULL != property );
2877 // property is being used in a separate thread; queue a message to set the property
2878 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2883 case Property::ROTATION:
2885 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2886 DALI_ASSERT_DEBUG( NULL != property );
2888 // property is being used in a separate thread; queue a message to set the property
2889 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2896 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2903 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2905 Property::Value value;
2909 case Dali::Actor::PARENT_ORIGIN:
2911 value = GetCurrentParentOrigin();
2915 case Dali::Actor::PARENT_ORIGIN_X:
2917 value = GetCurrentParentOrigin().x;
2921 case Dali::Actor::PARENT_ORIGIN_Y:
2923 value = GetCurrentParentOrigin().y;
2927 case Dali::Actor::PARENT_ORIGIN_Z:
2929 value = GetCurrentParentOrigin().z;
2933 case Dali::Actor::ANCHOR_POINT:
2935 value = GetCurrentAnchorPoint();
2939 case Dali::Actor::ANCHOR_POINT_X:
2941 value = GetCurrentAnchorPoint().x;
2945 case Dali::Actor::ANCHOR_POINT_Y:
2947 value = GetCurrentAnchorPoint().y;
2951 case Dali::Actor::ANCHOR_POINT_Z:
2953 value = GetCurrentAnchorPoint().z;
2957 case Dali::Actor::SIZE:
2959 value = GetCurrentSize();
2963 case Dali::Actor::SIZE_WIDTH:
2965 value = GetCurrentSize().width;
2969 case Dali::Actor::SIZE_HEIGHT:
2971 value = GetCurrentSize().height;
2975 case Dali::Actor::SIZE_DEPTH:
2977 value = GetCurrentSize().depth;
2981 case Dali::Actor::POSITION:
2983 value = GetCurrentPosition();
2987 case Dali::Actor::POSITION_X:
2989 value = GetCurrentPosition().x;
2993 case Dali::Actor::POSITION_Y:
2995 value = GetCurrentPosition().y;
2999 case Dali::Actor::POSITION_Z:
3001 value = GetCurrentPosition().z;
3005 case Dali::Actor::WORLD_POSITION:
3007 value = GetCurrentWorldPosition();
3011 case Dali::Actor::WORLD_POSITION_X:
3013 value = GetCurrentWorldPosition().x;
3017 case Dali::Actor::WORLD_POSITION_Y:
3019 value = GetCurrentWorldPosition().y;
3023 case Dali::Actor::WORLD_POSITION_Z:
3025 value = GetCurrentWorldPosition().z;
3029 case Dali::Actor::ROTATION:
3031 value = GetCurrentRotation();
3035 case Dali::Actor::WORLD_ROTATION:
3037 value = GetCurrentWorldRotation();
3041 case Dali::Actor::SCALE:
3043 value = GetCurrentScale();
3047 case Dali::Actor::SCALE_X:
3049 value = GetCurrentScale().x;
3053 case Dali::Actor::SCALE_Y:
3055 value = GetCurrentScale().y;
3059 case Dali::Actor::SCALE_Z:
3061 value = GetCurrentScale().z;
3065 case Dali::Actor::WORLD_SCALE:
3067 value = GetCurrentWorldScale();
3071 case Dali::Actor::VISIBLE:
3073 value = IsVisible();
3077 case Dali::Actor::COLOR:
3079 value = GetCurrentColor();
3083 case Dali::Actor::COLOR_RED:
3085 value = GetCurrentColor().r;
3089 case Dali::Actor::COLOR_GREEN:
3091 value = GetCurrentColor().g;
3095 case Dali::Actor::COLOR_BLUE:
3097 value = GetCurrentColor().b;
3101 case Dali::Actor::COLOR_ALPHA:
3103 value = GetCurrentColor().a;
3107 case Dali::Actor::WORLD_COLOR:
3109 value = GetCurrentWorldColor();
3113 case Dali::Actor::WORLD_MATRIX:
3115 value = GetCurrentWorldMatrix();
3119 case Dali::Actor::NAME:
3125 case Dali::Actor::SENSITIVE:
3127 value = IsSensitive();
3131 case Dali::Actor::LEAVE_REQUIRED:
3133 value = GetLeaveRequired();
3137 case Dali::Actor::INHERIT_SHADER_EFFECT:
3139 value = GetInheritShaderEffect();
3143 case Dali::Actor::INHERIT_ROTATION:
3145 value = IsRotationInherited();
3149 case Dali::Actor::INHERIT_SCALE:
3151 value = IsScaleInherited();
3155 case Dali::Actor::COLOR_MODE:
3157 value = Scripting::GetColorMode( GetColorMode() );
3161 case Dali::Actor::POSITION_INHERITANCE:
3163 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3167 case Dali::Actor::DRAW_MODE:
3169 value = Scripting::GetDrawMode( GetDrawMode() );
3175 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3183 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3187 // mNode is being used in a separate thread; queue a message to add the property
3188 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3192 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3194 // This method should only return an object connected to the scene-graph
3195 return OnStage() ? mNode : NULL;
3198 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3200 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3202 const PropertyBase* property( NULL );
3204 // This method should only return a property of an object connected to the scene-graph
3210 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3212 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3214 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3216 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3218 else if( NULL != mNode )
3222 case Dali::Actor::SIZE:
3223 property = &mNode->mSize;
3226 case Dali::Actor::SIZE_WIDTH:
3227 property = &mNode->mSize;
3230 case Dali::Actor::SIZE_HEIGHT:
3231 property = &mNode->mSize;
3234 case Dali::Actor::SIZE_DEPTH:
3235 property = &mNode->mSize;
3238 case Dali::Actor::POSITION:
3239 property = &mNode->mPosition;
3242 case Dali::Actor::POSITION_X:
3243 property = &mNode->mPosition;
3246 case Dali::Actor::POSITION_Y:
3247 property = &mNode->mPosition;
3250 case Dali::Actor::POSITION_Z:
3251 property = &mNode->mPosition;
3254 case Dali::Actor::ROTATION:
3255 property = &mNode->mRotation;
3258 case Dali::Actor::SCALE:
3259 property = &mNode->mScale;
3262 case Dali::Actor::SCALE_X:
3263 property = &mNode->mScale;
3266 case Dali::Actor::SCALE_Y:
3267 property = &mNode->mScale;
3270 case Dali::Actor::SCALE_Z:
3271 property = &mNode->mScale;
3274 case Dali::Actor::VISIBLE:
3275 property = &mNode->mVisible;
3278 case Dali::Actor::COLOR:
3279 property = &mNode->mColor;
3282 case Dali::Actor::COLOR_RED:
3283 property = &mNode->mColor;
3286 case Dali::Actor::COLOR_GREEN:
3287 property = &mNode->mColor;
3290 case Dali::Actor::COLOR_BLUE:
3291 property = &mNode->mColor;
3294 case Dali::Actor::COLOR_ALPHA:
3295 property = &mNode->mColor;
3306 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3308 const PropertyInputImpl* property( NULL );
3310 // This method should only return a property of an object connected to the scene-graph
3316 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3318 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3320 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3322 property = entry->second.GetSceneGraphProperty();
3324 else if( NULL != mNode )
3328 case Dali::Actor::PARENT_ORIGIN:
3329 property = &mNode->mParentOrigin;
3332 case Dali::Actor::PARENT_ORIGIN_X:
3333 property = &mNode->mParentOrigin;
3336 case Dali::Actor::PARENT_ORIGIN_Y:
3337 property = &mNode->mParentOrigin;
3340 case Dali::Actor::PARENT_ORIGIN_Z:
3341 property = &mNode->mParentOrigin;
3344 case Dali::Actor::ANCHOR_POINT:
3345 property = &mNode->mAnchorPoint;
3348 case Dali::Actor::ANCHOR_POINT_X:
3349 property = &mNode->mAnchorPoint;
3352 case Dali::Actor::ANCHOR_POINT_Y:
3353 property = &mNode->mAnchorPoint;
3356 case Dali::Actor::ANCHOR_POINT_Z:
3357 property = &mNode->mAnchorPoint;
3360 case Dali::Actor::SIZE:
3361 property = &mNode->mSize;
3364 case Dali::Actor::SIZE_WIDTH:
3365 property = &mNode->mSize;
3368 case Dali::Actor::SIZE_HEIGHT:
3369 property = &mNode->mSize;
3372 case Dali::Actor::SIZE_DEPTH:
3373 property = &mNode->mSize;
3376 case Dali::Actor::POSITION:
3377 property = &mNode->mPosition;
3380 case Dali::Actor::POSITION_X:
3381 property = &mNode->mPosition;
3384 case Dali::Actor::POSITION_Y:
3385 property = &mNode->mPosition;
3388 case Dali::Actor::POSITION_Z:
3389 property = &mNode->mPosition;
3392 case Dali::Actor::WORLD_POSITION:
3393 property = &mNode->mWorldPosition;
3396 case Dali::Actor::WORLD_POSITION_X:
3397 property = &mNode->mWorldPosition;
3400 case Dali::Actor::WORLD_POSITION_Y:
3401 property = &mNode->mWorldPosition;
3404 case Dali::Actor::WORLD_POSITION_Z:
3405 property = &mNode->mWorldPosition;
3408 case Dali::Actor::ROTATION:
3409 property = &mNode->mRotation;
3412 case Dali::Actor::WORLD_ROTATION:
3413 property = &mNode->mWorldRotation;
3416 case Dali::Actor::SCALE:
3417 property = &mNode->mScale;
3420 case Dali::Actor::SCALE_X:
3421 property = &mNode->mScale;
3424 case Dali::Actor::SCALE_Y:
3425 property = &mNode->mScale;
3428 case Dali::Actor::SCALE_Z:
3429 property = &mNode->mScale;
3432 case Dali::Actor::WORLD_SCALE:
3433 property = &mNode->mWorldScale;
3436 case Dali::Actor::VISIBLE:
3437 property = &mNode->mVisible;
3440 case Dali::Actor::COLOR:
3441 property = &mNode->mColor;
3444 case Dali::Actor::COLOR_RED:
3445 property = &mNode->mColor;
3448 case Dali::Actor::COLOR_GREEN:
3449 property = &mNode->mColor;
3452 case Dali::Actor::COLOR_BLUE:
3453 property = &mNode->mColor;
3456 case Dali::Actor::COLOR_ALPHA:
3457 property = &mNode->mColor;
3460 case Dali::Actor::WORLD_COLOR:
3461 property = &mNode->mWorldColor;
3464 case Dali::Actor::WORLD_MATRIX:
3465 property = &mNode->mWorldMatrix;
3476 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3478 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3482 case Dali::Actor::PARENT_ORIGIN_X:
3483 case Dali::Actor::ANCHOR_POINT_X:
3484 case Dali::Actor::SIZE_WIDTH:
3485 case Dali::Actor::POSITION_X:
3486 case Dali::Actor::SCALE_X:
3487 case Dali::Actor::COLOR_RED:
3488 case Dali::Actor::WORLD_POSITION_X:
3494 case Dali::Actor::PARENT_ORIGIN_Y:
3495 case Dali::Actor::ANCHOR_POINT_Y:
3496 case Dali::Actor::SIZE_HEIGHT:
3497 case Dali::Actor::POSITION_Y:
3498 case Dali::Actor::SCALE_Y:
3499 case Dali::Actor::COLOR_GREEN:
3500 case Dali::Actor::WORLD_POSITION_Y:
3506 case Dali::Actor::PARENT_ORIGIN_Z:
3507 case Dali::Actor::ANCHOR_POINT_Z:
3508 case Dali::Actor::SIZE_DEPTH:
3509 case Dali::Actor::POSITION_Z:
3510 case Dali::Actor::SCALE_Z:
3511 case Dali::Actor::COLOR_BLUE:
3512 case Dali::Actor::WORLD_POSITION_Z:
3518 case Dali::Actor::COLOR_ALPHA:
3531 return componentIndex;
3534 void Actor::SetParent(Actor* parent)
3538 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3542 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3545 StagePtr stage = parent->mStage;
3547 // Instruct each actor to create a corresponding node in the scene graph
3548 ConnectToStage(*stage);
3551 else // parent being set to NULL
3553 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3557 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3560 DALI_ASSERT_ALWAYS(mNode != NULL);
3564 // Disconnect the Node & its children from the scene-graph.
3565 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3568 // Instruct each actor to discard pointers to the scene-graph
3569 DisconnectFromStage();
3574 SceneGraph::Node* Actor::CreateNode() const
3579 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3582 Actor* actor = dynamic_cast<Actor*>(object);
3586 if(Dali::Actor::ACTION_SHOW == actionName)
3588 actor->SetVisible(true);
3591 else if(Dali::Actor::ACTION_HIDE == actionName)
3593 actor->SetVisible(false);
3601 } // namespace Internal