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-helper.h>
40 #include <dali/internal/event/common/stage-impl.h>
41 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
42 #include <dali/internal/event/animation/constraint-impl.h>
43 #include <dali/internal/event/common/projection.h>
44 #include <dali/internal/update/common/animatable-property.h>
45 #include <dali/internal/update/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
59 using Dali::Internal::SceneGraph::Node;
60 using Dali::Internal::SceneGraph::AnimatableProperty;
61 using Dali::Internal::SceneGraph::PropertyBase;
69 unsigned int Actor::mActorCounter = 0;
70 ActorContainer Actor::mNullChildren;
72 #ifdef DYNAMICS_SUPPORT
74 // Encapsulate actor related dynamics data
77 DynamicsData( Actor* slotOwner )
78 : slotDelegate( slotOwner )
82 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
83 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
86 JointContainer joints;
87 ReferencedJointContainer referencedJoints;
89 SlotDelegate< Actor > slotDelegate;
92 #endif // DYNAMICS_SUPPORT
94 namespace // unnamed namespace
100 * We want to discourage the use of property strings (minimize string comparisons),
101 * particularly for the default properties.
102 * Name Type writable animatable constraint-input enum for index-checking
104 DALI_PROPERTY_TABLE_BEGIN
105 DALI_PROPERTY( "parent-origin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
106 DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
107 DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
108 DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
109 DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
110 DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
111 DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
112 DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
113 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
114 DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
115 DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
116 DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
117 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
118 DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
119 DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
120 DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
121 DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
122 DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
123 DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
124 DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
125 DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
126 DALI_PROPERTY( "world-orientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
127 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
128 DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
129 DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
130 DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
131 DALI_PROPERTY( "world-scale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
132 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
133 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
134 DALI_PROPERTY( "color-red", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
135 DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
136 DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
137 DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
138 DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
139 DALI_PROPERTY( "world-matrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
140 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
141 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
142 DALI_PROPERTY( "leave-required", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
143 DALI_PROPERTY( "inherit-orientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
144 DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
145 DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
146 DALI_PROPERTY( "position-inheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
147 DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
148 DALI_PROPERTY( "size-mode", STRING, true, false, false, Dali::Actor::Property::SIZE_MODE )
149 DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
150 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
154 const char* const SIGNAL_TOUCHED = "touched";
155 const char* const SIGNAL_HOVERED = "hovered";
156 const char* const SIGNAL_MOUSE_WHEEL_EVENT = "mouse-wheel-event";
157 const char* const SIGNAL_ON_STAGE = "on-stage";
158 const char* const SIGNAL_OFF_STAGE = "off-stage";
162 const char* const ACTION_SHOW = "show";
163 const char* const ACTION_HIDE = "hide";
165 // Enumeration to / from string conversion tables
167 DALI_ENUM_TO_STRING_TABLE_BEGIN( SizeMode )
168 DALI_ENUM_TO_STRING( USE_OWN_SIZE )
169 DALI_ENUM_TO_STRING( SIZE_EQUAL_TO_PARENT )
170 DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT )
171 DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT )
172 DALI_ENUM_TO_STRING_TABLE_END( SizeMode )
174 BaseHandle CreateActor()
176 return Dali::Actor::New();
179 TypeRegistration mType( typeid( Dali::Actor ), typeid( Dali::Handle ), CreateActor );
181 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
182 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
183 SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
184 SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
186 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
187 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
189 } // unnamed namespace
191 ActorPtr Actor::New()
193 ActorPtr actor( new Actor( BASIC ) );
195 // Second-phase construction
201 const std::string& Actor::GetName() const
206 void Actor::SetName(const std::string& name)
212 // ATTENTION: string for debug purposes is not thread safe.
213 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
217 unsigned int Actor::GetId() const
222 void Actor::Attach( ActorAttachment& attachment )
224 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
228 attachment.Connect();
231 mAttachment = ActorAttachmentPtr(&attachment);
234 ActorAttachmentPtr Actor::GetAttachment()
239 bool Actor::OnStage() const
244 Dali::Layer Actor::GetLayer()
248 // Short-circuit for Layer derived actors
251 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
254 // Find the immediate Layer parent
255 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
257 if( parent->IsLayer() )
259 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
266 void Actor::Add(Actor& child)
268 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
269 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
273 mChildren = new ActorContainer;
276 Actor* const oldParent( child.mParent );
278 // child might already be ours
279 if( this != oldParent )
281 // if we already have parent, unparent us first
284 oldParent->Remove( child ); // This causes OnChildRemove callback
287 // Guard against Add() during previous OnChildRemove callback
288 if ( !child.mParent )
290 // Do this first, since user callbacks from within SetParent() may need to remove child
291 mChildren->push_back(Dali::Actor(&child));
293 // SetParent asserts that child can be added
294 child.SetParent(this);
296 // Notification for derived classes
302 void Actor::Insert(unsigned int index, Actor& child)
304 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
305 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
309 mChildren = new ActorContainer;
312 Actor* const oldParent( child.mParent );
314 // since an explicit position has been given, always insert, even if already a child
317 oldParent->Remove( child ); // This causes OnChildRemove callback
320 // Guard against Add() during previous OnChildRemove callback
321 if ( !child.mParent )
323 // Do this first, since user callbacks from within SetParent() may need to remove child
324 if (index < GetChildCount())
326 ActorIter it = mChildren->begin();
327 std::advance(it, index);
328 mChildren->insert(it, Dali::Actor(&child));
332 mChildren->push_back(Dali::Actor(&child));
334 // SetParent asserts that child can be added
335 child.SetParent(this, index);
337 // Notification for derived classes
342 void Actor::Remove(Actor& child)
344 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
354 // Find the child in mChildren, and unparent it
355 ActorIter end = mChildren->end();
356 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
358 Actor& actor = GetImplementation(*iter);
360 if( &actor == &child )
362 // Keep handle for OnChildRemove notification
363 removed = Dali::Actor( &actor );
365 // Do this first, since user callbacks from within SetParent() may need to add the child
366 mChildren->erase(iter);
368 DALI_ASSERT_DEBUG( actor.GetParent() == this );
369 actor.SetParent( NULL );
377 // Notification for derived classes
378 OnChildRemove( GetImplementation(removed) );
382 void Actor::Unparent()
386 mParent->Remove( *this );
390 unsigned int Actor::GetChildCount() const
392 return ( NULL != mChildren ) ? mChildren->size() : 0;
395 Dali::Actor Actor::GetChildAt(unsigned int index) const
397 DALI_ASSERT_ALWAYS( index < GetChildCount() );
399 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
402 ActorContainer Actor::GetChildren()
404 if( NULL != mChildren )
409 // return copy of mNullChildren
410 return mNullChildren;
413 const ActorContainer& Actor::GetChildren() const
415 if( NULL != mChildren )
420 // return const reference to mNullChildren
421 return mNullChildren;
424 ActorPtr Actor::FindChildByName(const std::string& actorName)
427 if (actorName == mName)
433 ActorIter end = mChildren->end();
434 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
436 child = GetImplementation(*iter).FindChildByName(actorName);
447 ActorPtr Actor::FindChildById(const unsigned int id)
456 ActorIter end = mChildren->end();
457 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
459 child = GetImplementation(*iter).FindChildById(id);
470 void Actor::SetParentOrigin( const Vector3& origin )
474 // mNode is being used in a separate thread; queue a message to set the value & base value
475 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
478 // Cache for event-thread access
481 // not allocated, check if different from default
482 if( ParentOrigin::DEFAULT != origin )
484 mParentOrigin = new Vector3( origin );
489 // check if different from current costs more than just set
490 *mParentOrigin = origin;
494 void Actor::SetParentOriginX( float x )
496 const Vector3& current = GetCurrentParentOrigin();
498 SetParentOrigin( Vector3( x, current.y, current.z ) );
501 void Actor::SetParentOriginY( float y )
503 const Vector3& current = GetCurrentParentOrigin();
505 SetParentOrigin( Vector3( current.x, y, current.z ) );
508 void Actor::SetParentOriginZ( float z )
510 const Vector3& current = GetCurrentParentOrigin();
512 SetParentOrigin( Vector3( current.x, current.y, z ) );
515 const Vector3& Actor::GetCurrentParentOrigin() const
517 // Cached for event-thread access
518 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
521 void Actor::SetAnchorPoint(const Vector3& anchor)
525 // mNode is being used in a separate thread; queue a message to set the value & base value
526 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
529 // Cache for event-thread access
532 // not allocated, check if different from default
533 if( AnchorPoint::DEFAULT != anchor )
535 mAnchorPoint = new Vector3( anchor );
540 // check if different from current costs more than just set
541 *mAnchorPoint = anchor;
545 void Actor::SetAnchorPointX( float x )
547 const Vector3& current = GetCurrentAnchorPoint();
549 SetAnchorPoint( Vector3( x, current.y, current.z ) );
552 void Actor::SetAnchorPointY( float y )
554 const Vector3& current = GetCurrentAnchorPoint();
556 SetAnchorPoint( Vector3( current.x, y, current.z ) );
559 void Actor::SetAnchorPointZ( float z )
561 const Vector3& current = GetCurrentAnchorPoint();
563 SetAnchorPoint( Vector3( current.x, current.y, z ) );
566 const Vector3& Actor::GetCurrentAnchorPoint() const
568 // Cached for event-thread access
569 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
572 void Actor::SetPosition(float x, float y)
574 SetPosition(Vector3(x, y, 0.0f));
577 void Actor::SetPosition(float x, float y, float z)
579 SetPosition(Vector3(x, y, z));
582 void Actor::SetPosition(const Vector3& position)
586 // mNode is being used in a separate thread; queue a message to set the value & base value
587 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
591 void Actor::SetX(float x)
595 // mNode is being used in a separate thread; queue a message to set the value & base value
596 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
600 void Actor::SetY(float y)
604 // mNode is being used in a separate thread; queue a message to set the value & base value
605 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
609 void Actor::SetZ(float z)
613 // mNode is being used in a separate thread; queue a message to set the value & base value
614 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
618 void Actor::TranslateBy(const Vector3& distance)
622 // mNode is being used in a separate thread; queue a message to set the value & base value
623 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
627 const Vector3& Actor::GetCurrentPosition() const
631 // mNode is being used in a separate thread; copy the value from the previous update
632 return mNode->GetPosition(mStage->GetEventBufferIndex());
635 return Vector3::ZERO;
638 const Vector3& Actor::GetCurrentWorldPosition() const
642 // mNode is being used in a separate thread; copy the value from the previous update
643 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
646 return Vector3::ZERO;
649 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
651 // this flag is not animatable so keep the value
652 mPositionInheritanceMode = mode;
655 // mNode is being used in a separate thread; queue a message to set the value
656 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
660 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
662 // Cached for event-thread access
663 return mPositionInheritanceMode;
666 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
668 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
669 normalizedAxis.Normalize();
671 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
673 SetOrientation(orientation);
676 void Actor::SetOrientation(const Quaternion& orientation)
680 // mNode is being used in a separate thread; queue a message to set the value & base value
681 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::Bake, orientation );
685 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
689 // mNode is being used in a separate thread; queue a message to set the value & base value
690 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
694 void Actor::RotateBy(const Quaternion& relativeRotation)
698 // mNode is being used in a separate thread; queue a message to set the value & base value
699 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mOrientation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
703 const Quaternion& Actor::GetCurrentOrientation() const
707 // mNode is being used in a separate thread; copy the value from the previous update
708 return mNode->GetOrientation(mStage->GetEventBufferIndex());
711 return Quaternion::IDENTITY;
714 const Quaternion& Actor::GetCurrentWorldOrientation() const
718 // mNode is being used in a separate thread; copy the value from the previous update
719 return mNode->GetWorldOrientation( mStage->GetEventBufferIndex() );
722 return Quaternion::IDENTITY;
725 void Actor::SetScale(float scale)
727 SetScale(Vector3(scale, scale, scale));
730 void Actor::SetScale(float x, float y, float z)
732 SetScale(Vector3(x, y, z));
735 void Actor::SetScale(const Vector3& scale)
739 // mNode is being used in a separate thread; queue a message to set the value & base value
740 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
744 void Actor::SetScaleX( float x )
748 // mNode is being used in a separate thread; queue a message to set the value & base value
749 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
753 void Actor::SetScaleY( float y )
757 // mNode is being used in a separate thread; queue a message to set the value & base value
758 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
762 void Actor::SetScaleZ( float z )
766 // mNode is being used in a separate thread; queue a message to set the value & base value
767 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
771 void Actor::SetInitialVolume(const Vector3& volume)
775 // mNode is being used in a separate thread; queue a message to set the value
776 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
780 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
784 // mNode is being used in a separate thread; queue a message to set the value
785 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
789 bool Actor::GetTransmitGeometryScaling() const
793 // mNode is being used in a separate thread; copy the value from the previous update
794 return mNode->GetTransmitGeometryScaling();
800 void Actor::ScaleBy(const Vector3& relativeScale)
804 // mNode is being used in a separate thread; queue a message to set the value & base value
805 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
809 const Vector3& Actor::GetCurrentScale() const
813 // mNode is being used in a separate thread; copy the value from the previous update
814 return mNode->GetScale(mStage->GetEventBufferIndex());
820 const Vector3& Actor::GetCurrentWorldScale() const
824 // mNode is being used in a separate thread; copy the value from the previous update
825 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
831 void Actor::SetInheritScale( bool inherit )
833 // non animateable so keep local copy
834 mInheritScale = inherit;
837 // mNode is being used in a separate thread; queue a message to set the value
838 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
842 bool Actor::IsScaleInherited() const
844 return mInheritScale;
847 Matrix Actor::GetCurrentWorldMatrix() const
851 // World matrix is no longer updated unless there is something observing the node.
852 // Need to calculate it from node's world position, orientation and scale:
853 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
854 Matrix worldMatrix(false);
855 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
856 mNode->GetWorldOrientation( updateBufferIndex ),
857 mNode->GetWorldPosition( updateBufferIndex ) );
861 return Matrix::IDENTITY;
864 void Actor::SetVisible(bool visible)
868 // mNode is being used in a separate thread; queue a message to set the value & base value
869 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
873 bool Actor::IsVisible() const
877 // mNode is being used in a separate thread; copy the value from the previous update
878 return mNode->IsVisible( mStage->GetEventBufferIndex() );
884 void Actor::SetOpacity(float opacity)
888 // mNode is being used in a separate thread; queue a message to set the value & base value
889 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
893 float Actor::GetCurrentOpacity() const
897 // mNode is being used in a separate thread; copy the value from the previous update
898 return mNode->GetOpacity(mStage->GetEventBufferIndex());
904 const Vector4& Actor::GetCurrentWorldColor() const
908 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
914 void Actor::SetColor(const Vector4& color)
918 // mNode is being used in a separate thread; queue a message to set the value & base value
919 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
923 void Actor::SetColorRed( float red )
927 // mNode is being used in a separate thread; queue a message to set the value & base value
928 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
932 void Actor::SetColorGreen( float green )
936 // mNode is being used in a separate thread; queue a message to set the value & base value
937 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
941 void Actor::SetColorBlue( float blue )
945 // mNode is being used in a separate thread; queue a message to set the value & base value
946 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
950 const Vector4& Actor::GetCurrentColor() const
954 // mNode is being used in a separate thread; copy the value from the previous update
955 return mNode->GetColor(mStage->GetEventBufferIndex());
961 void Actor::SetInheritOrientation(bool inherit)
963 // non animateable so keep local copy
964 mInheritOrientation = inherit;
967 // mNode is being used in a separate thread; queue a message to set the value
968 SetInheritOrientationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
972 bool Actor::IsOrientationInherited() const
974 return mInheritOrientation;
977 void Actor::SetSizeMode(SizeMode mode)
979 // non animateable so keep local copy
983 // mNode is being used in a separate thread; queue a message to set the value
984 SetSizeModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
988 void Actor::SetSizeModeFactor(const Vector3& factor)
990 // non animateable so keep local copy
991 mSizeModeFactor = factor;
994 // mNode is being used in a separate thread; queue a message to set the value
995 SetSizeModeFactorMessage( mStage->GetUpdateInterface(), *mNode, factor );
999 SizeMode Actor::GetSizeMode() const
1004 const Vector3& Actor::GetSizeModeFactor() const
1006 return mSizeModeFactor;
1009 void Actor::SetColorMode(ColorMode colorMode)
1011 // non animateable so keep local copy
1012 mColorMode = colorMode;
1015 // mNode is being used in a separate thread; queue a message to set the value
1016 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1020 ColorMode Actor::GetColorMode() const
1022 // we have cached copy
1026 void Actor::SetSize(float width, float height)
1028 SetSize( Vector2( width, height ) );
1031 void Actor::SetSize(float width, float height, float depth)
1033 SetSize( Vector3( width, height, depth ) );
1036 void Actor::SetSize(const Vector2& size)
1038 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1041 float Actor::CalculateSizeZ( const Vector2& size ) const
1043 return std::min( size.width, size.height );
1046 void Actor::SetSize(const Vector3& size)
1052 // mNode is being used in a separate thread; queue a message to set the value & base value
1053 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1055 // Notification for derived classes
1060 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1064 // Notify deriving classes
1065 OnSizeAnimation( animation, targetSize );
1068 void Actor::SetWidth( float width )
1072 // mNode is being used in a separate thread; queue a message to set the value & base value
1073 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1077 void Actor::SetHeight( float height )
1081 // mNode is being used in a separate thread; queue a message to set the value & base value
1082 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1086 void Actor::SetDepth( float depth )
1090 // mNode is being used in a separate thread; queue a message to set the value & base value
1091 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1095 const Vector3& Actor::GetSize() const
1100 const Vector3& Actor::GetCurrentSize() const
1104 // mNode is being used in a separate thread; copy the value from the previous update
1105 return mNode->GetSize( mStage->GetEventBufferIndex() );
1108 return Vector3::ZERO;
1111 Vector3 Actor::GetNaturalSize() const
1113 // It is up to deriving classes to return the appropriate natural size
1114 return Vector3( 0.0f, 0.0f, 0.0f );
1118 #ifdef DYNAMICS_SUPPORT
1120 //--------------- Dynamics ---------------
1122 void Actor::DisableDynamics()
1124 if( NULL != mDynamicsData )
1126 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1128 // ensure dynamics object are disconnected from scene
1129 DisconnectDynamics();
1131 // delete joint owned by this actor
1132 while( !mDynamicsData->joints.empty() )
1134 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1137 // delete other joints referencing this actor
1138 while( !mDynamicsData->referencedJoints.empty() )
1140 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1141 ActorPtr jointOwner( joint->GetActor( true ) );
1144 jointOwner->RemoveDynamicsJoint( joint );
1148 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1151 // delete the DynamicsBody object
1152 mDynamicsData->body.Reset();
1154 // Discard Dynamics data structure
1155 delete mDynamicsData;
1156 mDynamicsData = NULL;
1160 DynamicsBodyPtr Actor::GetDynamicsBody() const
1162 DynamicsBodyPtr body;
1164 if( NULL != mDynamicsData )
1166 body = mDynamicsData->body;
1172 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1174 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1176 if( NULL == mDynamicsData )
1178 mDynamicsData = new DynamicsData( this );
1181 if( !mDynamicsData->body )
1183 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1187 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1190 if( mParent == world->GetRootActor().Get() )
1192 mDynamicsData->body->Connect(*mStage);
1198 return mDynamicsData->body;
1201 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1203 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1204 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1207 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1209 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1210 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1212 DynamicsJointPtr joint;
1214 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1218 if( NULL != mDynamicsData )
1220 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1222 if( mDynamicsData->joints.end() != it )
1224 // use existing joint
1230 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1231 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1235 bodyA = EnableDynamics( new DynamicsBodyConfig );
1240 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1243 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1244 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1246 if( OnStage() && attachedActor->OnStage() )
1248 joint->Connect(*mStage);
1251 attachedActor->ReferenceJoint( joint );
1253 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1254 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1261 const int Actor::GetNumberOfJoints() const
1263 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1266 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1268 DynamicsJointPtr joint;
1270 if( NULL != mDynamicsData )
1272 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1274 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1276 for( int i = 0; i < index; ++i )
1288 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1290 DynamicsJointPtr joint;
1292 if( NULL != mDynamicsData )
1294 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1296 if( mDynamicsData->joints.end() != it )
1298 // use existing joint
1306 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1308 if( NULL != mDynamicsData )
1310 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1311 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1313 for( ; it != endIt; ++it )
1315 if( it->second == joint.Get() )
1317 ActorPtr attachedActor( it->first );
1319 if( OnStage() && attachedActor && attachedActor->OnStage() )
1321 joint->Disconnect(*mStage);
1326 attachedActor->ReleaseJoint( joint );
1327 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1328 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1331 mDynamicsData->joints.erase(it);
1338 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1340 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1342 if( NULL != mDynamicsData )
1344 mDynamicsData->referencedJoints.push_back(joint);
1348 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1350 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1352 if( NULL != mDynamicsData )
1354 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1356 if( it != mDynamicsData->referencedJoints.end() )
1358 mDynamicsData->referencedJoints.erase( it );
1363 void Actor::SetDynamicsRoot(bool flag)
1365 if( mIsDynamicsRoot != flag )
1367 mIsDynamicsRoot = flag;
1369 if( OnStage() && mChildren )
1371 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1372 ActorIter end = mChildren->end();
1373 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1375 Actor& child = GetImplementation(*iter);
1377 if( child.GetDynamicsBody() )
1379 if( mIsDynamicsRoot )
1381 child.ConnectDynamics();
1385 child.DisconnectDynamics();
1393 bool Actor::IsDynamicsRoot() const
1395 return mIsDynamicsRoot;
1398 void Actor::AttachedActorOnStage( Dali::Actor actor )
1400 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1404 ActorPtr attachedActor( &GetImplementation(actor) );
1406 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1407 if( NULL != mDynamicsData )
1409 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1410 if( mDynamicsData->joints.end() != it )
1412 DynamicsJointPtr joint( it->second );
1413 joint->Connect(*mStage);
1419 void Actor::AttachedActorOffStage( Dali::Actor actor )
1421 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1425 ActorPtr attachedActor( &GetImplementation(actor) );
1427 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1428 if( NULL != mDynamicsData )
1430 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1431 if( mDynamicsData->joints.end() != it )
1433 DynamicsJointPtr joint( it->second );
1434 joint->Disconnect(*mStage);
1440 void Actor::ConnectDynamics()
1442 if( NULL != mDynamicsData && mDynamicsData->body )
1444 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1446 mDynamicsData->body->Connect(*mStage);
1448 // Connect all joints where attachedActor is also on stage
1449 if( !mDynamicsData->joints.empty() )
1451 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1452 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1454 for( ; it != endIt; ++it )
1456 Actor* attachedActor( it->first );
1457 if( NULL != attachedActor && attachedActor->OnStage() )
1459 DynamicsJointPtr joint( it->second );
1461 joint->Connect(*mStage);
1469 void Actor::DisconnectDynamics()
1471 if( NULL != mDynamicsData && mDynamicsData->body )
1475 mDynamicsData->body->Disconnect(*mStage);
1477 // Disconnect all joints
1478 if( !mDynamicsData->joints.empty() )
1480 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1481 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1483 for( ; it != endIt; ++it )
1485 DynamicsJointPtr joint( it->second );
1487 joint->Disconnect(*mStage);
1494 #endif // DYNAMICS_SUPPORT
1496 void Actor::SetOverlay(bool enable)
1498 // Setting STENCIL will override OVERLAY
1499 if( DrawMode::STENCIL != mDrawMode )
1501 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1505 bool Actor::IsOverlay() const
1507 return ( DrawMode::OVERLAY == mDrawMode );
1510 void Actor::SetDrawMode( DrawMode::Type drawMode )
1512 // this flag is not animatable so keep the value
1513 mDrawMode = drawMode;
1516 // mNode is being used in a separate thread; queue a message to set the value
1517 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1521 DrawMode::Type Actor::GetDrawMode() const
1526 bool Actor::ScreenToLocal( float& localX,
1529 float screenY ) const
1531 // only valid when on-stage
1534 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1536 Vector2 converted( screenX, screenY );
1538 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1539 const int taskCount = taskList.GetTaskCount();
1540 for( int i = taskCount - 1; i >= 0; --i )
1542 Dali::RenderTask task = taskList.GetTask( i );
1543 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1545 // found a task where this conversion was ok so return
1553 bool Actor::ScreenToLocal( RenderTask& renderTask,
1557 float screenY ) const
1559 bool retval = false;
1560 // only valid when on-stage
1563 CameraActor* camera = renderTask.GetCameraActor();
1567 renderTask.GetViewport( viewport );
1569 // need to translate coordinates to render tasks coordinate space
1570 Vector2 converted( screenX, screenY );
1571 if( renderTask.TranslateCoordinates( converted ) )
1573 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1580 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1581 const Matrix& projectionMatrix,
1582 const Viewport& viewport,
1586 float screenY ) const
1588 // Early-out if mNode is NULL
1594 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1596 // Calculate the ModelView matrix
1597 Matrix modelView(false/*don't init*/);
1598 // need to use the components as world matrix is only updated for actors that need it
1599 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldOrientation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1600 Matrix::Multiply(modelView, modelView, viewMatrix);
1602 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1603 Matrix invertedMvp(false/*don't init*/);
1604 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1605 bool success = invertedMvp.Invert();
1607 // Convert to GL coordinates
1608 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1613 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1620 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1626 if (XyPlaneIntersect(nearPos, farPos, local))
1628 Vector3 size = GetCurrentSize();
1629 localX = local.x + size.x * 0.5f;
1630 localY = local.y + size.y * 0.5f;
1641 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1644 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1646 Mathematical Formulation
1648 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1650 ( p - c ) dot ( p - c ) = r^2
1652 Given a ray with a point of origin 'o', and a direction vector 'd':
1654 ray(t) = o + td, t >= 0
1656 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1658 (o + td - c ) dot ( o + td - c ) = r^2
1660 To solve for t we first expand the above into a more recognisable quadratic equation form
1662 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1671 B = 2( o - c ) dot d
1672 C = ( o - c ) dot ( o - c ) - r^2
1674 which can be solved using a standard quadratic formula.
1676 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1678 Practical Simplification
1680 In a renderer, we often differentiate between world space and object space. In the object space
1681 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1682 into object space, the mathematical solution presented above can be simplified significantly.
1684 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1688 and we can find the t at which the (transformed) ray intersects the sphere by
1690 ( o + td ) dot ( o + td ) = r^2
1692 According to the reasoning above, we expand the above quadratic equation into the general form
1696 which now has coefficients:
1703 // Early out if mNode is NULL
1709 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1711 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1712 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1713 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1714 rayOrigin.y - translation.y,
1715 rayOrigin.z - translation.z);
1717 // Compute the radius is not needed, square radius it's enough.
1718 const Vector3& size( mNode->GetSize( bufferIndex ) );
1720 // Scale the sphere.
1721 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1723 const float width = size.width * scale.width;
1724 const float height = size.height * scale.height;
1726 float squareSphereRadius = 0.5f * ( width * width + height * height );
1728 float a = rayDir.Dot( rayDir ); // a
1729 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1730 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1732 return ( b2*b2 - a*c ) >= 0.f;
1735 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1742 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1744 // Transforms the ray to the local reference system.
1746 // Calculate the inverse of Model matrix
1747 Matrix invModelMatrix(false/*don't init*/);
1748 // need to use the components as world matrix is only updated for actors that need it
1749 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldOrientation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1751 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1752 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1754 // Test with the actor's XY plane (Normal = 0 0 1 1).
1756 float a = -rayOriginLocal.z;
1757 float b = rayDirLocal.z;
1759 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1761 // Ray travels distance * rayDirLocal to intersect with plane.
1764 const Vector3& size = mNode->GetSize( bufferIndex );
1766 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1767 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1769 // Test with the actor's geometry.
1770 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1777 void Actor::SetLeaveRequired(bool required)
1779 mLeaveRequired = required;
1782 bool Actor::GetLeaveRequired() const
1784 return mLeaveRequired;
1787 void Actor::SetKeyboardFocusable( bool focusable )
1789 mKeyboardFocusable = focusable;
1792 bool Actor::IsKeyboardFocusable() const
1794 return mKeyboardFocusable;
1797 bool Actor::GetTouchRequired() const
1799 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1802 bool Actor::GetHoverRequired() const
1804 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1807 bool Actor::GetMouseWheelEventRequired() const
1809 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1812 bool Actor::IsHittable() const
1814 return IsSensitive() &&
1816 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1820 ActorGestureData& Actor::GetGestureData()
1822 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1823 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1824 if ( NULL == mGestureData )
1826 mGestureData = new ActorGestureData;
1828 return *mGestureData;
1831 bool Actor::IsGestureRequred( Gesture::Type type ) const
1833 return mGestureData && mGestureData->IsGestureRequred( type );
1836 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1838 bool consumed = false;
1840 if ( !mTouchedSignal.Empty() )
1842 Dali::Actor handle( this );
1843 consumed = mTouchedSignal.Emit( handle, event );
1848 // Notification for derived classes
1849 consumed = OnTouchEvent( event );
1855 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1857 bool consumed = false;
1859 if ( !mHoveredSignal.Empty() )
1861 Dali::Actor handle( this );
1862 consumed = mHoveredSignal.Emit( handle, event );
1867 // Notification for derived classes
1868 consumed = OnHoverEvent( event );
1874 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1876 bool consumed = false;
1878 if ( !mMouseWheelEventSignal.Empty() )
1880 Dali::Actor handle( this );
1881 consumed = mMouseWheelEventSignal.Emit( handle, event );
1886 // Notification for derived classes
1887 consumed = OnMouseWheelEvent(event);
1893 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1895 return mTouchedSignal;
1898 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1900 return mHoveredSignal;
1903 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1905 return mMouseWheelEventSignal;
1908 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1910 return mOnStageSignal;
1913 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1915 return mOffStageSignal;
1918 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1920 bool connected( true );
1921 Actor* actor = dynamic_cast<Actor*>( object );
1923 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
1925 actor->TouchedSignal().Connect( tracker, functor );
1927 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
1929 actor->HoveredSignal().Connect( tracker, functor );
1931 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
1933 actor->MouseWheelEventSignal().Connect( tracker, functor );
1935 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
1937 actor->OnStageSignal().Connect( tracker, functor );
1939 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
1941 actor->OffStageSignal().Connect( tracker, functor );
1945 // signalName does not match any signal
1952 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()
1991 mStage = Stage::GetCurrent();
1992 DALI_ASSERT_ALWAYS( mStage && "Stage doesn't exist" );
1995 SceneGraph::Node* node = CreateNode();
1997 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
1998 mNode = node; // Keep raw-pointer to Node
2002 mStage->RegisterObject( this );
2007 // Remove mParent pointers from children even if we're destroying core,
2008 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2011 ActorConstIter endIter = mChildren->end();
2012 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2014 Actor& actor = GetImplementation( *iter );
2015 actor.SetParent( NULL );
2020 // Guard to allow handle destruction after Core has been destroyed
2021 if( Stage::IsInstalled() )
2025 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2026 mNode = NULL; // Node is about to be destroyed
2029 mStage->UnregisterObject( this );
2032 #ifdef DYNAMICS_SUPPORT
2034 delete mDynamicsData;
2037 // Cleanup optional gesture data
2038 delete mGestureData;
2040 // Cleanup optional parent origin and anchor
2041 delete mParentOrigin;
2042 delete mAnchorPoint;
2045 void Actor::ConnectToStage( int index )
2047 // This container is used instead of walking the Actor hierachy.
2048 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2049 ActorContainer connectionList;
2051 // This stage is atomic i.e. not interrupted by user callbacks
2052 RecursiveConnectToStage( connectionList, index );
2054 // Notify applications about the newly connected actors.
2055 const ActorIter endIter = connectionList.end();
2056 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2058 Actor& actor = GetImplementation(*iter);
2059 actor.NotifyStageConnection();
2063 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2065 DALI_ASSERT_ALWAYS( !OnStage() );
2069 ConnectToSceneGraph(index);
2071 // Notification for internal derived classes
2072 OnStageConnectionInternal();
2074 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2075 connectionList.push_back( Dali::Actor(this) );
2077 // Recursively connect children
2080 ActorConstIter endIter = mChildren->end();
2081 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2083 Actor& actor = GetImplementation( *iter );
2084 actor.RecursiveConnectToStage( connectionList );
2090 * This method is called when the Actor is connected to the Stage.
2091 * The parent must have added its Node to the scene-graph.
2092 * The child must connect its Node to the parent's Node.
2093 * This is resursive; the child calls ConnectToStage() for its children.
2095 void Actor::ConnectToSceneGraph(int index)
2097 DALI_ASSERT_DEBUG( mNode != NULL);
2098 DALI_ASSERT_DEBUG( mParent != NULL);
2099 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2103 // Reparent Node in next Update
2104 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2107 // Notify attachment
2110 mAttachment->Connect();
2113 #ifdef DYNAMICS_SUPPORT
2115 if( NULL != mDynamicsData )
2121 // Notification for Object::Observers
2125 void Actor::NotifyStageConnection()
2127 // Actors can be removed (in a callback), before the on-stage stage is reported.
2128 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2129 if ( OnStage() && !mOnStageSignalled )
2131 // Notification for external (CustomActor) derived classes
2132 OnStageConnectionExternal();
2134 if ( !mOnStageSignal.Empty() )
2136 Dali::Actor handle( this );
2137 mOnStageSignal.Emit( handle );
2140 // Guard against Remove during callbacks
2143 mOnStageSignalled = true; // signal required next time Actor is removed
2148 void Actor::DisconnectFromStage()
2150 // This container is used instead of walking the Actor hierachy.
2151 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2152 ActorContainer disconnectionList;
2154 // This stage is atomic i.e. not interrupted by user callbacks
2155 RecursiveDisconnectFromStage( disconnectionList );
2157 // Notify applications about the newly disconnected actors.
2158 const ActorIter endIter = disconnectionList.end();
2159 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2161 Actor& actor = GetImplementation(*iter);
2162 actor.NotifyStageDisconnection();
2166 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2168 DALI_ASSERT_ALWAYS( OnStage() );
2170 // Recursively disconnect children
2173 ActorConstIter endIter = mChildren->end();
2174 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2176 Actor& actor = GetImplementation( *iter );
2177 actor.RecursiveDisconnectFromStage( disconnectionList );
2181 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2182 disconnectionList.push_back( Dali::Actor(this) );
2184 // Notification for internal derived classes
2185 OnStageDisconnectionInternal();
2187 DisconnectFromSceneGraph();
2193 * This method is called by an actor or its parent, before a node removal message is sent.
2194 * This is recursive; the child calls DisconnectFromStage() for its children.
2196 void Actor::DisconnectFromSceneGraph()
2198 // Notification for Object::Observers
2199 OnSceneObjectRemove();
2201 // Notify attachment
2204 mAttachment->Disconnect();
2207 #ifdef DYNAMICS_SUPPORT
2209 if( NULL != mDynamicsData )
2211 DisconnectDynamics();
2216 void Actor::NotifyStageDisconnection()
2218 // Actors can be added (in a callback), before the off-stage state is reported.
2219 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2220 // only do this step if there is a stage, i.e. Core is not being shut down
2221 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2223 // Notification for external (CustomeActor) derived classes
2224 OnStageDisconnectionExternal();
2226 if( !mOffStageSignal.Empty() )
2228 Dali::Actor handle( this );
2229 mOffStageSignal.Emit( handle );
2232 // Guard against Add during callbacks
2235 mOnStageSignalled = false; // signal required next time Actor is added
2240 bool Actor::IsNodeConnected() const
2242 bool connected( false );
2247 if( mNode->IsRoot() || mNode->GetParent() )
2256 unsigned int Actor::GetDefaultPropertyCount() const
2258 return DEFAULT_PROPERTY_COUNT;
2261 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2263 indices.reserve( DEFAULT_PROPERTY_COUNT );
2265 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2267 indices.push_back( i );
2271 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2273 if( index < DEFAULT_PROPERTY_COUNT )
2275 return DEFAULT_PROPERTY_DETAILS[index].name;
2281 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2283 Property::Index index = Property::INVALID_INDEX;
2285 // Look for name in default properties
2286 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2288 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2289 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2299 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2301 if( index < DEFAULT_PROPERTY_COUNT )
2303 return DEFAULT_PROPERTY_DETAILS[index].writable;
2309 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2311 if( index < DEFAULT_PROPERTY_COUNT )
2313 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2319 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2321 if( index < DEFAULT_PROPERTY_COUNT )
2323 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2329 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2331 if( index < DEFAULT_PROPERTY_COUNT )
2333 return DEFAULT_PROPERTY_DETAILS[index].type;
2336 // index out of range...return Property::NONE
2337 return Property::NONE;
2340 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2344 case Dali::Actor::Property::PARENT_ORIGIN:
2346 SetParentOrigin( property.Get<Vector3>() );
2350 case Dali::Actor::Property::PARENT_ORIGIN_X:
2352 SetParentOriginX( property.Get<float>() );
2356 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2358 SetParentOriginY( property.Get<float>() );
2362 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2364 SetParentOriginZ( property.Get<float>() );
2368 case Dali::Actor::Property::ANCHOR_POINT:
2370 SetAnchorPoint( property.Get<Vector3>() );
2374 case Dali::Actor::Property::ANCHOR_POINT_X:
2376 SetAnchorPointX( property.Get<float>() );
2380 case Dali::Actor::Property::ANCHOR_POINT_Y:
2382 SetAnchorPointY( property.Get<float>() );
2386 case Dali::Actor::Property::ANCHOR_POINT_Z:
2388 SetAnchorPointZ( property.Get<float>() );
2392 case Dali::Actor::Property::SIZE:
2394 SetSize( property.Get<Vector3>() );
2398 case Dali::Actor::Property::SIZE_WIDTH:
2400 SetWidth( property.Get<float>() );
2404 case Dali::Actor::Property::SIZE_HEIGHT:
2406 SetHeight( property.Get<float>() );
2410 case Dali::Actor::Property::SIZE_DEPTH:
2412 SetDepth( property.Get<float>() );
2416 case Dali::Actor::Property::POSITION:
2418 SetPosition( property.Get<Vector3>() );
2422 case Dali::Actor::Property::POSITION_X:
2424 SetX( property.Get<float>() );
2428 case Dali::Actor::Property::POSITION_Y:
2430 SetY( property.Get<float>() );
2434 case Dali::Actor::Property::POSITION_Z:
2436 SetZ( property.Get<float>() );
2440 case Dali::Actor::Property::ORIENTATION:
2442 SetOrientation( property.Get<Quaternion>() );
2446 case Dali::Actor::Property::SCALE:
2448 SetScale( property.Get<Vector3>() );
2452 case Dali::Actor::Property::SCALE_X:
2454 SetScaleX( property.Get<float>() );
2458 case Dali::Actor::Property::SCALE_Y:
2460 SetScaleY( property.Get<float>() );
2464 case Dali::Actor::Property::SCALE_Z:
2466 SetScaleZ( property.Get<float>() );
2470 case Dali::Actor::Property::VISIBLE:
2472 SetVisible( property.Get<bool>() );
2476 case Dali::Actor::Property::COLOR:
2478 SetColor( property.Get<Vector4>() );
2482 case Dali::Actor::Property::COLOR_RED:
2484 SetColorRed( property.Get<float>() );
2488 case Dali::Actor::Property::COLOR_GREEN:
2490 SetColorGreen( property.Get<float>() );
2494 case Dali::Actor::Property::COLOR_BLUE:
2496 SetColorBlue( property.Get<float>() );
2500 case Dali::Actor::Property::COLOR_ALPHA:
2502 SetOpacity( property.Get<float>() );
2506 case Dali::Actor::Property::NAME:
2508 SetName( property.Get<std::string>() );
2512 case Dali::Actor::Property::SENSITIVE:
2514 SetSensitive( property.Get<bool>() );
2518 case Dali::Actor::Property::LEAVE_REQUIRED:
2520 SetLeaveRequired( property.Get<bool>() );
2524 case Dali::Actor::Property::INHERIT_ORIENTATION:
2526 SetInheritOrientation( property.Get<bool>() );
2530 case Dali::Actor::Property::INHERIT_SCALE:
2532 SetInheritScale( property.Get<bool>() );
2536 case Dali::Actor::Property::COLOR_MODE:
2538 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2542 case Dali::Actor::Property::POSITION_INHERITANCE:
2544 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2548 case Dali::Actor::Property::DRAW_MODE:
2550 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2554 case Dali::Actor::Property::SIZE_MODE:
2556 SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SizeModeTable, SizeModeTableCount ) );
2560 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2562 SetSizeModeFactor( property.Get<Vector3>() );
2568 // this can happen in the case of a non-animatable default property so just do nothing
2574 // TODO: This method needs to be removed
2575 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2577 OnPropertySet(index, value);
2579 switch ( entry.type )
2581 case Property::BOOLEAN:
2583 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2584 DALI_ASSERT_DEBUG( NULL != property );
2586 // property is being used in a separate thread; queue a message to set the property
2587 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2592 case Property::FLOAT:
2594 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2595 DALI_ASSERT_DEBUG( NULL != property );
2597 // property is being used in a separate thread; queue a message to set the property
2598 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2603 case Property::INTEGER:
2605 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2606 DALI_ASSERT_DEBUG( NULL != property );
2608 // property is being used in a separate thread; queue a message to set the property
2609 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2614 case Property::VECTOR2:
2616 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2617 DALI_ASSERT_DEBUG( NULL != property );
2619 // property is being used in a separate thread; queue a message to set the property
2620 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2625 case Property::VECTOR3:
2627 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2628 DALI_ASSERT_DEBUG( NULL != property );
2630 // property is being used in a separate thread; queue a message to set the property
2631 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2636 case Property::VECTOR4:
2638 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2639 DALI_ASSERT_DEBUG( NULL != property );
2641 // property is being used in a separate thread; queue a message to set the property
2642 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2647 case Property::ROTATION:
2649 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2650 DALI_ASSERT_DEBUG( NULL != property );
2652 // property is being used in a separate thread; queue a message to set the property
2653 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2658 case Property::MATRIX:
2660 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2661 DALI_ASSERT_DEBUG( NULL != property );
2663 // property is being used in a separate thread; queue a message to set the property
2664 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2669 case Property::MATRIX3:
2671 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2672 DALI_ASSERT_DEBUG( NULL != property );
2674 // property is being used in a separate thread; queue a message to set the property
2675 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2682 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2688 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2690 Property::Value value;
2694 case Dali::Actor::Property::PARENT_ORIGIN:
2696 value = GetCurrentParentOrigin();
2700 case Dali::Actor::Property::PARENT_ORIGIN_X:
2702 value = GetCurrentParentOrigin().x;
2706 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2708 value = GetCurrentParentOrigin().y;
2712 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2714 value = GetCurrentParentOrigin().z;
2718 case Dali::Actor::Property::ANCHOR_POINT:
2720 value = GetCurrentAnchorPoint();
2724 case Dali::Actor::Property::ANCHOR_POINT_X:
2726 value = GetCurrentAnchorPoint().x;
2730 case Dali::Actor::Property::ANCHOR_POINT_Y:
2732 value = GetCurrentAnchorPoint().y;
2736 case Dali::Actor::Property::ANCHOR_POINT_Z:
2738 value = GetCurrentAnchorPoint().z;
2742 case Dali::Actor::Property::SIZE:
2744 value = GetCurrentSize();
2748 case Dali::Actor::Property::SIZE_WIDTH:
2750 value = GetCurrentSize().width;
2754 case Dali::Actor::Property::SIZE_HEIGHT:
2756 value = GetCurrentSize().height;
2760 case Dali::Actor::Property::SIZE_DEPTH:
2762 value = GetCurrentSize().depth;
2766 case Dali::Actor::Property::POSITION:
2768 value = GetCurrentPosition();
2772 case Dali::Actor::Property::POSITION_X:
2774 value = GetCurrentPosition().x;
2778 case Dali::Actor::Property::POSITION_Y:
2780 value = GetCurrentPosition().y;
2784 case Dali::Actor::Property::POSITION_Z:
2786 value = GetCurrentPosition().z;
2790 case Dali::Actor::Property::WORLD_POSITION:
2792 value = GetCurrentWorldPosition();
2796 case Dali::Actor::Property::WORLD_POSITION_X:
2798 value = GetCurrentWorldPosition().x;
2802 case Dali::Actor::Property::WORLD_POSITION_Y:
2804 value = GetCurrentWorldPosition().y;
2808 case Dali::Actor::Property::WORLD_POSITION_Z:
2810 value = GetCurrentWorldPosition().z;
2814 case Dali::Actor::Property::ORIENTATION:
2816 value = GetCurrentOrientation();
2820 case Dali::Actor::Property::WORLD_ORIENTATION:
2822 value = GetCurrentWorldOrientation();
2826 case Dali::Actor::Property::SCALE:
2828 value = GetCurrentScale();
2832 case Dali::Actor::Property::SCALE_X:
2834 value = GetCurrentScale().x;
2838 case Dali::Actor::Property::SCALE_Y:
2840 value = GetCurrentScale().y;
2844 case Dali::Actor::Property::SCALE_Z:
2846 value = GetCurrentScale().z;
2850 case Dali::Actor::Property::WORLD_SCALE:
2852 value = GetCurrentWorldScale();
2856 case Dali::Actor::Property::VISIBLE:
2858 value = IsVisible();
2862 case Dali::Actor::Property::COLOR:
2864 value = GetCurrentColor();
2868 case Dali::Actor::Property::COLOR_RED:
2870 value = GetCurrentColor().r;
2874 case Dali::Actor::Property::COLOR_GREEN:
2876 value = GetCurrentColor().g;
2880 case Dali::Actor::Property::COLOR_BLUE:
2882 value = GetCurrentColor().b;
2886 case Dali::Actor::Property::COLOR_ALPHA:
2888 value = GetCurrentColor().a;
2892 case Dali::Actor::Property::WORLD_COLOR:
2894 value = GetCurrentWorldColor();
2898 case Dali::Actor::Property::WORLD_MATRIX:
2900 value = GetCurrentWorldMatrix();
2904 case Dali::Actor::Property::NAME:
2910 case Dali::Actor::Property::SENSITIVE:
2912 value = IsSensitive();
2916 case Dali::Actor::Property::LEAVE_REQUIRED:
2918 value = GetLeaveRequired();
2922 case Dali::Actor::Property::INHERIT_ORIENTATION:
2924 value = IsOrientationInherited();
2928 case Dali::Actor::Property::INHERIT_SCALE:
2930 value = IsScaleInherited();
2934 case Dali::Actor::Property::COLOR_MODE:
2936 value = Scripting::GetColorMode( GetColorMode() );
2940 case Dali::Actor::Property::POSITION_INHERITANCE:
2942 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2946 case Dali::Actor::Property::DRAW_MODE:
2948 value = Scripting::GetDrawMode( GetDrawMode() );
2952 case Dali::Actor::Property::SIZE_MODE:
2954 value = Scripting::GetLinearEnumerationName< SizeMode >( GetSizeMode(), SizeModeTable, SizeModeTableCount );
2958 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2960 value = GetSizeModeFactor();
2966 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2974 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
2979 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2981 // This method should only return an object connected to the scene-graph
2982 return OnStage() ? mNode : NULL;
2985 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2987 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2989 const PropertyBase* property( NULL );
2991 // This method should only return a property of an object connected to the scene-graph
2997 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2999 CustomProperty* custom = FindCustomProperty( index );
3000 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3002 property = custom->GetSceneGraphProperty();
3004 else if( NULL != mNode )
3008 case Dali::Actor::Property::SIZE:
3009 property = &mNode->mSize;
3012 case Dali::Actor::Property::SIZE_WIDTH:
3013 property = &mNode->mSize;
3016 case Dali::Actor::Property::SIZE_HEIGHT:
3017 property = &mNode->mSize;
3020 case Dali::Actor::Property::SIZE_DEPTH:
3021 property = &mNode->mSize;
3024 case Dali::Actor::Property::POSITION:
3025 property = &mNode->mPosition;
3028 case Dali::Actor::Property::POSITION_X:
3029 property = &mNode->mPosition;
3032 case Dali::Actor::Property::POSITION_Y:
3033 property = &mNode->mPosition;
3036 case Dali::Actor::Property::POSITION_Z:
3037 property = &mNode->mPosition;
3040 case Dali::Actor::Property::ORIENTATION:
3041 property = &mNode->mOrientation;
3044 case Dali::Actor::Property::SCALE:
3045 property = &mNode->mScale;
3048 case Dali::Actor::Property::SCALE_X:
3049 property = &mNode->mScale;
3052 case Dali::Actor::Property::SCALE_Y:
3053 property = &mNode->mScale;
3056 case Dali::Actor::Property::SCALE_Z:
3057 property = &mNode->mScale;
3060 case Dali::Actor::Property::VISIBLE:
3061 property = &mNode->mVisible;
3064 case Dali::Actor::Property::COLOR:
3065 property = &mNode->mColor;
3068 case Dali::Actor::Property::COLOR_RED:
3069 property = &mNode->mColor;
3072 case Dali::Actor::Property::COLOR_GREEN:
3073 property = &mNode->mColor;
3076 case Dali::Actor::Property::COLOR_BLUE:
3077 property = &mNode->mColor;
3080 case Dali::Actor::Property::COLOR_ALPHA:
3081 property = &mNode->mColor;
3092 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3094 const PropertyInputImpl* property( NULL );
3096 // This method should only return a property of an object connected to the scene-graph
3102 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3104 CustomProperty* custom = FindCustomProperty( index );
3105 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3106 property = custom->GetSceneGraphProperty();
3108 else if( NULL != mNode )
3112 case Dali::Actor::Property::PARENT_ORIGIN:
3113 property = &mNode->mParentOrigin;
3116 case Dali::Actor::Property::PARENT_ORIGIN_X:
3117 property = &mNode->mParentOrigin;
3120 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3121 property = &mNode->mParentOrigin;
3124 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3125 property = &mNode->mParentOrigin;
3128 case Dali::Actor::Property::ANCHOR_POINT:
3129 property = &mNode->mAnchorPoint;
3132 case Dali::Actor::Property::ANCHOR_POINT_X:
3133 property = &mNode->mAnchorPoint;
3136 case Dali::Actor::Property::ANCHOR_POINT_Y:
3137 property = &mNode->mAnchorPoint;
3140 case Dali::Actor::Property::ANCHOR_POINT_Z:
3141 property = &mNode->mAnchorPoint;
3144 case Dali::Actor::Property::SIZE:
3145 property = &mNode->mSize;
3148 case Dali::Actor::Property::SIZE_WIDTH:
3149 property = &mNode->mSize;
3152 case Dali::Actor::Property::SIZE_HEIGHT:
3153 property = &mNode->mSize;
3156 case Dali::Actor::Property::SIZE_DEPTH:
3157 property = &mNode->mSize;
3160 case Dali::Actor::Property::POSITION:
3161 property = &mNode->mPosition;
3164 case Dali::Actor::Property::POSITION_X:
3165 property = &mNode->mPosition;
3168 case Dali::Actor::Property::POSITION_Y:
3169 property = &mNode->mPosition;
3172 case Dali::Actor::Property::POSITION_Z:
3173 property = &mNode->mPosition;
3176 case Dali::Actor::Property::WORLD_POSITION:
3177 property = &mNode->mWorldPosition;
3180 case Dali::Actor::Property::WORLD_POSITION_X:
3181 property = &mNode->mWorldPosition;
3184 case Dali::Actor::Property::WORLD_POSITION_Y:
3185 property = &mNode->mWorldPosition;
3188 case Dali::Actor::Property::WORLD_POSITION_Z:
3189 property = &mNode->mWorldPosition;
3192 case Dali::Actor::Property::ORIENTATION:
3193 property = &mNode->mOrientation;
3196 case Dali::Actor::Property::WORLD_ORIENTATION:
3197 property = &mNode->mWorldOrientation;
3200 case Dali::Actor::Property::SCALE:
3201 property = &mNode->mScale;
3204 case Dali::Actor::Property::SCALE_X:
3205 property = &mNode->mScale;
3208 case Dali::Actor::Property::SCALE_Y:
3209 property = &mNode->mScale;
3212 case Dali::Actor::Property::SCALE_Z:
3213 property = &mNode->mScale;
3216 case Dali::Actor::Property::WORLD_SCALE:
3217 property = &mNode->mWorldScale;
3220 case Dali::Actor::Property::VISIBLE:
3221 property = &mNode->mVisible;
3224 case Dali::Actor::Property::COLOR:
3225 property = &mNode->mColor;
3228 case Dali::Actor::Property::COLOR_RED:
3229 property = &mNode->mColor;
3232 case Dali::Actor::Property::COLOR_GREEN:
3233 property = &mNode->mColor;
3236 case Dali::Actor::Property::COLOR_BLUE:
3237 property = &mNode->mColor;
3240 case Dali::Actor::Property::COLOR_ALPHA:
3241 property = &mNode->mColor;
3244 case Dali::Actor::Property::WORLD_COLOR:
3245 property = &mNode->mWorldColor;
3248 case Dali::Actor::Property::WORLD_MATRIX:
3249 property = &mNode->mWorldMatrix;
3260 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3262 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3266 case Dali::Actor::Property::PARENT_ORIGIN_X:
3267 case Dali::Actor::Property::ANCHOR_POINT_X:
3268 case Dali::Actor::Property::SIZE_WIDTH:
3269 case Dali::Actor::Property::POSITION_X:
3270 case Dali::Actor::Property::WORLD_POSITION_X:
3271 case Dali::Actor::Property::SCALE_X:
3272 case Dali::Actor::Property::COLOR_RED:
3278 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3279 case Dali::Actor::Property::ANCHOR_POINT_Y:
3280 case Dali::Actor::Property::SIZE_HEIGHT:
3281 case Dali::Actor::Property::POSITION_Y:
3282 case Dali::Actor::Property::WORLD_POSITION_Y:
3283 case Dali::Actor::Property::SCALE_Y:
3284 case Dali::Actor::Property::COLOR_GREEN:
3290 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3291 case Dali::Actor::Property::ANCHOR_POINT_Z:
3292 case Dali::Actor::Property::SIZE_DEPTH:
3293 case Dali::Actor::Property::POSITION_Z:
3294 case Dali::Actor::Property::WORLD_POSITION_Z:
3295 case Dali::Actor::Property::SCALE_Z:
3296 case Dali::Actor::Property::COLOR_BLUE:
3302 case Dali::Actor::Property::COLOR_ALPHA:
3315 return componentIndex;
3318 void Actor::SetParent(Actor* parent, int index)
3322 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3326 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3329 // Instruct each actor to create a corresponding node in the scene graph
3330 ConnectToStage( index );
3333 else // parent being set to NULL
3335 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3339 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3342 DALI_ASSERT_ALWAYS(mNode != NULL);
3346 // Disconnect the Node & its children from the scene-graph.
3347 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3350 // Instruct each actor to discard pointers to the scene-graph
3351 DisconnectFromStage();
3356 SceneGraph::Node* Actor::CreateNode() const
3361 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
3364 Actor* actor = dynamic_cast<Actor*>( object );
3368 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3370 actor->SetVisible(true);
3373 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3375 actor->SetVisible(false);
3383 } // namespace Internal