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/common/event-thread-services.h>
37 #include <dali/internal/event/render-tasks/render-task-impl.h>
38 #include <dali/internal/event/actors/camera-actor-impl.h>
39 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
40 #include <dali/internal/event/common/property-helper.h>
41 #include <dali/internal/event/common/stage-impl.h>
42 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
43 #include <dali/internal/event/animation/constraint-impl.h>
44 #include <dali/internal/event/common/projection.h>
45 #include <dali/internal/update/common/animatable-property.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/events/actor-gesture-data.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 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::AnimatableProperty;
62 using Dali::Internal::SceneGraph::PropertyBase;
70 unsigned int Actor::mActorCounter = 0;
71 ActorContainer Actor::mNullChildren;
73 #ifdef DYNAMICS_SUPPORT
75 // Encapsulate actor related dynamics data
78 DynamicsData( Actor* slotOwner )
79 : slotDelegate( slotOwner )
83 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
84 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
87 JointContainer joints;
88 ReferencedJointContainer referencedJoints;
90 SlotDelegate< Actor > slotDelegate;
93 #endif // DYNAMICS_SUPPORT
95 namespace // unnamed namespace
101 * We want to discourage the use of property strings (minimize string comparisons),
102 * particularly for the default properties.
103 * Name Type writable animatable constraint-input enum for index-checking
105 DALI_PROPERTY_TABLE_BEGIN
106 DALI_PROPERTY( "parent-origin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
107 DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
108 DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
109 DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
110 DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
111 DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
112 DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
113 DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
114 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
115 DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
116 DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
117 DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
118 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
119 DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
120 DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
121 DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
122 DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
123 DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
124 DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
125 DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
126 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
127 DALI_PROPERTY( "world-orientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
128 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
129 DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
130 DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
131 DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
132 DALI_PROPERTY( "world-scale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
133 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
134 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
135 DALI_PROPERTY( "color-red", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
136 DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
137 DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
138 DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
139 DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
140 DALI_PROPERTY( "world-matrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
141 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
142 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
143 DALI_PROPERTY( "leave-required", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
144 DALI_PROPERTY( "inherit-orientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
145 DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
146 DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
147 DALI_PROPERTY( "position-inheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
148 DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
149 DALI_PROPERTY( "size-mode", STRING, true, false, false, Dali::Actor::Property::SIZE_MODE )
150 DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
151 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
155 const char* const SIGNAL_TOUCHED = "touched";
156 const char* const SIGNAL_HOVERED = "hovered";
157 const char* const SIGNAL_MOUSE_WHEEL_EVENT = "mouse-wheel-event";
158 const char* const SIGNAL_ON_STAGE = "on-stage";
159 const char* const SIGNAL_OFF_STAGE = "off-stage";
163 const char* const ACTION_SHOW = "show";
164 const char* const ACTION_HIDE = "hide";
166 // Enumeration to / from string conversion tables
168 DALI_ENUM_TO_STRING_TABLE_BEGIN( SizeMode )
169 DALI_ENUM_TO_STRING( USE_OWN_SIZE )
170 DALI_ENUM_TO_STRING( SIZE_EQUAL_TO_PARENT )
171 DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT )
172 DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT )
173 DALI_ENUM_TO_STRING_TABLE_END( SizeMode )
175 BaseHandle CreateActor()
177 return Dali::Actor::New();
180 TypeRegistration mType( typeid( Dali::Actor ), typeid( Dali::Handle ), CreateActor );
182 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
183 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
184 SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
185 SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
187 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
188 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
190 } // unnamed namespace
192 ActorPtr Actor::New()
194 ActorPtr actor( new Actor( BASIC ) );
196 // Second-phase construction
202 const std::string& Actor::GetName() const
207 void Actor::SetName(const std::string& name)
213 // ATTENTION: string for debug purposes is not thread safe.
214 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
218 unsigned int Actor::GetId() const
223 void Actor::Attach( ActorAttachment& attachment )
225 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
229 attachment.Connect();
232 mAttachment = ActorAttachmentPtr(&attachment);
235 ActorAttachmentPtr Actor::GetAttachment()
240 bool Actor::OnStage() const
245 Dali::Layer Actor::GetLayer()
249 // Short-circuit for Layer derived actors
252 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
255 // Find the immediate Layer parent
256 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
258 if( parent->IsLayer() )
260 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
267 void Actor::Add(Actor& child)
269 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
270 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
274 mChildren = new ActorContainer;
277 Actor* const oldParent( child.mParent );
279 // child might already be ours
280 if( this != oldParent )
282 // if we already have parent, unparent us first
285 oldParent->Remove( child ); // This causes OnChildRemove callback
288 // Guard against Add() during previous OnChildRemove callback
289 if ( !child.mParent )
291 // Do this first, since user callbacks from within SetParent() may need to remove child
292 mChildren->push_back(Dali::Actor(&child));
294 // SetParent asserts that child can be added
295 child.SetParent(this);
297 // Notification for derived classes
303 void Actor::Insert(unsigned int index, Actor& child)
305 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
306 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
310 mChildren = new ActorContainer;
313 Actor* const oldParent( child.mParent );
315 // since an explicit position has been given, always insert, even if already a child
318 oldParent->Remove( child ); // This causes OnChildRemove callback
321 // Guard against Add() during previous OnChildRemove callback
322 if ( !child.mParent )
324 // Do this first, since user callbacks from within SetParent() may need to remove child
325 if (index < GetChildCount())
327 ActorIter it = mChildren->begin();
328 std::advance(it, index);
329 mChildren->insert(it, Dali::Actor(&child));
333 mChildren->push_back(Dali::Actor(&child));
335 // SetParent asserts that child can be added
336 child.SetParent(this, index);
338 // Notification for derived classes
343 void Actor::Remove(Actor& child)
345 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
355 // Find the child in mChildren, and unparent it
356 ActorIter end = mChildren->end();
357 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
359 Actor& actor = GetImplementation(*iter);
361 if( &actor == &child )
363 // Keep handle for OnChildRemove notification
364 removed = Dali::Actor( &actor );
366 // Do this first, since user callbacks from within SetParent() may need to add the child
367 mChildren->erase(iter);
369 DALI_ASSERT_DEBUG( actor.GetParent() == this );
370 actor.SetParent( NULL );
378 // Notification for derived classes
379 OnChildRemove( GetImplementation(removed) );
383 void Actor::Unparent()
387 mParent->Remove( *this );
391 unsigned int Actor::GetChildCount() const
393 return ( NULL != mChildren ) ? mChildren->size() : 0;
396 Dali::Actor Actor::GetChildAt(unsigned int index) const
398 DALI_ASSERT_ALWAYS( index < GetChildCount() );
400 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
403 ActorContainer Actor::GetChildren()
405 if( NULL != mChildren )
410 // return copy of mNullChildren
411 return mNullChildren;
414 const ActorContainer& Actor::GetChildren() const
416 if( NULL != mChildren )
421 // return const reference to mNullChildren
422 return mNullChildren;
425 ActorPtr Actor::FindChildByName(const std::string& actorName)
428 if (actorName == mName)
434 ActorIter end = mChildren->end();
435 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
437 child = GetImplementation(*iter).FindChildByName(actorName);
448 ActorPtr Actor::FindChildById(const unsigned int id)
457 ActorIter end = mChildren->end();
458 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
460 child = GetImplementation(*iter).FindChildById(id);
471 void Actor::SetParentOrigin( const Vector3& origin )
475 // mNode is being used in a separate thread; queue a message to set the value & base value
476 SetParentOriginMessage( GetEventThreadServices(), *mNode, origin );
479 // Cache for event-thread access
482 // not allocated, check if different from default
483 if( ParentOrigin::DEFAULT != origin )
485 mParentOrigin = new Vector3( origin );
490 // check if different from current costs more than just set
491 *mParentOrigin = origin;
495 void Actor::SetParentOriginX( float x )
497 const Vector3& current = GetCurrentParentOrigin();
499 SetParentOrigin( Vector3( x, current.y, current.z ) );
502 void Actor::SetParentOriginY( float y )
504 const Vector3& current = GetCurrentParentOrigin();
506 SetParentOrigin( Vector3( current.x, y, current.z ) );
509 void Actor::SetParentOriginZ( float z )
511 const Vector3& current = GetCurrentParentOrigin();
513 SetParentOrigin( Vector3( current.x, current.y, z ) );
516 const Vector3& Actor::GetCurrentParentOrigin() const
518 // Cached for event-thread access
519 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
522 void Actor::SetAnchorPoint(const Vector3& anchor)
526 // mNode is being used in a separate thread; queue a message to set the value & base value
527 SetAnchorPointMessage( GetEventThreadServices(), *mNode, anchor );
530 // Cache for event-thread access
533 // not allocated, check if different from default
534 if( AnchorPoint::DEFAULT != anchor )
536 mAnchorPoint = new Vector3( anchor );
541 // check if different from current costs more than just set
542 *mAnchorPoint = anchor;
546 void Actor::SetAnchorPointX( float x )
548 const Vector3& current = GetCurrentAnchorPoint();
550 SetAnchorPoint( Vector3( x, current.y, current.z ) );
553 void Actor::SetAnchorPointY( float y )
555 const Vector3& current = GetCurrentAnchorPoint();
557 SetAnchorPoint( Vector3( current.x, y, current.z ) );
560 void Actor::SetAnchorPointZ( float z )
562 const Vector3& current = GetCurrentAnchorPoint();
564 SetAnchorPoint( Vector3( current.x, current.y, z ) );
567 const Vector3& Actor::GetCurrentAnchorPoint() const
569 // Cached for event-thread access
570 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
573 void Actor::SetPosition(float x, float y)
575 SetPosition(Vector3(x, y, 0.0f));
578 void Actor::SetPosition(float x, float y, float z)
580 SetPosition(Vector3(x, y, z));
583 void Actor::SetPosition(const Vector3& position)
587 // mNode is being used in a separate thread; queue a message to set the value & base value
588 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
592 void Actor::SetX(float x)
596 // mNode is being used in a separate thread; queue a message to set the value & base value
597 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
601 void Actor::SetY(float y)
605 // mNode is being used in a separate thread; queue a message to set the value & base value
606 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
610 void Actor::SetZ(float z)
614 // mNode is being used in a separate thread; queue a message to set the value & base value
615 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
619 void Actor::TranslateBy(const Vector3& distance)
623 // mNode is being used in a separate thread; queue a message to set the value & base value
624 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
628 const Vector3& Actor::GetCurrentPosition() const
632 // mNode is being used in a separate thread; copy the value from the previous update
633 return mNode->GetPosition(GetEventThreadServices().GetEventBufferIndex());
636 return Vector3::ZERO;
639 const Vector3& Actor::GetCurrentWorldPosition() const
643 // mNode is being used in a separate thread; copy the value from the previous update
644 return mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
647 return Vector3::ZERO;
650 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
652 // this flag is not animatable so keep the value
653 mPositionInheritanceMode = mode;
656 // mNode is being used in a separate thread; queue a message to set the value
657 SetPositionInheritanceModeMessage( GetEventThreadServices(), *mNode, mode );
661 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
663 // Cached for event-thread access
664 return mPositionInheritanceMode;
667 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
669 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
670 normalizedAxis.Normalize();
672 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
674 SetOrientation(orientation);
677 void Actor::SetOrientation(const Quaternion& orientation)
681 // mNode is being used in a separate thread; queue a message to set the value & base value
682 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::Bake, orientation );
686 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
690 // mNode is being used in a separate thread; queue a message to set the value & base value
691 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
695 void Actor::RotateBy(const Quaternion& relativeRotation)
699 // mNode is being used in a separate thread; queue a message to set the value & base value
700 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
704 const Quaternion& Actor::GetCurrentOrientation() const
708 // mNode is being used in a separate thread; copy the value from the previous update
709 return mNode->GetOrientation(GetEventThreadServices().GetEventBufferIndex());
712 return Quaternion::IDENTITY;
715 const Quaternion& Actor::GetCurrentWorldOrientation() const
719 // mNode is being used in a separate thread; copy the value from the previous update
720 return mNode->GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
723 return Quaternion::IDENTITY;
726 void Actor::SetScale(float scale)
728 SetScale(Vector3(scale, scale, scale));
731 void Actor::SetScale(float x, float y, float z)
733 SetScale(Vector3(x, y, z));
736 void Actor::SetScale(const Vector3& scale)
740 // mNode is being used in a separate thread; queue a message to set the value & base value
741 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
745 void Actor::SetScaleX( float x )
749 // mNode is being used in a separate thread; queue a message to set the value & base value
750 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
754 void Actor::SetScaleY( float y )
758 // mNode is being used in a separate thread; queue a message to set the value & base value
759 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
763 void Actor::SetScaleZ( float z )
767 // mNode is being used in a separate thread; queue a message to set the value & base value
768 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
772 void Actor::SetInitialVolume(const Vector3& volume)
776 // mNode is being used in a separate thread; queue a message to set the value
777 SetInitialVolumeMessage( GetEventThreadServices(), *mNode, volume );
781 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
785 // mNode is being used in a separate thread; queue a message to set the value
786 SetTransmitGeometryScalingMessage( GetEventThreadServices(), *mNode, transmitGeometryScaling );
790 bool Actor::GetTransmitGeometryScaling() const
794 // mNode is being used in a separate thread; copy the value from the previous update
795 return mNode->GetTransmitGeometryScaling();
801 void Actor::ScaleBy(const Vector3& relativeScale)
805 // mNode is being used in a separate thread; queue a message to set the value & base value
806 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
810 const Vector3& Actor::GetCurrentScale() const
814 // mNode is being used in a separate thread; copy the value from the previous update
815 return mNode->GetScale(GetEventThreadServices().GetEventBufferIndex());
821 const Vector3& Actor::GetCurrentWorldScale() const
825 // mNode is being used in a separate thread; copy the value from the previous update
826 return mNode->GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
832 void Actor::SetInheritScale( bool inherit )
834 // non animateable so keep local copy
835 mInheritScale = inherit;
838 // mNode is being used in a separate thread; queue a message to set the value
839 SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit );
843 bool Actor::IsScaleInherited() const
845 return mInheritScale;
848 Matrix Actor::GetCurrentWorldMatrix() const
852 // World matrix is no longer updated unless there is something observing the node.
853 // Need to calculate it from node's world position, orientation and scale:
854 BufferIndex updateBufferIndex = GetEventThreadServices().GetEventBufferIndex();
855 Matrix worldMatrix(false);
856 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
857 mNode->GetWorldOrientation( updateBufferIndex ),
858 mNode->GetWorldPosition( updateBufferIndex ) );
862 return Matrix::IDENTITY;
865 void Actor::SetVisible(bool visible)
869 // mNode is being used in a separate thread; queue a message to set the value & base value
870 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
874 bool Actor::IsVisible() const
878 // mNode is being used in a separate thread; copy the value from the previous update
879 return mNode->IsVisible( GetEventThreadServices().GetEventBufferIndex() );
885 void Actor::SetOpacity(float opacity)
889 // mNode is being used in a separate thread; queue a message to set the value & base value
890 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
894 float Actor::GetCurrentOpacity() const
898 // mNode is being used in a separate thread; copy the value from the previous update
899 return mNode->GetOpacity(GetEventThreadServices().GetEventBufferIndex());
905 const Vector4& Actor::GetCurrentWorldColor() const
909 return mNode->GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
915 void Actor::SetColor(const Vector4& color)
919 // mNode is being used in a separate thread; queue a message to set the value & base value
920 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
924 void Actor::SetColorRed( float red )
928 // mNode is being used in a separate thread; queue a message to set the value & base value
929 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
933 void Actor::SetColorGreen( float green )
937 // mNode is being used in a separate thread; queue a message to set the value & base value
938 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
942 void Actor::SetColorBlue( float blue )
946 // mNode is being used in a separate thread; queue a message to set the value & base value
947 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
951 const Vector4& Actor::GetCurrentColor() const
955 // mNode is being used in a separate thread; copy the value from the previous update
956 return mNode->GetColor(GetEventThreadServices().GetEventBufferIndex());
962 void Actor::SetInheritOrientation(bool inherit)
964 // non animateable so keep local copy
965 mInheritOrientation = inherit;
968 // mNode is being used in a separate thread; queue a message to set the value
969 SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit );
973 bool Actor::IsOrientationInherited() const
975 return mInheritOrientation;
978 void Actor::SetSizeMode(SizeMode mode)
980 // non animateable so keep local copy
984 // mNode is being used in a separate thread; queue a message to set the value
985 SetSizeModeMessage( GetEventThreadServices(), *mNode, mode );
989 void Actor::SetSizeModeFactor(const Vector3& factor)
991 // non animateable so keep local copy
992 mSizeModeFactor = factor;
995 // mNode is being used in a separate thread; queue a message to set the value
996 SetSizeModeFactorMessage( GetEventThreadServices(), *mNode, factor );
1000 SizeMode Actor::GetSizeMode() const
1005 const Vector3& Actor::GetSizeModeFactor() const
1007 return mSizeModeFactor;
1010 void Actor::SetColorMode(ColorMode colorMode)
1012 // non animateable so keep local copy
1013 mColorMode = colorMode;
1016 // mNode is being used in a separate thread; queue a message to set the value
1017 SetColorModeMessage( GetEventThreadServices(), *mNode, colorMode );
1021 ColorMode Actor::GetColorMode() const
1023 // we have cached copy
1027 void Actor::SetSize(float width, float height)
1029 SetSize( Vector2( width, height ) );
1032 void Actor::SetSize(float width, float height, float depth)
1034 SetSize( Vector3( width, height, depth ) );
1037 void Actor::SetSize(const Vector2& size)
1039 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1042 float Actor::CalculateSizeZ( const Vector2& size ) const
1044 return std::min( size.width, size.height );
1047 void Actor::SetSize(const Vector3& size)
1053 // mNode is being used in a separate thread; queue a message to set the value & base value
1054 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1056 // Notification for derived classes
1061 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1065 // Notify deriving classes
1066 OnSizeAnimation( animation, targetSize );
1069 void Actor::SetWidth( float width )
1073 // mNode is being used in a separate thread; queue a message to set the value & base value
1074 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1078 void Actor::SetHeight( float height )
1082 // mNode is being used in a separate thread; queue a message to set the value & base value
1083 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1087 void Actor::SetDepth( float depth )
1091 // mNode is being used in a separate thread; queue a message to set the value & base value
1092 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1096 const Vector3& Actor::GetSize() const
1101 const Vector3& Actor::GetCurrentSize() const
1105 // mNode is being used in a separate thread; copy the value from the previous update
1106 return mNode->GetSize( GetEventThreadServices().GetEventBufferIndex() );
1109 return Vector3::ZERO;
1112 Vector3 Actor::GetNaturalSize() const
1114 // It is up to deriving classes to return the appropriate natural size
1115 return Vector3( 0.0f, 0.0f, 0.0f );
1119 #ifdef DYNAMICS_SUPPORT
1121 //--------------- Dynamics ---------------
1123 void Actor::DisableDynamics()
1125 if( NULL != mDynamicsData )
1127 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1129 // ensure dynamics object are disconnected from scene
1130 DisconnectDynamics();
1132 // delete joint owned by this actor
1133 while( !mDynamicsData->joints.empty() )
1135 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1138 // delete other joints referencing this actor
1139 while( !mDynamicsData->referencedJoints.empty() )
1141 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1142 ActorPtr jointOwner( joint->GetActor( true ) );
1145 jointOwner->RemoveDynamicsJoint( joint );
1149 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1152 // delete the DynamicsBody object
1153 mDynamicsData->body.Reset();
1155 // Discard Dynamics data structure
1156 delete mDynamicsData;
1157 mDynamicsData = NULL;
1161 DynamicsBodyPtr Actor::GetDynamicsBody() const
1163 DynamicsBodyPtr body;
1165 if( NULL != mDynamicsData )
1167 body = mDynamicsData->body;
1173 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1175 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1177 if( NULL == mDynamicsData )
1179 mDynamicsData = new DynamicsData( this );
1182 if( !mDynamicsData->body )
1184 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1188 DynamicsWorldPtr world( DynamicsWorld::Get() );
1191 if( mParent == world->GetRootActor().Get() )
1193 mDynamicsData->body->Connect( GetEventThreadServices() );
1199 return mDynamicsData->body;
1202 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1204 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1205 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1208 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1210 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1211 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1213 DynamicsJointPtr joint;
1215 DynamicsWorldPtr world( DynamicsWorld::Get() );
1219 if( NULL != mDynamicsData )
1221 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1223 if( mDynamicsData->joints.end() != it )
1225 // use existing joint
1231 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1232 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1236 bodyA = EnableDynamics( new DynamicsBodyConfig );
1241 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1244 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1245 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1247 if( OnStage() && attachedActor->OnStage() )
1249 joint->Connect( GetEventThreadServices() );
1252 attachedActor->ReferenceJoint( joint );
1254 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1255 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1262 const int Actor::GetNumberOfJoints() const
1264 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1267 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1269 DynamicsJointPtr joint;
1271 if( NULL != mDynamicsData )
1273 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1275 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1277 for( int i = 0; i < index; ++i )
1289 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1291 DynamicsJointPtr joint;
1293 if( NULL != mDynamicsData )
1295 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1297 if( mDynamicsData->joints.end() != it )
1299 // use existing joint
1307 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1309 if( NULL != mDynamicsData )
1311 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1312 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1314 for( ; it != endIt; ++it )
1316 if( it->second == joint.Get() )
1318 ActorPtr attachedActor( it->first );
1320 if( OnStage() && attachedActor && attachedActor->OnStage() )
1322 joint->Disconnect( GetEventThreadServices() );
1327 attachedActor->ReleaseJoint( joint );
1328 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1329 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1332 mDynamicsData->joints.erase(it);
1339 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1341 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1343 if( NULL != mDynamicsData )
1345 mDynamicsData->referencedJoints.push_back(joint);
1349 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1351 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1353 if( NULL != mDynamicsData )
1355 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1357 if( it != mDynamicsData->referencedJoints.end() )
1359 mDynamicsData->referencedJoints.erase( it );
1364 void Actor::SetDynamicsRoot(bool flag)
1366 if( mIsDynamicsRoot != flag )
1368 mIsDynamicsRoot = flag;
1370 if( OnStage() && mChildren )
1372 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1373 ActorIter end = mChildren->end();
1374 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1376 Actor& child = GetImplementation(*iter);
1378 if( child.GetDynamicsBody() )
1380 if( mIsDynamicsRoot )
1382 child.ConnectDynamics();
1386 child.DisconnectDynamics();
1394 bool Actor::IsDynamicsRoot() const
1396 return mIsDynamicsRoot;
1399 void Actor::AttachedActorOnStage( Dali::Actor actor )
1401 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1405 ActorPtr attachedActor( &GetImplementation(actor) );
1407 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1408 if( NULL != mDynamicsData )
1410 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1411 if( mDynamicsData->joints.end() != it )
1413 DynamicsJointPtr joint( it->second );
1414 joint->Connect( GetEventThreadServices() );
1420 void Actor::AttachedActorOffStage( Dali::Actor actor )
1422 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1426 ActorPtr attachedActor( &GetImplementation(actor) );
1428 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1429 if( NULL != mDynamicsData )
1431 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1432 if( mDynamicsData->joints.end() != it )
1434 DynamicsJointPtr joint( it->second );
1435 joint->Disconnect( GetEventThreadServices() );
1441 void Actor::ConnectDynamics()
1443 if( NULL != mDynamicsData && mDynamicsData->body )
1445 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1447 mDynamicsData->body->Connect( GetEventThreadServices() );
1449 // Connect all joints where attachedActor is also on stage
1450 if( !mDynamicsData->joints.empty() )
1452 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1453 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1455 for( ; it != endIt; ++it )
1457 Actor* attachedActor( it->first );
1458 if( NULL != attachedActor && attachedActor->OnStage() )
1460 DynamicsJointPtr joint( it->second );
1462 joint->Connect( GetEventThreadServices() );
1470 void Actor::DisconnectDynamics()
1472 if( NULL != mDynamicsData && mDynamicsData->body )
1476 mDynamicsData->body->Disconnect( GetEventThreadServices() );
1478 // Disconnect all joints
1479 if( !mDynamicsData->joints.empty() )
1481 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1482 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1484 for( ; it != endIt; ++it )
1486 DynamicsJointPtr joint( it->second );
1488 joint->Disconnect( GetEventThreadServices() );
1495 #endif // DYNAMICS_SUPPORT
1497 void Actor::SetOverlay(bool enable)
1499 // Setting STENCIL will override OVERLAY
1500 if( DrawMode::STENCIL != mDrawMode )
1502 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1506 bool Actor::IsOverlay() const
1508 return ( DrawMode::OVERLAY == mDrawMode );
1511 void Actor::SetDrawMode( DrawMode::Type drawMode )
1513 // this flag is not animatable so keep the value
1514 mDrawMode = drawMode;
1517 // mNode is being used in a separate thread; queue a message to set the value
1518 SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
1522 DrawMode::Type Actor::GetDrawMode() const
1527 bool Actor::ScreenToLocal( float& localX,
1530 float screenY ) const
1532 // only valid when on-stage
1535 const RenderTaskList& taskList = Stage::GetCurrent()->GetRenderTaskList();
1537 Vector2 converted( screenX, screenY );
1539 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1540 const int taskCount = taskList.GetTaskCount();
1541 for( int i = taskCount - 1; i >= 0; --i )
1543 Dali::RenderTask task = taskList.GetTask( i );
1544 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1546 // found a task where this conversion was ok so return
1554 bool Actor::ScreenToLocal( RenderTask& renderTask,
1558 float screenY ) const
1560 bool retval = false;
1561 // only valid when on-stage
1564 CameraActor* camera = renderTask.GetCameraActor();
1568 renderTask.GetViewport( viewport );
1570 // need to translate coordinates to render tasks coordinate space
1571 Vector2 converted( screenX, screenY );
1572 if( renderTask.TranslateCoordinates( converted ) )
1574 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1581 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1582 const Matrix& projectionMatrix,
1583 const Viewport& viewport,
1587 float screenY ) const
1589 // Early-out if mNode is NULL
1595 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1597 // Calculate the ModelView matrix
1598 Matrix modelView(false/*don't init*/);
1599 // need to use the components as world matrix is only updated for actors that need it
1600 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldOrientation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1601 Matrix::Multiply(modelView, modelView, viewMatrix);
1603 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1604 Matrix invertedMvp(false/*don't init*/);
1605 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1606 bool success = invertedMvp.Invert();
1608 // Convert to GL coordinates
1609 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1614 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1621 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1627 if (XyPlaneIntersect(nearPos, farPos, local))
1629 Vector3 size = GetCurrentSize();
1630 localX = local.x + size.x * 0.5f;
1631 localY = local.y + size.y * 0.5f;
1642 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1645 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1647 Mathematical Formulation
1649 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1651 ( p - c ) dot ( p - c ) = r^2
1653 Given a ray with a point of origin 'o', and a direction vector 'd':
1655 ray(t) = o + td, t >= 0
1657 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1659 (o + td - c ) dot ( o + td - c ) = r^2
1661 To solve for t we first expand the above into a more recognisable quadratic equation form
1663 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1672 B = 2( o - c ) dot d
1673 C = ( o - c ) dot ( o - c ) - r^2
1675 which can be solved using a standard quadratic formula.
1677 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1679 Practical Simplification
1681 In a renderer, we often differentiate between world space and object space. In the object space
1682 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1683 into object space, the mathematical solution presented above can be simplified significantly.
1685 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1689 and we can find the t at which the (transformed) ray intersects the sphere by
1691 ( o + td ) dot ( o + td ) = r^2
1693 According to the reasoning above, we expand the above quadratic equation into the general form
1697 which now has coefficients:
1704 // Early out if mNode is NULL
1710 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1712 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1713 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1714 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1715 rayOrigin.y - translation.y,
1716 rayOrigin.z - translation.z);
1718 // Compute the radius is not needed, square radius it's enough.
1719 const Vector3& size( mNode->GetSize( bufferIndex ) );
1721 // Scale the sphere.
1722 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1724 const float width = size.width * scale.width;
1725 const float height = size.height * scale.height;
1727 float squareSphereRadius = 0.5f * ( width * width + height * height );
1729 float a = rayDir.Dot( rayDir ); // a
1730 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1731 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1733 return ( b2*b2 - a*c ) >= 0.f;
1736 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1743 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
1745 // Transforms the ray to the local reference system.
1747 // Calculate the inverse of Model matrix
1748 Matrix invModelMatrix(false/*don't init*/);
1749 // need to use the components as world matrix is only updated for actors that need it
1750 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldOrientation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1752 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1753 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1755 // Test with the actor's XY plane (Normal = 0 0 1 1).
1757 float a = -rayOriginLocal.z;
1758 float b = rayDirLocal.z;
1760 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1762 // Ray travels distance * rayDirLocal to intersect with plane.
1765 const Vector3& size = mNode->GetSize( bufferIndex );
1767 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1768 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1770 // Test with the actor's geometry.
1771 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1778 void Actor::SetLeaveRequired(bool required)
1780 mLeaveRequired = required;
1783 bool Actor::GetLeaveRequired() const
1785 return mLeaveRequired;
1788 void Actor::SetKeyboardFocusable( bool focusable )
1790 mKeyboardFocusable = focusable;
1793 bool Actor::IsKeyboardFocusable() const
1795 return mKeyboardFocusable;
1798 bool Actor::GetTouchRequired() const
1800 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1803 bool Actor::GetHoverRequired() const
1805 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1808 bool Actor::GetMouseWheelEventRequired() const
1810 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1813 bool Actor::IsHittable() const
1815 return IsSensitive() &&
1817 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1821 ActorGestureData& Actor::GetGestureData()
1823 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1824 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1825 if ( NULL == mGestureData )
1827 mGestureData = new ActorGestureData;
1829 return *mGestureData;
1832 bool Actor::IsGestureRequred( Gesture::Type type ) const
1834 return mGestureData && mGestureData->IsGestureRequred( type );
1837 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1839 bool consumed = false;
1841 if ( !mTouchedSignal.Empty() )
1843 Dali::Actor handle( this );
1844 consumed = mTouchedSignal.Emit( handle, event );
1849 // Notification for derived classes
1850 consumed = OnTouchEvent( event );
1856 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1858 bool consumed = false;
1860 if ( !mHoveredSignal.Empty() )
1862 Dali::Actor handle( this );
1863 consumed = mHoveredSignal.Emit( handle, event );
1868 // Notification for derived classes
1869 consumed = OnHoverEvent( event );
1875 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1877 bool consumed = false;
1879 if ( !mMouseWheelEventSignal.Empty() )
1881 Dali::Actor handle( this );
1882 consumed = mMouseWheelEventSignal.Emit( handle, event );
1887 // Notification for derived classes
1888 consumed = OnMouseWheelEvent(event);
1894 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1896 return mTouchedSignal;
1899 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1901 return mHoveredSignal;
1904 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1906 return mMouseWheelEventSignal;
1909 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1911 return mOnStageSignal;
1914 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1916 return mOffStageSignal;
1919 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1921 bool connected( true );
1922 Actor* actor = dynamic_cast<Actor*>( object );
1924 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
1926 actor->TouchedSignal().Connect( tracker, functor );
1928 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
1930 actor->HoveredSignal().Connect( tracker, functor );
1932 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
1934 actor->MouseWheelEventSignal().Connect( tracker, functor );
1936 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
1938 actor->OnStageSignal().Connect( tracker, functor );
1940 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
1942 actor->OffStageSignal().Connect( tracker, functor );
1946 // signalName does not match any signal
1953 Actor::Actor( DerivedType derivedType )
1957 mParentOrigin( NULL ),
1958 mAnchorPoint( NULL ),
1959 #ifdef DYNAMICS_SUPPORT
1960 mDynamicsData( NULL ),
1962 mGestureData( NULL ),
1964 mSize( 0.0f, 0.0f, 0.0f ),
1965 mSizeModeFactor( Vector3::ONE ),
1967 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1968 mIsRoot( ROOT_LAYER == derivedType ),
1969 mIsRenderable( RENDERABLE == derivedType ),
1970 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1971 mIsOnStage( false ),
1972 mIsDynamicsRoot(false),
1974 mLeaveRequired( false ),
1975 mKeyboardFocusable( false ),
1976 mDerivedRequiresTouch( false ),
1977 mDerivedRequiresHover( false ),
1978 mDerivedRequiresMouseWheelEvent( false ),
1979 mOnStageSignalled( false ),
1980 mInheritOrientation( true ),
1981 mInheritScale( true ),
1982 mDrawMode( DrawMode::NORMAL ),
1983 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1984 mColorMode( Node::DEFAULT_COLOR_MODE ),
1985 mSizeMode( Node::DEFAULT_SIZE_MODE )
1989 void Actor::Initialize()
1992 SceneGraph::Node* node = CreateNode();
1994 AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
1995 mNode = node; // Keep raw-pointer to Node
1999 GetEventThreadServices().RegisterObject( this );
2004 // Remove mParent pointers from children even if we're destroying core,
2005 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2008 ActorConstIter endIter = mChildren->end();
2009 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2011 Actor& actor = GetImplementation( *iter );
2012 actor.SetParent( NULL );
2017 // Guard to allow handle destruction after Core has been destroyed
2018 if( EventThreadServices::IsCoreRunning() )
2022 DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
2023 mNode = NULL; // Node is about to be destroyed
2026 GetEventThreadServices().UnregisterObject( this );
2029 #ifdef DYNAMICS_SUPPORT
2031 delete mDynamicsData;
2034 // Cleanup optional gesture data
2035 delete mGestureData;
2037 // Cleanup optional parent origin and anchor
2038 delete mParentOrigin;
2039 delete mAnchorPoint;
2042 void Actor::ConnectToStage( int index )
2044 // This container is used instead of walking the Actor hierachy.
2045 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2046 ActorContainer connectionList;
2048 // This stage is atomic i.e. not interrupted by user callbacks
2049 RecursiveConnectToStage( connectionList, index );
2051 // Notify applications about the newly connected actors.
2052 const ActorIter endIter = connectionList.end();
2053 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2055 Actor& actor = GetImplementation(*iter);
2056 actor.NotifyStageConnection();
2060 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2062 DALI_ASSERT_ALWAYS( !OnStage() );
2066 ConnectToSceneGraph(index);
2068 // Notification for internal derived classes
2069 OnStageConnectionInternal();
2071 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2072 connectionList.push_back( Dali::Actor(this) );
2074 // Recursively connect children
2077 ActorConstIter endIter = mChildren->end();
2078 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2080 Actor& actor = GetImplementation( *iter );
2081 actor.RecursiveConnectToStage( connectionList );
2087 * This method is called when the Actor is connected to the Stage.
2088 * The parent must have added its Node to the scene-graph.
2089 * The child must connect its Node to the parent's Node.
2090 * This is resursive; the child calls ConnectToStage() for its children.
2092 void Actor::ConnectToSceneGraph(int index)
2094 DALI_ASSERT_DEBUG( mNode != NULL);
2095 DALI_ASSERT_DEBUG( mParent != NULL);
2096 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2100 // Reparent Node in next Update
2101 ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode, index );
2104 // Notify attachment
2107 mAttachment->Connect();
2110 #ifdef DYNAMICS_SUPPORT
2112 if( NULL != mDynamicsData )
2118 // Notification for Object::Observers
2122 void Actor::NotifyStageConnection()
2124 // Actors can be removed (in a callback), before the on-stage stage is reported.
2125 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2126 if ( OnStage() && !mOnStageSignalled )
2128 // Notification for external (CustomActor) derived classes
2129 OnStageConnectionExternal();
2131 if ( !mOnStageSignal.Empty() )
2133 Dali::Actor handle( this );
2134 mOnStageSignal.Emit( handle );
2137 // Guard against Remove during callbacks
2140 mOnStageSignalled = true; // signal required next time Actor is removed
2145 void Actor::DisconnectFromStage()
2147 // This container is used instead of walking the Actor hierachy.
2148 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2149 ActorContainer disconnectionList;
2151 // This stage is atomic i.e. not interrupted by user callbacks
2152 RecursiveDisconnectFromStage( disconnectionList );
2154 // Notify applications about the newly disconnected actors.
2155 const ActorIter endIter = disconnectionList.end();
2156 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2158 Actor& actor = GetImplementation(*iter);
2159 actor.NotifyStageDisconnection();
2163 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2165 DALI_ASSERT_ALWAYS( OnStage() );
2167 // Recursively disconnect children
2170 ActorConstIter endIter = mChildren->end();
2171 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2173 Actor& actor = GetImplementation( *iter );
2174 actor.RecursiveDisconnectFromStage( disconnectionList );
2178 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2179 disconnectionList.push_back( Dali::Actor(this) );
2181 // Notification for internal derived classes
2182 OnStageDisconnectionInternal();
2184 DisconnectFromSceneGraph();
2190 * This method is called by an actor or its parent, before a node removal message is sent.
2191 * This is recursive; the child calls DisconnectFromStage() for its children.
2193 void Actor::DisconnectFromSceneGraph()
2195 // Notification for Object::Observers
2196 OnSceneObjectRemove();
2198 // Notify attachment
2201 mAttachment->Disconnect();
2204 #ifdef DYNAMICS_SUPPORT
2206 if( NULL != mDynamicsData )
2208 DisconnectDynamics();
2213 void Actor::NotifyStageDisconnection()
2215 // Actors can be added (in a callback), before the off-stage state is reported.
2216 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2217 // only do this step if there is a stage, i.e. Core is not being shut down
2218 if ( EventThreadServices::IsCoreRunning() && !OnStage() && mOnStageSignalled )
2220 // Notification for external (CustomeActor) derived classes
2221 OnStageDisconnectionExternal();
2223 if( !mOffStageSignal.Empty() )
2225 Dali::Actor handle( this );
2226 mOffStageSignal.Emit( handle );
2229 // Guard against Add during callbacks
2232 mOnStageSignalled = false; // signal required next time Actor is added
2237 bool Actor::IsNodeConnected() const
2239 bool connected( false );
2244 if( mNode->IsRoot() || mNode->GetParent() )
2253 unsigned int Actor::GetDefaultPropertyCount() const
2255 return DEFAULT_PROPERTY_COUNT;
2258 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2260 indices.reserve( DEFAULT_PROPERTY_COUNT );
2262 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2264 indices.push_back( i );
2268 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2270 if( index < DEFAULT_PROPERTY_COUNT )
2272 return DEFAULT_PROPERTY_DETAILS[index].name;
2278 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2280 Property::Index index = Property::INVALID_INDEX;
2282 // Look for name in default properties
2283 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2285 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2286 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2296 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2298 if( index < DEFAULT_PROPERTY_COUNT )
2300 return DEFAULT_PROPERTY_DETAILS[index].writable;
2306 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2308 if( index < DEFAULT_PROPERTY_COUNT )
2310 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2316 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2318 if( index < DEFAULT_PROPERTY_COUNT )
2320 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2326 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2328 if( index < DEFAULT_PROPERTY_COUNT )
2330 return DEFAULT_PROPERTY_DETAILS[index].type;
2333 // index out of range...return Property::NONE
2334 return Property::NONE;
2337 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2341 case Dali::Actor::Property::PARENT_ORIGIN:
2343 SetParentOrigin( property.Get<Vector3>() );
2347 case Dali::Actor::Property::PARENT_ORIGIN_X:
2349 SetParentOriginX( property.Get<float>() );
2353 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2355 SetParentOriginY( property.Get<float>() );
2359 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2361 SetParentOriginZ( property.Get<float>() );
2365 case Dali::Actor::Property::ANCHOR_POINT:
2367 SetAnchorPoint( property.Get<Vector3>() );
2371 case Dali::Actor::Property::ANCHOR_POINT_X:
2373 SetAnchorPointX( property.Get<float>() );
2377 case Dali::Actor::Property::ANCHOR_POINT_Y:
2379 SetAnchorPointY( property.Get<float>() );
2383 case Dali::Actor::Property::ANCHOR_POINT_Z:
2385 SetAnchorPointZ( property.Get<float>() );
2389 case Dali::Actor::Property::SIZE:
2391 SetSize( property.Get<Vector3>() );
2395 case Dali::Actor::Property::SIZE_WIDTH:
2397 SetWidth( property.Get<float>() );
2401 case Dali::Actor::Property::SIZE_HEIGHT:
2403 SetHeight( property.Get<float>() );
2407 case Dali::Actor::Property::SIZE_DEPTH:
2409 SetDepth( property.Get<float>() );
2413 case Dali::Actor::Property::POSITION:
2415 SetPosition( property.Get<Vector3>() );
2419 case Dali::Actor::Property::POSITION_X:
2421 SetX( property.Get<float>() );
2425 case Dali::Actor::Property::POSITION_Y:
2427 SetY( property.Get<float>() );
2431 case Dali::Actor::Property::POSITION_Z:
2433 SetZ( property.Get<float>() );
2437 case Dali::Actor::Property::ORIENTATION:
2439 SetOrientation( property.Get<Quaternion>() );
2443 case Dali::Actor::Property::SCALE:
2445 SetScale( property.Get<Vector3>() );
2449 case Dali::Actor::Property::SCALE_X:
2451 SetScaleX( property.Get<float>() );
2455 case Dali::Actor::Property::SCALE_Y:
2457 SetScaleY( property.Get<float>() );
2461 case Dali::Actor::Property::SCALE_Z:
2463 SetScaleZ( property.Get<float>() );
2467 case Dali::Actor::Property::VISIBLE:
2469 SetVisible( property.Get<bool>() );
2473 case Dali::Actor::Property::COLOR:
2475 SetColor( property.Get<Vector4>() );
2479 case Dali::Actor::Property::COLOR_RED:
2481 SetColorRed( property.Get<float>() );
2485 case Dali::Actor::Property::COLOR_GREEN:
2487 SetColorGreen( property.Get<float>() );
2491 case Dali::Actor::Property::COLOR_BLUE:
2493 SetColorBlue( property.Get<float>() );
2497 case Dali::Actor::Property::COLOR_ALPHA:
2499 SetOpacity( property.Get<float>() );
2503 case Dali::Actor::Property::NAME:
2505 SetName( property.Get<std::string>() );
2509 case Dali::Actor::Property::SENSITIVE:
2511 SetSensitive( property.Get<bool>() );
2515 case Dali::Actor::Property::LEAVE_REQUIRED:
2517 SetLeaveRequired( property.Get<bool>() );
2521 case Dali::Actor::Property::INHERIT_ORIENTATION:
2523 SetInheritOrientation( property.Get<bool>() );
2527 case Dali::Actor::Property::INHERIT_SCALE:
2529 SetInheritScale( property.Get<bool>() );
2533 case Dali::Actor::Property::COLOR_MODE:
2535 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2539 case Dali::Actor::Property::POSITION_INHERITANCE:
2541 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2545 case Dali::Actor::Property::DRAW_MODE:
2547 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2551 case Dali::Actor::Property::SIZE_MODE:
2553 SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SizeModeTable, SizeModeTableCount ) );
2557 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2559 SetSizeModeFactor( property.Get<Vector3>() );
2565 // this can happen in the case of a non-animatable default property so just do nothing
2571 // TODO: This method needs to be removed
2572 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
2574 OnPropertySet(index, value);
2576 switch ( entry.type )
2578 case Property::BOOLEAN:
2580 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2581 DALI_ASSERT_DEBUG( NULL != property );
2583 // property is being used in a separate thread; queue a message to set the property
2584 SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2589 case Property::FLOAT:
2591 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2592 DALI_ASSERT_DEBUG( NULL != property );
2594 // property is being used in a separate thread; queue a message to set the property
2595 SceneGraph::NodePropertyMessage<float>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2600 case Property::INTEGER:
2602 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2603 DALI_ASSERT_DEBUG( NULL != property );
2605 // property is being used in a separate thread; queue a message to set the property
2606 SceneGraph::NodePropertyMessage<int>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2611 case Property::VECTOR2:
2613 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2614 DALI_ASSERT_DEBUG( NULL != property );
2616 // property is being used in a separate thread; queue a message to set the property
2617 SceneGraph::NodePropertyMessage<Vector2>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2622 case Property::VECTOR3:
2624 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2625 DALI_ASSERT_DEBUG( NULL != property );
2627 // property is being used in a separate thread; queue a message to set the property
2628 SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2633 case Property::VECTOR4:
2635 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2636 DALI_ASSERT_DEBUG( NULL != property );
2638 // property is being used in a separate thread; queue a message to set the property
2639 SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2644 case Property::ROTATION:
2646 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2647 DALI_ASSERT_DEBUG( NULL != property );
2649 // property is being used in a separate thread; queue a message to set the property
2650 SceneGraph::NodePropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2655 case Property::MATRIX:
2657 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2658 DALI_ASSERT_DEBUG( NULL != property );
2660 // property is being used in a separate thread; queue a message to set the property
2661 SceneGraph::NodePropertyMessage<Matrix>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2666 case Property::MATRIX3:
2668 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2669 DALI_ASSERT_DEBUG( NULL != property );
2671 // property is being used in a separate thread; queue a message to set the property
2672 SceneGraph::NodePropertyMessage<Matrix3>::Send( GetEventThreadServices(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2679 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2685 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2687 Property::Value value;
2691 case Dali::Actor::Property::PARENT_ORIGIN:
2693 value = GetCurrentParentOrigin();
2697 case Dali::Actor::Property::PARENT_ORIGIN_X:
2699 value = GetCurrentParentOrigin().x;
2703 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2705 value = GetCurrentParentOrigin().y;
2709 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2711 value = GetCurrentParentOrigin().z;
2715 case Dali::Actor::Property::ANCHOR_POINT:
2717 value = GetCurrentAnchorPoint();
2721 case Dali::Actor::Property::ANCHOR_POINT_X:
2723 value = GetCurrentAnchorPoint().x;
2727 case Dali::Actor::Property::ANCHOR_POINT_Y:
2729 value = GetCurrentAnchorPoint().y;
2733 case Dali::Actor::Property::ANCHOR_POINT_Z:
2735 value = GetCurrentAnchorPoint().z;
2739 case Dali::Actor::Property::SIZE:
2741 value = GetCurrentSize();
2745 case Dali::Actor::Property::SIZE_WIDTH:
2747 value = GetCurrentSize().width;
2751 case Dali::Actor::Property::SIZE_HEIGHT:
2753 value = GetCurrentSize().height;
2757 case Dali::Actor::Property::SIZE_DEPTH:
2759 value = GetCurrentSize().depth;
2763 case Dali::Actor::Property::POSITION:
2765 value = GetCurrentPosition();
2769 case Dali::Actor::Property::POSITION_X:
2771 value = GetCurrentPosition().x;
2775 case Dali::Actor::Property::POSITION_Y:
2777 value = GetCurrentPosition().y;
2781 case Dali::Actor::Property::POSITION_Z:
2783 value = GetCurrentPosition().z;
2787 case Dali::Actor::Property::WORLD_POSITION:
2789 value = GetCurrentWorldPosition();
2793 case Dali::Actor::Property::WORLD_POSITION_X:
2795 value = GetCurrentWorldPosition().x;
2799 case Dali::Actor::Property::WORLD_POSITION_Y:
2801 value = GetCurrentWorldPosition().y;
2805 case Dali::Actor::Property::WORLD_POSITION_Z:
2807 value = GetCurrentWorldPosition().z;
2811 case Dali::Actor::Property::ORIENTATION:
2813 value = GetCurrentOrientation();
2817 case Dali::Actor::Property::WORLD_ORIENTATION:
2819 value = GetCurrentWorldOrientation();
2823 case Dali::Actor::Property::SCALE:
2825 value = GetCurrentScale();
2829 case Dali::Actor::Property::SCALE_X:
2831 value = GetCurrentScale().x;
2835 case Dali::Actor::Property::SCALE_Y:
2837 value = GetCurrentScale().y;
2841 case Dali::Actor::Property::SCALE_Z:
2843 value = GetCurrentScale().z;
2847 case Dali::Actor::Property::WORLD_SCALE:
2849 value = GetCurrentWorldScale();
2853 case Dali::Actor::Property::VISIBLE:
2855 value = IsVisible();
2859 case Dali::Actor::Property::COLOR:
2861 value = GetCurrentColor();
2865 case Dali::Actor::Property::COLOR_RED:
2867 value = GetCurrentColor().r;
2871 case Dali::Actor::Property::COLOR_GREEN:
2873 value = GetCurrentColor().g;
2877 case Dali::Actor::Property::COLOR_BLUE:
2879 value = GetCurrentColor().b;
2883 case Dali::Actor::Property::COLOR_ALPHA:
2885 value = GetCurrentColor().a;
2889 case Dali::Actor::Property::WORLD_COLOR:
2891 value = GetCurrentWorldColor();
2895 case Dali::Actor::Property::WORLD_MATRIX:
2897 value = GetCurrentWorldMatrix();
2901 case Dali::Actor::Property::NAME:
2907 case Dali::Actor::Property::SENSITIVE:
2909 value = IsSensitive();
2913 case Dali::Actor::Property::LEAVE_REQUIRED:
2915 value = GetLeaveRequired();
2919 case Dali::Actor::Property::INHERIT_ORIENTATION:
2921 value = IsOrientationInherited();
2925 case Dali::Actor::Property::INHERIT_SCALE:
2927 value = IsScaleInherited();
2931 case Dali::Actor::Property::COLOR_MODE:
2933 value = Scripting::GetColorMode( GetColorMode() );
2937 case Dali::Actor::Property::POSITION_INHERITANCE:
2939 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2943 case Dali::Actor::Property::DRAW_MODE:
2945 value = Scripting::GetDrawMode( GetDrawMode() );
2949 case Dali::Actor::Property::SIZE_MODE:
2951 value = Scripting::GetLinearEnumerationName< SizeMode >( GetSizeMode(), SizeModeTable, SizeModeTableCount );
2955 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2957 value = GetSizeModeFactor();
2963 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2971 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
2976 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2978 // This method should only return an object connected to the scene-graph
2979 return OnStage() ? mNode : NULL;
2982 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2984 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2986 const PropertyBase* property( NULL );
2988 // This method should only return a property of an object connected to the scene-graph
2994 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
2996 AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
2997 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
2998 property = animatable->GetSceneGraphProperty();
3000 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3002 CustomPropertyMetadata* custom = FindCustomProperty( index );
3003 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3005 property = custom->GetSceneGraphProperty();
3007 else if( NULL != mNode )
3011 case Dali::Actor::Property::SIZE:
3012 property = &mNode->mSize;
3015 case Dali::Actor::Property::SIZE_WIDTH:
3016 property = &mNode->mSize;
3019 case Dali::Actor::Property::SIZE_HEIGHT:
3020 property = &mNode->mSize;
3023 case Dali::Actor::Property::SIZE_DEPTH:
3024 property = &mNode->mSize;
3027 case Dali::Actor::Property::POSITION:
3028 property = &mNode->mPosition;
3031 case Dali::Actor::Property::POSITION_X:
3032 property = &mNode->mPosition;
3035 case Dali::Actor::Property::POSITION_Y:
3036 property = &mNode->mPosition;
3039 case Dali::Actor::Property::POSITION_Z:
3040 property = &mNode->mPosition;
3043 case Dali::Actor::Property::ORIENTATION:
3044 property = &mNode->mOrientation;
3047 case Dali::Actor::Property::SCALE:
3048 property = &mNode->mScale;
3051 case Dali::Actor::Property::SCALE_X:
3052 property = &mNode->mScale;
3055 case Dali::Actor::Property::SCALE_Y:
3056 property = &mNode->mScale;
3059 case Dali::Actor::Property::SCALE_Z:
3060 property = &mNode->mScale;
3063 case Dali::Actor::Property::VISIBLE:
3064 property = &mNode->mVisible;
3067 case Dali::Actor::Property::COLOR:
3068 property = &mNode->mColor;
3071 case Dali::Actor::Property::COLOR_RED:
3072 property = &mNode->mColor;
3075 case Dali::Actor::Property::COLOR_GREEN:
3076 property = &mNode->mColor;
3079 case Dali::Actor::Property::COLOR_BLUE:
3080 property = &mNode->mColor;
3083 case Dali::Actor::Property::COLOR_ALPHA:
3084 property = &mNode->mColor;
3095 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3097 const PropertyInputImpl* property( NULL );
3099 // This method should only return a property of an object connected to the scene-graph
3105 if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
3107 AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
3108 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
3109 property = animatable->GetSceneGraphProperty();
3111 else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3113 CustomPropertyMetadata* custom = FindCustomProperty( index );
3114 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3115 property = custom->GetSceneGraphProperty();
3117 else if( NULL != mNode )
3121 case Dali::Actor::Property::PARENT_ORIGIN:
3122 property = &mNode->mParentOrigin;
3125 case Dali::Actor::Property::PARENT_ORIGIN_X:
3126 property = &mNode->mParentOrigin;
3129 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3130 property = &mNode->mParentOrigin;
3133 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3134 property = &mNode->mParentOrigin;
3137 case Dali::Actor::Property::ANCHOR_POINT:
3138 property = &mNode->mAnchorPoint;
3141 case Dali::Actor::Property::ANCHOR_POINT_X:
3142 property = &mNode->mAnchorPoint;
3145 case Dali::Actor::Property::ANCHOR_POINT_Y:
3146 property = &mNode->mAnchorPoint;
3149 case Dali::Actor::Property::ANCHOR_POINT_Z:
3150 property = &mNode->mAnchorPoint;
3153 case Dali::Actor::Property::SIZE:
3154 property = &mNode->mSize;
3157 case Dali::Actor::Property::SIZE_WIDTH:
3158 property = &mNode->mSize;
3161 case Dali::Actor::Property::SIZE_HEIGHT:
3162 property = &mNode->mSize;
3165 case Dali::Actor::Property::SIZE_DEPTH:
3166 property = &mNode->mSize;
3169 case Dali::Actor::Property::POSITION:
3170 property = &mNode->mPosition;
3173 case Dali::Actor::Property::POSITION_X:
3174 property = &mNode->mPosition;
3177 case Dali::Actor::Property::POSITION_Y:
3178 property = &mNode->mPosition;
3181 case Dali::Actor::Property::POSITION_Z:
3182 property = &mNode->mPosition;
3185 case Dali::Actor::Property::WORLD_POSITION:
3186 property = &mNode->mWorldPosition;
3189 case Dali::Actor::Property::WORLD_POSITION_X:
3190 property = &mNode->mWorldPosition;
3193 case Dali::Actor::Property::WORLD_POSITION_Y:
3194 property = &mNode->mWorldPosition;
3197 case Dali::Actor::Property::WORLD_POSITION_Z:
3198 property = &mNode->mWorldPosition;
3201 case Dali::Actor::Property::ORIENTATION:
3202 property = &mNode->mOrientation;
3205 case Dali::Actor::Property::WORLD_ORIENTATION:
3206 property = &mNode->mWorldOrientation;
3209 case Dali::Actor::Property::SCALE:
3210 property = &mNode->mScale;
3213 case Dali::Actor::Property::SCALE_X:
3214 property = &mNode->mScale;
3217 case Dali::Actor::Property::SCALE_Y:
3218 property = &mNode->mScale;
3221 case Dali::Actor::Property::SCALE_Z:
3222 property = &mNode->mScale;
3225 case Dali::Actor::Property::WORLD_SCALE:
3226 property = &mNode->mWorldScale;
3229 case Dali::Actor::Property::VISIBLE:
3230 property = &mNode->mVisible;
3233 case Dali::Actor::Property::COLOR:
3234 property = &mNode->mColor;
3237 case Dali::Actor::Property::COLOR_RED:
3238 property = &mNode->mColor;
3241 case Dali::Actor::Property::COLOR_GREEN:
3242 property = &mNode->mColor;
3245 case Dali::Actor::Property::COLOR_BLUE:
3246 property = &mNode->mColor;
3249 case Dali::Actor::Property::COLOR_ALPHA:
3250 property = &mNode->mColor;
3253 case Dali::Actor::Property::WORLD_COLOR:
3254 property = &mNode->mWorldColor;
3257 case Dali::Actor::Property::WORLD_MATRIX:
3258 property = &mNode->mWorldMatrix;
3269 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3271 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3275 case Dali::Actor::Property::PARENT_ORIGIN_X:
3276 case Dali::Actor::Property::ANCHOR_POINT_X:
3277 case Dali::Actor::Property::SIZE_WIDTH:
3278 case Dali::Actor::Property::POSITION_X:
3279 case Dali::Actor::Property::WORLD_POSITION_X:
3280 case Dali::Actor::Property::SCALE_X:
3281 case Dali::Actor::Property::COLOR_RED:
3287 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3288 case Dali::Actor::Property::ANCHOR_POINT_Y:
3289 case Dali::Actor::Property::SIZE_HEIGHT:
3290 case Dali::Actor::Property::POSITION_Y:
3291 case Dali::Actor::Property::WORLD_POSITION_Y:
3292 case Dali::Actor::Property::SCALE_Y:
3293 case Dali::Actor::Property::COLOR_GREEN:
3299 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3300 case Dali::Actor::Property::ANCHOR_POINT_Z:
3301 case Dali::Actor::Property::SIZE_DEPTH:
3302 case Dali::Actor::Property::POSITION_Z:
3303 case Dali::Actor::Property::WORLD_POSITION_Z:
3304 case Dali::Actor::Property::SCALE_Z:
3305 case Dali::Actor::Property::COLOR_BLUE:
3311 case Dali::Actor::Property::COLOR_ALPHA:
3324 return componentIndex;
3327 void Actor::SetParent(Actor* parent, int index)
3331 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3335 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3338 // Instruct each actor to create a corresponding node in the scene graph
3339 ConnectToStage( index );
3342 else // parent being set to NULL
3344 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3348 if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
3351 DALI_ASSERT_ALWAYS(mNode != NULL);
3355 // Disconnect the Node & its children from the scene-graph.
3356 DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
3359 // Instruct each actor to discard pointers to the scene-graph
3360 DisconnectFromStage();
3365 SceneGraph::Node* Actor::CreateNode() const
3370 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
3373 Actor* actor = dynamic_cast<Actor*>( object );
3377 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3379 actor->SetVisible(true);
3382 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3384 actor->SetVisible(false);
3392 } // namespace Internal