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::ParentOrigin )
106 DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::ParentOriginX )
107 DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::ParentOriginY )
108 DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::ParentOriginZ )
109 DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::AnchorPoint )
110 DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::AnchorPointX )
111 DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::AnchorPointY )
112 DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::AnchorPointZ )
113 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::Size )
114 DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SizeWidth )
115 DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SizeHeight )
116 DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SizeDepth )
117 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::Position )
118 DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::PositionX )
119 DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::PositionY )
120 DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::PositionZ )
121 DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WorldPosition )
122 DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WorldPositionX )
123 DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WorldPositionY )
124 DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WorldPositionZ )
125 DALI_PROPERTY( "rotation", ROTATION, true, true, true, Dali::Actor::Property::Rotation )
126 DALI_PROPERTY( "world-rotation", ROTATION, false, false, true, Dali::Actor::Property::WorldRotation )
127 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::Scale )
128 DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::ScaleX )
129 DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::ScaleY )
130 DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::ScaleZ )
131 DALI_PROPERTY( "world-scale", VECTOR3, false, false, true, Dali::Actor::Property::WorldScale )
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::ColorRed )
135 DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::ColorGreen )
136 DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::ColorBlue )
137 DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::ColorAlpha )
138 DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WorldColor )
139 DALI_PROPERTY( "world-matrix", MATRIX, false, false, true, Dali::Actor::Property::WorldMatrix )
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::LeaveRequired )
143 DALI_PROPERTY( "inherit-rotation", BOOLEAN, true, false, false, Dali::Actor::Property::InheritRotation )
144 DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::InheritScale )
145 DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::ColorMode )
146 DALI_PROPERTY( "position-inheritance", STRING, true, false, false, Dali::Actor::Property::PositionInheritance )
147 DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DrawMode )
148 DALI_PROPERTY( "size-mode", STRING, true, false, false, Dali::Actor::Property::SizeMode )
149 DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SizeModeFactor )
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 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
449 Dali::Actor child = DoGetChildByAlias(actorAlias);
451 // If not found then search by name.
454 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
457 child = Dali::Actor(child_ptr.Get());
464 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
466 Dali::Actor child = GetChildByAlias(actorAlias);
468 if (!child && mChildren )
470 ActorIter end = mChildren->end();
471 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
473 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
485 ActorPtr Actor::FindChildById(const unsigned int id)
494 ActorIter end = mChildren->end();
495 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
497 child = GetImplementation(*iter).FindChildById(id);
508 void Actor::SetParentOrigin( const Vector3& origin )
512 // mNode is being used in a separate thread; queue a message to set the value & base value
513 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
516 // Cache for event-thread access
519 // not allocated, check if different from default
520 if( ParentOrigin::DEFAULT != origin )
522 mParentOrigin = new Vector3( origin );
527 // check if different from current costs more than just set
528 *mParentOrigin = origin;
532 void Actor::SetParentOriginX( float x )
534 const Vector3& current = GetCurrentParentOrigin();
536 SetParentOrigin( Vector3( x, current.y, current.z ) );
539 void Actor::SetParentOriginY( float y )
541 const Vector3& current = GetCurrentParentOrigin();
543 SetParentOrigin( Vector3( current.x, y, current.z ) );
546 void Actor::SetParentOriginZ( float z )
548 const Vector3& current = GetCurrentParentOrigin();
550 SetParentOrigin( Vector3( current.x, current.y, z ) );
553 const Vector3& Actor::GetCurrentParentOrigin() const
555 // Cached for event-thread access
556 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
559 void Actor::SetAnchorPoint(const Vector3& anchor)
563 // mNode is being used in a separate thread; queue a message to set the value & base value
564 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
567 // Cache for event-thread access
570 // not allocated, check if different from default
571 if( AnchorPoint::DEFAULT != anchor )
573 mAnchorPoint = new Vector3( anchor );
578 // check if different from current costs more than just set
579 *mAnchorPoint = anchor;
583 void Actor::SetAnchorPointX( float x )
585 const Vector3& current = GetCurrentAnchorPoint();
587 SetAnchorPoint( Vector3( x, current.y, current.z ) );
590 void Actor::SetAnchorPointY( float y )
592 const Vector3& current = GetCurrentAnchorPoint();
594 SetAnchorPoint( Vector3( current.x, y, current.z ) );
597 void Actor::SetAnchorPointZ( float z )
599 const Vector3& current = GetCurrentAnchorPoint();
601 SetAnchorPoint( Vector3( current.x, current.y, z ) );
604 const Vector3& Actor::GetCurrentAnchorPoint() const
606 // Cached for event-thread access
607 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
610 void Actor::SetPosition(float x, float y)
612 SetPosition(Vector3(x, y, 0.0f));
615 void Actor::SetPosition(float x, float y, float z)
617 SetPosition(Vector3(x, y, z));
620 void Actor::SetPosition(const Vector3& position)
624 // mNode is being used in a separate thread; queue a message to set the value & base value
625 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
629 void Actor::SetX(float x)
633 // mNode is being used in a separate thread; queue a message to set the value & base value
634 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
638 void Actor::SetY(float y)
642 // mNode is being used in a separate thread; queue a message to set the value & base value
643 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
647 void Actor::SetZ(float z)
651 // mNode is being used in a separate thread; queue a message to set the value & base value
652 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
656 void Actor::MoveBy(const Vector3& distance)
660 // mNode is being used in a separate thread; queue a message to set the value & base value
661 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
665 const Vector3& Actor::GetCurrentPosition() const
669 // mNode is being used in a separate thread; copy the value from the previous update
670 return mNode->GetPosition(mStage->GetEventBufferIndex());
673 return Vector3::ZERO;
676 const Vector3& Actor::GetCurrentWorldPosition() const
680 // mNode is being used in a separate thread; copy the value from the previous update
681 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
684 return Vector3::ZERO;
687 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
689 // this flag is not animatable so keep the value
690 mPositionInheritanceMode = mode;
693 // mNode is being used in a separate thread; queue a message to set the value
694 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
698 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
700 // Cached for event-thread access
701 return mPositionInheritanceMode;
704 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
706 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
707 normalizedAxis.Normalize();
709 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
711 SetRotation(rotation);
714 void Actor::SetRotation(const Quaternion& rotation)
718 // mNode is being used in a separate thread; queue a message to set the value & base value
719 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
723 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
727 // mNode is being used in a separate thread; queue a message to set the value & base value
728 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
732 void Actor::RotateBy(const Quaternion& relativeRotation)
736 // mNode is being used in a separate thread; queue a message to set the value & base value
737 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
741 const Quaternion& Actor::GetCurrentRotation() const
745 // mNode is being used in a separate thread; copy the value from the previous update
746 return mNode->GetRotation(mStage->GetEventBufferIndex());
749 return Quaternion::IDENTITY;
752 const Quaternion& Actor::GetCurrentWorldRotation() const
756 // mNode is being used in a separate thread; copy the value from the previous update
757 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
760 return Quaternion::IDENTITY;
763 void Actor::SetScale(float scale)
765 SetScale(Vector3(scale, scale, scale));
768 void Actor::SetScale(float x, float y, float z)
770 SetScale(Vector3(x, y, z));
773 void Actor::SetScale(const Vector3& scale)
777 // mNode is being used in a separate thread; queue a message to set the value & base value
778 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
782 void Actor::SetScaleX( float x )
786 // mNode is being used in a separate thread; queue a message to set the value & base value
787 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
791 void Actor::SetScaleY( float y )
795 // mNode is being used in a separate thread; queue a message to set the value & base value
796 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
800 void Actor::SetScaleZ( float z )
804 // mNode is being used in a separate thread; queue a message to set the value & base value
805 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
809 void Actor::SetInitialVolume(const Vector3& volume)
813 // mNode is being used in a separate thread; queue a message to set the value
814 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
818 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
822 // mNode is being used in a separate thread; queue a message to set the value
823 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
827 bool Actor::GetTransmitGeometryScaling() const
831 // mNode is being used in a separate thread; copy the value from the previous update
832 return mNode->GetTransmitGeometryScaling();
838 void Actor::ScaleBy(const Vector3& relativeScale)
842 // mNode is being used in a separate thread; queue a message to set the value & base value
843 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
847 const Vector3& Actor::GetCurrentScale() const
851 // mNode is being used in a separate thread; copy the value from the previous update
852 return mNode->GetScale(mStage->GetEventBufferIndex());
858 const Vector3& Actor::GetCurrentWorldScale() const
862 // mNode is being used in a separate thread; copy the value from the previous update
863 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
869 void Actor::SetInheritScale( bool inherit )
871 // non animateable so keep local copy
872 mInheritScale = inherit;
875 // mNode is being used in a separate thread; queue a message to set the value
876 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
880 bool Actor::IsScaleInherited() const
882 return mInheritScale;
885 Matrix Actor::GetCurrentWorldMatrix() const
889 // World matrix is no longer updated unless there is something observing the node.
890 // Need to calculate it from node's world position, rotation and scale:
891 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
892 Matrix worldMatrix(false);
893 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
894 mNode->GetWorldRotation( updateBufferIndex ),
895 mNode->GetWorldPosition( updateBufferIndex ) );
899 return Matrix::IDENTITY;
902 void Actor::SetVisible(bool visible)
906 // mNode is being used in a separate thread; queue a message to set the value & base value
907 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
911 bool Actor::IsVisible() const
915 // mNode is being used in a separate thread; copy the value from the previous update
916 return mNode->IsVisible( mStage->GetEventBufferIndex() );
922 void Actor::SetOpacity(float opacity)
926 // mNode is being used in a separate thread; queue a message to set the value & base value
927 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
931 void Actor::OpacityBy(float relativeOpacity)
935 // mNode is being used in a separate thread; queue a message to set the value & base value
936 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
940 float Actor::GetCurrentOpacity() const
944 // mNode is being used in a separate thread; copy the value from the previous update
945 return mNode->GetOpacity(mStage->GetEventBufferIndex());
951 const Vector4& Actor::GetCurrentWorldColor() const
955 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
961 void Actor::SetColor(const Vector4& color)
965 // mNode is being used in a separate thread; queue a message to set the value & base value
966 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
970 void Actor::SetColorRed( float red )
974 // mNode is being used in a separate thread; queue a message to set the value & base value
975 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
979 void Actor::SetColorGreen( float green )
983 // mNode is being used in a separate thread; queue a message to set the value & base value
984 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
988 void Actor::SetColorBlue( float blue )
992 // mNode is being used in a separate thread; queue a message to set the value & base value
993 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
997 void Actor::ColorBy(const Vector4& relativeColor)
1001 // mNode is being used in a separate thread; queue a message to set the value & base value
1002 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1006 const Vector4& Actor::GetCurrentColor() const
1010 // mNode is being used in a separate thread; copy the value from the previous update
1011 return mNode->GetColor(mStage->GetEventBufferIndex());
1014 return Color::WHITE;
1017 void Actor::SetInheritRotation(bool inherit)
1019 // non animateable so keep local copy
1020 mInheritRotation = inherit;
1023 // mNode is being used in a separate thread; queue a message to set the value
1024 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1028 bool Actor::IsRotationInherited() const
1030 return mInheritRotation;
1033 void Actor::SetSizeMode(SizeMode mode)
1035 // non animateable so keep local copy
1039 // mNode is being used in a separate thread; queue a message to set the value
1040 SetSizeModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
1044 void Actor::SetSizeModeFactor(const Vector3& factor)
1046 // non animateable so keep local copy
1047 mSizeModeFactor = factor;
1050 // mNode is being used in a separate thread; queue a message to set the value
1051 SetSizeModeFactorMessage( mStage->GetUpdateInterface(), *mNode, factor );
1055 SizeMode Actor::GetSizeMode() const
1060 const Vector3& Actor::GetSizeModeFactor() const
1062 return mSizeModeFactor;
1065 void Actor::SetColorMode(ColorMode colorMode)
1067 // non animateable so keep local copy
1068 mColorMode = colorMode;
1071 // mNode is being used in a separate thread; queue a message to set the value
1072 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1076 ColorMode Actor::GetColorMode() const
1078 // we have cached copy
1082 void Actor::SetSize(float width, float height)
1084 SetSize( Vector2( width, height ) );
1087 void Actor::SetSize(float width, float height, float depth)
1089 SetSize( Vector3( width, height, depth ) );
1092 void Actor::SetSize(const Vector2& size)
1094 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1097 float Actor::CalculateSizeZ( const Vector2& size ) const
1099 return std::min( size.width, size.height );
1102 void Actor::SetSize(const Vector3& size)
1108 // mNode is being used in a separate thread; queue a message to set the value & base value
1109 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1111 // Notification for derived classes
1116 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1120 // Notify deriving classes
1121 OnSizeAnimation( animation, targetSize );
1124 void Actor::SetWidth( float width )
1128 // mNode is being used in a separate thread; queue a message to set the value & base value
1129 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1133 void Actor::SetHeight( float height )
1137 // mNode is being used in a separate thread; queue a message to set the value & base value
1138 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1142 void Actor::SetDepth( float depth )
1146 // mNode is being used in a separate thread; queue a message to set the value & base value
1147 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1151 const Vector3& Actor::GetSize() const
1156 const Vector3& Actor::GetCurrentSize() const
1160 // mNode is being used in a separate thread; copy the value from the previous update
1161 return mNode->GetSize( mStage->GetEventBufferIndex() );
1164 return Vector3::ZERO;
1167 Vector3 Actor::GetNaturalSize() const
1169 // It is up to deriving classes to return the appropriate natural size
1170 return Vector3( 0.0f, 0.0f, 0.0f );
1174 #ifdef DYNAMICS_SUPPORT
1176 //--------------- Dynamics ---------------
1178 void Actor::DisableDynamics()
1180 if( NULL != mDynamicsData )
1182 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1184 // ensure dynamics object are disconnected from scene
1185 DisconnectDynamics();
1187 // delete joint owned by this actor
1188 while( !mDynamicsData->joints.empty() )
1190 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1193 // delete other joints referencing this actor
1194 while( !mDynamicsData->referencedJoints.empty() )
1196 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1197 ActorPtr jointOwner( joint->GetActor( true ) );
1200 jointOwner->RemoveDynamicsJoint( joint );
1204 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1207 // delete the DynamicsBody object
1208 mDynamicsData->body.Reset();
1210 // Discard Dynamics data structure
1211 delete mDynamicsData;
1212 mDynamicsData = NULL;
1216 DynamicsBodyPtr Actor::GetDynamicsBody() const
1218 DynamicsBodyPtr body;
1220 if( NULL != mDynamicsData )
1222 body = mDynamicsData->body;
1228 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1230 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1232 if( NULL == mDynamicsData )
1234 mDynamicsData = new DynamicsData( this );
1237 if( !mDynamicsData->body )
1239 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1243 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1246 if( mParent == world->GetRootActor().Get() )
1248 mDynamicsData->body->Connect(*mStage);
1254 return mDynamicsData->body;
1257 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1259 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1260 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1263 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1265 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1266 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1268 DynamicsJointPtr joint;
1270 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1274 if( NULL != mDynamicsData )
1276 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1278 if( mDynamicsData->joints.end() != it )
1280 // use existing joint
1286 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1287 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1291 bodyA = EnableDynamics( new DynamicsBodyConfig );
1296 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1299 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1300 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1302 if( OnStage() && attachedActor->OnStage() )
1304 joint->Connect(*mStage);
1307 attachedActor->ReferenceJoint( joint );
1309 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1310 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1317 const int Actor::GetNumberOfJoints() const
1319 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1322 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1324 DynamicsJointPtr joint;
1326 if( NULL != mDynamicsData )
1328 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1330 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1332 for( int i = 0; i < index; ++i )
1344 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1346 DynamicsJointPtr joint;
1348 if( NULL != mDynamicsData )
1350 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1352 if( mDynamicsData->joints.end() != it )
1354 // use existing joint
1362 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1364 if( NULL != mDynamicsData )
1366 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1367 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1369 for( ; it != endIt; ++it )
1371 if( it->second == joint.Get() )
1373 ActorPtr attachedActor( it->first );
1375 if( OnStage() && attachedActor && attachedActor->OnStage() )
1377 joint->Disconnect(*mStage);
1382 attachedActor->ReleaseJoint( joint );
1383 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1384 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1387 mDynamicsData->joints.erase(it);
1394 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1396 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1398 if( NULL != mDynamicsData )
1400 mDynamicsData->referencedJoints.push_back(joint);
1404 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1406 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1408 if( NULL != mDynamicsData )
1410 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1412 if( it != mDynamicsData->referencedJoints.end() )
1414 mDynamicsData->referencedJoints.erase( it );
1419 void Actor::SetDynamicsRoot(bool flag)
1421 if( mIsDynamicsRoot != flag )
1423 mIsDynamicsRoot = flag;
1425 if( OnStage() && mChildren )
1427 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1428 ActorIter end = mChildren->end();
1429 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1431 Actor& child = GetImplementation(*iter);
1433 if( child.GetDynamicsBody() )
1435 if( mIsDynamicsRoot )
1437 child.ConnectDynamics();
1441 child.DisconnectDynamics();
1449 bool Actor::IsDynamicsRoot() const
1451 return mIsDynamicsRoot;
1454 void Actor::AttachedActorOnStage( Dali::Actor actor )
1456 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1460 ActorPtr attachedActor( &GetImplementation(actor) );
1462 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1463 if( NULL != mDynamicsData )
1465 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1466 if( mDynamicsData->joints.end() != it )
1468 DynamicsJointPtr joint( it->second );
1469 joint->Connect(*mStage);
1475 void Actor::AttachedActorOffStage( Dali::Actor actor )
1477 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1481 ActorPtr attachedActor( &GetImplementation(actor) );
1483 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1484 if( NULL != mDynamicsData )
1486 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1487 if( mDynamicsData->joints.end() != it )
1489 DynamicsJointPtr joint( it->second );
1490 joint->Disconnect(*mStage);
1496 void Actor::ConnectDynamics()
1498 if( NULL != mDynamicsData && mDynamicsData->body )
1500 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1502 mDynamicsData->body->Connect(*mStage);
1504 // Connect all joints where attachedActor is also on stage
1505 if( !mDynamicsData->joints.empty() )
1507 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1508 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1510 for( ; it != endIt; ++it )
1512 Actor* attachedActor( it->first );
1513 if( NULL != attachedActor && attachedActor->OnStage() )
1515 DynamicsJointPtr joint( it->second );
1517 joint->Connect(*mStage);
1525 void Actor::DisconnectDynamics()
1527 if( NULL != mDynamicsData && mDynamicsData->body )
1531 mDynamicsData->body->Disconnect(*mStage);
1533 // Disconnect all joints
1534 if( !mDynamicsData->joints.empty() )
1536 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1537 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1539 for( ; it != endIt; ++it )
1541 DynamicsJointPtr joint( it->second );
1543 joint->Disconnect(*mStage);
1550 #endif // DYNAMICS_SUPPORT
1552 void Actor::SetOverlay(bool enable)
1554 // Setting STENCIL will override OVERLAY
1555 if( DrawMode::STENCIL != mDrawMode )
1557 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1561 bool Actor::IsOverlay() const
1563 return ( DrawMode::OVERLAY == mDrawMode );
1566 void Actor::SetDrawMode( DrawMode::Type drawMode )
1568 // this flag is not animatable so keep the value
1569 mDrawMode = drawMode;
1572 // mNode is being used in a separate thread; queue a message to set the value
1573 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1577 DrawMode::Type Actor::GetDrawMode() const
1582 bool Actor::ScreenToLocal( float& localX,
1585 float screenY ) const
1587 // only valid when on-stage
1590 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1592 Vector2 converted( screenX, screenY );
1594 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1595 const int taskCount = taskList.GetTaskCount();
1596 for( int i = taskCount - 1; i >= 0; --i )
1598 Dali::RenderTask task = taskList.GetTask( i );
1599 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1601 // found a task where this conversion was ok so return
1609 bool Actor::ScreenToLocal( RenderTask& renderTask,
1613 float screenY ) const
1615 bool retval = false;
1616 // only valid when on-stage
1619 CameraActor* camera = renderTask.GetCameraActor();
1623 renderTask.GetViewport( viewport );
1625 // need to translate coordinates to render tasks coordinate space
1626 Vector2 converted( screenX, screenY );
1627 if( renderTask.TranslateCoordinates( converted ) )
1629 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1636 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1637 const Matrix& projectionMatrix,
1638 const Viewport& viewport,
1642 float screenY ) const
1644 // Early-out if mNode is NULL
1650 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1652 // Calculate the ModelView matrix
1653 Matrix modelView(false/*don't init*/);
1654 // need to use the components as world matrix is only updated for actors that need it
1655 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1656 Matrix::Multiply(modelView, modelView, viewMatrix);
1658 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1659 Matrix invertedMvp(false/*don't init*/);
1660 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1661 bool success = invertedMvp.Invert();
1663 // Convert to GL coordinates
1664 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1669 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1676 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1682 if (XyPlaneIntersect(nearPos, farPos, local))
1684 Vector3 size = GetCurrentSize();
1685 localX = local.x + size.x * 0.5f;
1686 localY = local.y + size.y * 0.5f;
1697 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1700 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1702 Mathematical Formulation
1704 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1706 ( p - c ) dot ( p - c ) = r^2
1708 Given a ray with a point of origin 'o', and a direction vector 'd':
1710 ray(t) = o + td, t >= 0
1712 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1714 (o + td - c ) dot ( o + td - c ) = r^2
1716 To solve for t we first expand the above into a more recognisable quadratic equation form
1718 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1727 B = 2( o - c ) dot d
1728 C = ( o - c ) dot ( o - c ) - r^2
1730 which can be solved using a standard quadratic formula.
1732 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1734 Practical Simplification
1736 In a renderer, we often differentiate between world space and object space. In the object space
1737 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1738 into object space, the mathematical solution presented above can be simplified significantly.
1740 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1744 and we can find the t at which the (transformed) ray intersects the sphere by
1746 ( o + td ) dot ( o + td ) = r^2
1748 According to the reasoning above, we expand the above quadratic equation into the general form
1752 which now has coefficients:
1759 // Early out if mNode is NULL
1765 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1767 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1768 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1769 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1770 rayOrigin.y - translation.y,
1771 rayOrigin.z - translation.z);
1773 // Compute the radius is not needed, square radius it's enough.
1774 const Vector3& size( mNode->GetSize( bufferIndex ) );
1776 // Scale the sphere.
1777 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1779 const float width = size.width * scale.width;
1780 const float height = size.height * scale.height;
1782 float squareSphereRadius = 0.5f * ( width * width + height * height );
1784 float a = rayDir.Dot( rayDir ); // a
1785 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1786 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1788 return ( b2*b2 - a*c ) >= 0.f;
1791 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1798 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1800 // Transforms the ray to the local reference system.
1802 // Calculate the inverse of Model matrix
1803 Matrix invModelMatrix(false/*don't init*/);
1804 // need to use the components as world matrix is only updated for actors that need it
1805 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1807 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1808 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1810 // Test with the actor's XY plane (Normal = 0 0 1 1).
1812 float a = -rayOriginLocal.z;
1813 float b = rayDirLocal.z;
1815 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1817 // Ray travels distance * rayDirLocal to intersect with plane.
1820 const Vector3& size = mNode->GetSize( bufferIndex );
1822 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1823 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1825 // Test with the actor's geometry.
1826 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1833 void Actor::SetLeaveRequired(bool required)
1835 mLeaveRequired = required;
1838 bool Actor::GetLeaveRequired() const
1840 return mLeaveRequired;
1843 void Actor::SetKeyboardFocusable( bool focusable )
1845 mKeyboardFocusable = focusable;
1848 bool Actor::IsKeyboardFocusable() const
1850 return mKeyboardFocusable;
1853 bool Actor::GetTouchRequired() const
1855 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1858 bool Actor::GetHoverRequired() const
1860 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1863 bool Actor::GetMouseWheelEventRequired() const
1865 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1868 bool Actor::IsHittable() const
1870 return IsSensitive() &&
1872 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1876 ActorGestureData& Actor::GetGestureData()
1878 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1879 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1880 if ( NULL == mGestureData )
1882 mGestureData = new ActorGestureData;
1884 return *mGestureData;
1887 bool Actor::IsGestureRequred( Gesture::Type type ) const
1889 return mGestureData && mGestureData->IsGestureRequred( type );
1892 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1894 bool consumed = false;
1896 if ( !mTouchedSignal.Empty() )
1898 Dali::Actor handle( this );
1899 consumed = mTouchedSignal.Emit( handle, event );
1904 // Notification for derived classes
1905 consumed = OnTouchEvent( event );
1911 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1913 bool consumed = false;
1915 if ( !mHoveredSignal.Empty() )
1917 Dali::Actor handle( this );
1918 consumed = mHoveredSignal.Emit( handle, event );
1923 // Notification for derived classes
1924 consumed = OnHoverEvent( event );
1930 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1932 bool consumed = false;
1934 if ( !mMouseWheelEventSignal.Empty() )
1936 Dali::Actor handle( this );
1937 consumed = mMouseWheelEventSignal.Emit( handle, event );
1942 // Notification for derived classes
1943 consumed = OnMouseWheelEvent(event);
1949 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1951 return mTouchedSignal;
1954 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1956 return mHoveredSignal;
1959 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1961 return mMouseWheelEventSignal;
1964 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1966 return mOnStageSignal;
1969 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1971 return mOffStageSignal;
1974 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1976 bool connected( true );
1977 Actor* actor = dynamic_cast<Actor*>( object );
1979 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
1981 actor->TouchedSignal().Connect( tracker, functor );
1983 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
1985 actor->HoveredSignal().Connect( tracker, functor );
1987 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
1989 actor->MouseWheelEventSignal().Connect( tracker, functor );
1991 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
1993 actor->OnStageSignal().Connect( tracker, functor );
1995 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
1997 actor->OffStageSignal().Connect( tracker, functor );
2001 // signalName does not match any signal
2008 Actor::Actor( DerivedType derivedType )
2013 mParentOrigin( NULL ),
2014 mAnchorPoint( NULL ),
2015 #ifdef DYNAMICS_SUPPORT
2016 mDynamicsData( NULL ),
2018 mGestureData( NULL ),
2020 mSize( 0.0f, 0.0f, 0.0f ),
2021 mSizeModeFactor( Vector3::ONE ),
2023 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2024 mIsRoot( ROOT_LAYER == derivedType ),
2025 mIsRenderable( RENDERABLE == derivedType ),
2026 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2027 mIsOnStage( false ),
2028 mIsDynamicsRoot(false),
2030 mLeaveRequired( false ),
2031 mKeyboardFocusable( false ),
2032 mDerivedRequiresTouch( false ),
2033 mDerivedRequiresHover( false ),
2034 mDerivedRequiresMouseWheelEvent( false ),
2035 mOnStageSignalled( false ),
2036 mInheritRotation( true ),
2037 mInheritScale( true ),
2038 mDrawMode( DrawMode::NORMAL ),
2039 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2040 mColorMode( Node::DEFAULT_COLOR_MODE ),
2041 mSizeMode( Node::DEFAULT_SIZE_MODE )
2045 void Actor::Initialize()
2047 mStage = Stage::GetCurrent();
2048 DALI_ASSERT_ALWAYS( mStage && "Stage doesn't exist" );
2051 SceneGraph::Node* node = CreateNode();
2053 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2054 mNode = node; // Keep raw-pointer to Node
2058 mStage->RegisterObject( this );
2063 // Remove mParent pointers from children even if we're destroying core,
2064 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2067 ActorConstIter endIter = mChildren->end();
2068 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2070 Actor& actor = GetImplementation( *iter );
2071 actor.SetParent( NULL );
2076 // Guard to allow handle destruction after Core has been destroyed
2077 if( Stage::IsInstalled() )
2081 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2082 mNode = NULL; // Node is about to be destroyed
2085 mStage->UnregisterObject( this );
2088 #ifdef DYNAMICS_SUPPORT
2090 delete mDynamicsData;
2093 // Cleanup optional gesture data
2094 delete mGestureData;
2096 // Cleanup optional parent origin and anchor
2097 delete mParentOrigin;
2098 delete mAnchorPoint;
2101 void Actor::ConnectToStage( int index )
2103 // This container is used instead of walking the Actor hierachy.
2104 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2105 ActorContainer connectionList;
2107 // This stage is atomic i.e. not interrupted by user callbacks
2108 RecursiveConnectToStage( connectionList, index );
2110 // Notify applications about the newly connected actors.
2111 const ActorIter endIter = connectionList.end();
2112 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2114 Actor& actor = GetImplementation(*iter);
2115 actor.NotifyStageConnection();
2119 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2121 DALI_ASSERT_ALWAYS( !OnStage() );
2125 ConnectToSceneGraph(index);
2127 // Notification for internal derived classes
2128 OnStageConnectionInternal();
2130 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2131 connectionList.push_back( Dali::Actor(this) );
2133 // Recursively connect children
2136 ActorConstIter endIter = mChildren->end();
2137 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2139 Actor& actor = GetImplementation( *iter );
2140 actor.RecursiveConnectToStage( connectionList );
2146 * This method is called when the Actor is connected to the Stage.
2147 * The parent must have added its Node to the scene-graph.
2148 * The child must connect its Node to the parent's Node.
2149 * This is resursive; the child calls ConnectToStage() for its children.
2151 void Actor::ConnectToSceneGraph(int index)
2153 DALI_ASSERT_DEBUG( mNode != NULL);
2154 DALI_ASSERT_DEBUG( mParent != NULL);
2155 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2159 // Reparent Node in next Update
2160 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2163 // Notify attachment
2166 mAttachment->Connect();
2169 #ifdef DYNAMICS_SUPPORT
2171 if( NULL != mDynamicsData )
2177 // Notification for Object::Observers
2181 void Actor::NotifyStageConnection()
2183 // Actors can be removed (in a callback), before the on-stage stage is reported.
2184 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2185 if ( OnStage() && !mOnStageSignalled )
2187 // Notification for external (CustomActor) derived classes
2188 OnStageConnectionExternal();
2190 if ( !mOnStageSignal.Empty() )
2192 Dali::Actor handle( this );
2193 mOnStageSignal.Emit( handle );
2196 // Guard against Remove during callbacks
2199 mOnStageSignalled = true; // signal required next time Actor is removed
2204 void Actor::DisconnectFromStage()
2206 // This container is used instead of walking the Actor hierachy.
2207 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2208 ActorContainer disconnectionList;
2210 // This stage is atomic i.e. not interrupted by user callbacks
2211 RecursiveDisconnectFromStage( disconnectionList );
2213 // Notify applications about the newly disconnected actors.
2214 const ActorIter endIter = disconnectionList.end();
2215 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2217 Actor& actor = GetImplementation(*iter);
2218 actor.NotifyStageDisconnection();
2222 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2224 DALI_ASSERT_ALWAYS( OnStage() );
2226 // Recursively disconnect children
2229 ActorConstIter endIter = mChildren->end();
2230 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2232 Actor& actor = GetImplementation( *iter );
2233 actor.RecursiveDisconnectFromStage( disconnectionList );
2237 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2238 disconnectionList.push_back( Dali::Actor(this) );
2240 // Notification for internal derived classes
2241 OnStageDisconnectionInternal();
2243 DisconnectFromSceneGraph();
2249 * This method is called by an actor or its parent, before a node removal message is sent.
2250 * This is recursive; the child calls DisconnectFromStage() for its children.
2252 void Actor::DisconnectFromSceneGraph()
2254 // Notification for Object::Observers
2255 OnSceneObjectRemove();
2257 // Notify attachment
2260 mAttachment->Disconnect();
2263 #ifdef DYNAMICS_SUPPORT
2265 if( NULL != mDynamicsData )
2267 DisconnectDynamics();
2272 void Actor::NotifyStageDisconnection()
2274 // Actors can be added (in a callback), before the off-stage state is reported.
2275 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2276 // only do this step if there is a stage, i.e. Core is not being shut down
2277 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2279 // Notification for external (CustomeActor) derived classes
2280 OnStageDisconnectionExternal();
2282 if( !mOffStageSignal.Empty() )
2284 Dali::Actor handle( this );
2285 mOffStageSignal.Emit( handle );
2288 // Guard against Add during callbacks
2291 mOnStageSignalled = false; // signal required next time Actor is added
2296 bool Actor::IsNodeConnected() const
2298 bool connected( false );
2303 if( mNode->IsRoot() || mNode->GetParent() )
2312 unsigned int Actor::GetDefaultPropertyCount() const
2314 return DEFAULT_PROPERTY_COUNT;
2317 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2319 indices.reserve( DEFAULT_PROPERTY_COUNT );
2321 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2323 indices.push_back( i );
2327 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2329 if( index < DEFAULT_PROPERTY_COUNT )
2331 return DEFAULT_PROPERTY_DETAILS[index].name;
2337 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2339 Property::Index index = Property::INVALID_INDEX;
2341 // Look for name in default properties
2342 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2344 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2345 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2355 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2357 if( index < DEFAULT_PROPERTY_COUNT )
2359 return DEFAULT_PROPERTY_DETAILS[index].writable;
2365 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2367 if( index < DEFAULT_PROPERTY_COUNT )
2369 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2375 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2377 if( index < DEFAULT_PROPERTY_COUNT )
2379 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2385 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2387 if( index < DEFAULT_PROPERTY_COUNT )
2389 return DEFAULT_PROPERTY_DETAILS[index].type;
2392 // index out of range...return Property::NONE
2393 return Property::NONE;
2396 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2400 case Dali::Actor::Property::ParentOrigin:
2402 SetParentOrigin( property.Get<Vector3>() );
2406 case Dali::Actor::Property::ParentOriginX:
2408 SetParentOriginX( property.Get<float>() );
2412 case Dali::Actor::Property::ParentOriginY:
2414 SetParentOriginY( property.Get<float>() );
2418 case Dali::Actor::Property::ParentOriginZ:
2420 SetParentOriginZ( property.Get<float>() );
2424 case Dali::Actor::Property::AnchorPoint:
2426 SetAnchorPoint( property.Get<Vector3>() );
2430 case Dali::Actor::Property::AnchorPointX:
2432 SetAnchorPointX( property.Get<float>() );
2436 case Dali::Actor::Property::AnchorPointY:
2438 SetAnchorPointY( property.Get<float>() );
2442 case Dali::Actor::Property::AnchorPointZ:
2444 SetAnchorPointZ( property.Get<float>() );
2448 case Dali::Actor::Property::Size:
2450 SetSize( property.Get<Vector3>() );
2454 case Dali::Actor::Property::SizeWidth:
2456 SetWidth( property.Get<float>() );
2460 case Dali::Actor::Property::SizeHeight:
2462 SetHeight( property.Get<float>() );
2466 case Dali::Actor::Property::SizeDepth:
2468 SetDepth( property.Get<float>() );
2472 case Dali::Actor::Property::Position:
2474 SetPosition( property.Get<Vector3>() );
2478 case Dali::Actor::Property::PositionX:
2480 SetX( property.Get<float>() );
2484 case Dali::Actor::Property::PositionY:
2486 SetY( property.Get<float>() );
2490 case Dali::Actor::Property::PositionZ:
2492 SetZ( property.Get<float>() );
2496 case Dali::Actor::Property::Rotation:
2498 SetRotation( property.Get<Quaternion>() );
2502 case Dali::Actor::Property::Scale:
2504 SetScale( property.Get<Vector3>() );
2508 case Dali::Actor::Property::ScaleX:
2510 SetScaleX( property.Get<float>() );
2514 case Dali::Actor::Property::ScaleY:
2516 SetScaleY( property.Get<float>() );
2520 case Dali::Actor::Property::ScaleZ:
2522 SetScaleZ( property.Get<float>() );
2526 case Dali::Actor::Property::Visible:
2528 SetVisible( property.Get<bool>() );
2532 case Dali::Actor::Property::Color:
2534 SetColor( property.Get<Vector4>() );
2538 case Dali::Actor::Property::ColorRed:
2540 SetColorRed( property.Get<float>() );
2544 case Dali::Actor::Property::ColorGreen:
2546 SetColorGreen( property.Get<float>() );
2550 case Dali::Actor::Property::ColorBlue:
2552 SetColorBlue( property.Get<float>() );
2556 case Dali::Actor::Property::ColorAlpha:
2558 SetOpacity( property.Get<float>() );
2562 case Dali::Actor::Property::Name:
2564 SetName( property.Get<std::string>() );
2568 case Dali::Actor::Property::Sensitive:
2570 SetSensitive( property.Get<bool>() );
2574 case Dali::Actor::Property::LeaveRequired:
2576 SetLeaveRequired( property.Get<bool>() );
2580 case Dali::Actor::Property::InheritRotation:
2582 SetInheritRotation( property.Get<bool>() );
2586 case Dali::Actor::Property::InheritScale:
2588 SetInheritScale( property.Get<bool>() );
2592 case Dali::Actor::Property::ColorMode:
2594 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2598 case Dali::Actor::Property::PositionInheritance:
2600 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2604 case Dali::Actor::Property::DrawMode:
2606 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2610 case Dali::Actor::Property::SizeMode:
2612 SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SizeModeTable, SizeModeTableCount ) );
2616 case Dali::Actor::Property::SizeModeFactor:
2618 SetSizeModeFactor( property.Get<Vector3>() );
2624 // this can happen in the case of a non-animatable default property so just do nothing
2630 // TODO: This method needs to be removed
2631 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2633 OnPropertySet(index, value);
2635 switch ( entry.type )
2637 case Property::BOOLEAN:
2639 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2640 DALI_ASSERT_DEBUG( NULL != property );
2642 // property is being used in a separate thread; queue a message to set the property
2643 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2648 case Property::FLOAT:
2650 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2651 DALI_ASSERT_DEBUG( NULL != property );
2653 // property is being used in a separate thread; queue a message to set the property
2654 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2659 case Property::INTEGER:
2661 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2662 DALI_ASSERT_DEBUG( NULL != property );
2664 // property is being used in a separate thread; queue a message to set the property
2665 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2670 case Property::VECTOR2:
2672 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2673 DALI_ASSERT_DEBUG( NULL != property );
2675 // property is being used in a separate thread; queue a message to set the property
2676 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2681 case Property::VECTOR3:
2683 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2684 DALI_ASSERT_DEBUG( NULL != property );
2686 // property is being used in a separate thread; queue a message to set the property
2687 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2692 case Property::VECTOR4:
2694 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2695 DALI_ASSERT_DEBUG( NULL != property );
2697 // property is being used in a separate thread; queue a message to set the property
2698 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2703 case Property::ROTATION:
2705 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2706 DALI_ASSERT_DEBUG( NULL != property );
2708 // property is being used in a separate thread; queue a message to set the property
2709 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2714 case Property::MATRIX:
2716 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2717 DALI_ASSERT_DEBUG( NULL != property );
2719 // property is being used in a separate thread; queue a message to set the property
2720 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2725 case Property::MATRIX3:
2727 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2728 DALI_ASSERT_DEBUG( NULL != property );
2730 // property is being used in a separate thread; queue a message to set the property
2731 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2738 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2744 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2746 Property::Value value;
2750 case Dali::Actor::Property::ParentOrigin:
2752 value = GetCurrentParentOrigin();
2756 case Dali::Actor::Property::ParentOriginX:
2758 value = GetCurrentParentOrigin().x;
2762 case Dali::Actor::Property::ParentOriginY:
2764 value = GetCurrentParentOrigin().y;
2768 case Dali::Actor::Property::ParentOriginZ:
2770 value = GetCurrentParentOrigin().z;
2774 case Dali::Actor::Property::AnchorPoint:
2776 value = GetCurrentAnchorPoint();
2780 case Dali::Actor::Property::AnchorPointX:
2782 value = GetCurrentAnchorPoint().x;
2786 case Dali::Actor::Property::AnchorPointY:
2788 value = GetCurrentAnchorPoint().y;
2792 case Dali::Actor::Property::AnchorPointZ:
2794 value = GetCurrentAnchorPoint().z;
2798 case Dali::Actor::Property::Size:
2800 value = GetCurrentSize();
2804 case Dali::Actor::Property::SizeWidth:
2806 value = GetCurrentSize().width;
2810 case Dali::Actor::Property::SizeHeight:
2812 value = GetCurrentSize().height;
2816 case Dali::Actor::Property::SizeDepth:
2818 value = GetCurrentSize().depth;
2822 case Dali::Actor::Property::Position:
2824 value = GetCurrentPosition();
2828 case Dali::Actor::Property::PositionX:
2830 value = GetCurrentPosition().x;
2834 case Dali::Actor::Property::PositionY:
2836 value = GetCurrentPosition().y;
2840 case Dali::Actor::Property::PositionZ:
2842 value = GetCurrentPosition().z;
2846 case Dali::Actor::Property::WorldPosition:
2848 value = GetCurrentWorldPosition();
2852 case Dali::Actor::Property::WorldPositionX:
2854 value = GetCurrentWorldPosition().x;
2858 case Dali::Actor::Property::WorldPositionY:
2860 value = GetCurrentWorldPosition().y;
2864 case Dali::Actor::Property::WorldPositionZ:
2866 value = GetCurrentWorldPosition().z;
2870 case Dali::Actor::Property::Rotation:
2872 value = GetCurrentRotation();
2876 case Dali::Actor::Property::WorldRotation:
2878 value = GetCurrentWorldRotation();
2882 case Dali::Actor::Property::Scale:
2884 value = GetCurrentScale();
2888 case Dali::Actor::Property::ScaleX:
2890 value = GetCurrentScale().x;
2894 case Dali::Actor::Property::ScaleY:
2896 value = GetCurrentScale().y;
2900 case Dali::Actor::Property::ScaleZ:
2902 value = GetCurrentScale().z;
2906 case Dali::Actor::Property::WorldScale:
2908 value = GetCurrentWorldScale();
2912 case Dali::Actor::Property::Visible:
2914 value = IsVisible();
2918 case Dali::Actor::Property::Color:
2920 value = GetCurrentColor();
2924 case Dali::Actor::Property::ColorRed:
2926 value = GetCurrentColor().r;
2930 case Dali::Actor::Property::ColorGreen:
2932 value = GetCurrentColor().g;
2936 case Dali::Actor::Property::ColorBlue:
2938 value = GetCurrentColor().b;
2942 case Dali::Actor::Property::ColorAlpha:
2944 value = GetCurrentColor().a;
2948 case Dali::Actor::Property::WorldColor:
2950 value = GetCurrentWorldColor();
2954 case Dali::Actor::Property::WorldMatrix:
2956 value = GetCurrentWorldMatrix();
2960 case Dali::Actor::Property::Name:
2966 case Dali::Actor::Property::Sensitive:
2968 value = IsSensitive();
2972 case Dali::Actor::Property::LeaveRequired:
2974 value = GetLeaveRequired();
2978 case Dali::Actor::Property::InheritRotation:
2980 value = IsRotationInherited();
2984 case Dali::Actor::Property::InheritScale:
2986 value = IsScaleInherited();
2990 case Dali::Actor::Property::ColorMode:
2992 value = Scripting::GetColorMode( GetColorMode() );
2996 case Dali::Actor::Property::PositionInheritance:
2998 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3002 case Dali::Actor::Property::DrawMode:
3004 value = Scripting::GetDrawMode( GetDrawMode() );
3008 case Dali::Actor::Property::SizeMode:
3010 value = Scripting::GetLinearEnumerationName< SizeMode >( GetSizeMode(), SizeModeTable, SizeModeTableCount );
3014 case Dali::Actor::Property::SizeModeFactor:
3016 value = GetSizeModeFactor();
3022 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3030 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3035 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3037 // This method should only return an object connected to the scene-graph
3038 return OnStage() ? mNode : NULL;
3041 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3043 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3045 const PropertyBase* property( NULL );
3047 // This method should only return a property of an object connected to the scene-graph
3053 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3055 CustomProperty* custom = FindCustomProperty( index );
3056 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3058 property = custom->GetSceneGraphProperty();
3060 else if( NULL != mNode )
3064 case Dali::Actor::Property::Size:
3065 property = &mNode->mSize;
3068 case Dali::Actor::Property::SizeWidth:
3069 property = &mNode->mSize;
3072 case Dali::Actor::Property::SizeHeight:
3073 property = &mNode->mSize;
3076 case Dali::Actor::Property::SizeDepth:
3077 property = &mNode->mSize;
3080 case Dali::Actor::Property::Position:
3081 property = &mNode->mPosition;
3084 case Dali::Actor::Property::PositionX:
3085 property = &mNode->mPosition;
3088 case Dali::Actor::Property::PositionY:
3089 property = &mNode->mPosition;
3092 case Dali::Actor::Property::PositionZ:
3093 property = &mNode->mPosition;
3096 case Dali::Actor::Property::Rotation:
3097 property = &mNode->mRotation;
3100 case Dali::Actor::Property::Scale:
3101 property = &mNode->mScale;
3104 case Dali::Actor::Property::ScaleX:
3105 property = &mNode->mScale;
3108 case Dali::Actor::Property::ScaleY:
3109 property = &mNode->mScale;
3112 case Dali::Actor::Property::ScaleZ:
3113 property = &mNode->mScale;
3116 case Dali::Actor::Property::Visible:
3117 property = &mNode->mVisible;
3120 case Dali::Actor::Property::Color:
3121 property = &mNode->mColor;
3124 case Dali::Actor::Property::ColorRed:
3125 property = &mNode->mColor;
3128 case Dali::Actor::Property::ColorGreen:
3129 property = &mNode->mColor;
3132 case Dali::Actor::Property::ColorBlue:
3133 property = &mNode->mColor;
3136 case Dali::Actor::Property::ColorAlpha:
3137 property = &mNode->mColor;
3148 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3150 const PropertyInputImpl* property( NULL );
3152 // This method should only return a property of an object connected to the scene-graph
3158 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3160 CustomProperty* custom = FindCustomProperty( index );
3161 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3162 property = custom->GetSceneGraphProperty();
3164 else if( NULL != mNode )
3168 case Dali::Actor::Property::ParentOrigin:
3169 property = &mNode->mParentOrigin;
3172 case Dali::Actor::Property::ParentOriginX:
3173 property = &mNode->mParentOrigin;
3176 case Dali::Actor::Property::ParentOriginY:
3177 property = &mNode->mParentOrigin;
3180 case Dali::Actor::Property::ParentOriginZ:
3181 property = &mNode->mParentOrigin;
3184 case Dali::Actor::Property::AnchorPoint:
3185 property = &mNode->mAnchorPoint;
3188 case Dali::Actor::Property::AnchorPointX:
3189 property = &mNode->mAnchorPoint;
3192 case Dali::Actor::Property::AnchorPointY:
3193 property = &mNode->mAnchorPoint;
3196 case Dali::Actor::Property::AnchorPointZ:
3197 property = &mNode->mAnchorPoint;
3200 case Dali::Actor::Property::Size:
3201 property = &mNode->mSize;
3204 case Dali::Actor::Property::SizeWidth:
3205 property = &mNode->mSize;
3208 case Dali::Actor::Property::SizeHeight:
3209 property = &mNode->mSize;
3212 case Dali::Actor::Property::SizeDepth:
3213 property = &mNode->mSize;
3216 case Dali::Actor::Property::Position:
3217 property = &mNode->mPosition;
3220 case Dali::Actor::Property::PositionX:
3221 property = &mNode->mPosition;
3224 case Dali::Actor::Property::PositionY:
3225 property = &mNode->mPosition;
3228 case Dali::Actor::Property::PositionZ:
3229 property = &mNode->mPosition;
3232 case Dali::Actor::Property::WorldPosition:
3233 property = &mNode->mWorldPosition;
3236 case Dali::Actor::Property::WorldPositionX:
3237 property = &mNode->mWorldPosition;
3240 case Dali::Actor::Property::WorldPositionY:
3241 property = &mNode->mWorldPosition;
3244 case Dali::Actor::Property::WorldPositionZ:
3245 property = &mNode->mWorldPosition;
3248 case Dali::Actor::Property::Rotation:
3249 property = &mNode->mRotation;
3252 case Dali::Actor::Property::WorldRotation:
3253 property = &mNode->mWorldRotation;
3256 case Dali::Actor::Property::Scale:
3257 property = &mNode->mScale;
3260 case Dali::Actor::Property::ScaleX:
3261 property = &mNode->mScale;
3264 case Dali::Actor::Property::ScaleY:
3265 property = &mNode->mScale;
3268 case Dali::Actor::Property::ScaleZ:
3269 property = &mNode->mScale;
3272 case Dali::Actor::Property::WorldScale:
3273 property = &mNode->mWorldScale;
3276 case Dali::Actor::Property::Visible:
3277 property = &mNode->mVisible;
3280 case Dali::Actor::Property::Color:
3281 property = &mNode->mColor;
3284 case Dali::Actor::Property::ColorRed:
3285 property = &mNode->mColor;
3288 case Dali::Actor::Property::ColorGreen:
3289 property = &mNode->mColor;
3292 case Dali::Actor::Property::ColorBlue:
3293 property = &mNode->mColor;
3296 case Dali::Actor::Property::ColorAlpha:
3297 property = &mNode->mColor;
3300 case Dali::Actor::Property::WorldColor:
3301 property = &mNode->mWorldColor;
3304 case Dali::Actor::Property::WorldMatrix:
3305 property = &mNode->mWorldMatrix;
3316 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3318 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3322 case Dali::Actor::Property::ParentOriginX:
3323 case Dali::Actor::Property::AnchorPointX:
3324 case Dali::Actor::Property::SizeWidth:
3325 case Dali::Actor::Property::PositionX:
3326 case Dali::Actor::Property::WorldPositionX:
3327 case Dali::Actor::Property::ScaleX:
3328 case Dali::Actor::Property::ColorRed:
3334 case Dali::Actor::Property::ParentOriginY:
3335 case Dali::Actor::Property::AnchorPointY:
3336 case Dali::Actor::Property::SizeHeight:
3337 case Dali::Actor::Property::PositionY:
3338 case Dali::Actor::Property::WorldPositionY:
3339 case Dali::Actor::Property::ScaleY:
3340 case Dali::Actor::Property::ColorGreen:
3346 case Dali::Actor::Property::ParentOriginZ:
3347 case Dali::Actor::Property::AnchorPointZ:
3348 case Dali::Actor::Property::SizeDepth:
3349 case Dali::Actor::Property::PositionZ:
3350 case Dali::Actor::Property::WorldPositionZ:
3351 case Dali::Actor::Property::ScaleZ:
3352 case Dali::Actor::Property::ColorBlue:
3358 case Dali::Actor::Property::ColorAlpha:
3371 return componentIndex;
3374 void Actor::SetParent(Actor* parent, int index)
3378 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3382 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3385 // Instruct each actor to create a corresponding node in the scene graph
3386 ConnectToStage( index );
3389 else // parent being set to NULL
3391 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3395 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3398 DALI_ASSERT_ALWAYS(mNode != NULL);
3402 // Disconnect the Node & its children from the scene-graph.
3403 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3406 // Instruct each actor to discard pointers to the scene-graph
3407 DisconnectFromStage();
3412 SceneGraph::Node* Actor::CreateNode() const
3417 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
3420 Actor* actor = dynamic_cast<Actor*>( object );
3424 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3426 actor->SetVisible(true);
3429 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3431 actor->SetVisible(false);
3439 } // namespace Internal