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( "rotation", ROTATION, true, true, true, Dali::Actor::Property::ROTATION )
126 DALI_PROPERTY( "world-rotation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ROTATION )
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-rotation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ROTATION )
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::MoveBy(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::SetRotation(const Radian& angle, const Vector3& axis)
668 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
669 normalizedAxis.Normalize();
671 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
673 SetRotation(rotation);
676 void Actor::SetRotation(const Quaternion& rotation)
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->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
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->mRotation, &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->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
703 const Quaternion& Actor::GetCurrentRotation() const
707 // mNode is being used in a separate thread; copy the value from the previous update
708 return mNode->GetRotation(mStage->GetEventBufferIndex());
711 return Quaternion::IDENTITY;
714 const Quaternion& Actor::GetCurrentWorldRotation() const
718 // mNode is being used in a separate thread; copy the value from the previous update
719 return mNode->GetWorldRotation( 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, rotation and scale:
853 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
854 Matrix worldMatrix(false);
855 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
856 mNode->GetWorldRotation( 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 void Actor::OpacityBy(float relativeOpacity)
897 // mNode is being used in a separate thread; queue a message to set the value & base value
898 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
902 float Actor::GetCurrentOpacity() const
906 // mNode is being used in a separate thread; copy the value from the previous update
907 return mNode->GetOpacity(mStage->GetEventBufferIndex());
913 const Vector4& Actor::GetCurrentWorldColor() const
917 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
923 void Actor::SetColor(const Vector4& color)
927 // mNode is being used in a separate thread; queue a message to set the value & base value
928 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
932 void Actor::SetColorRed( float red )
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>::BakeX, red );
941 void Actor::SetColorGreen( float green )
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>::BakeY, green );
950 void Actor::SetColorBlue( float blue )
954 // mNode is being used in a separate thread; queue a message to set the value & base value
955 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
959 void Actor::ColorBy(const Vector4& relativeColor)
963 // mNode is being used in a separate thread; queue a message to set the value & base value
964 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
968 const Vector4& Actor::GetCurrentColor() const
972 // mNode is being used in a separate thread; copy the value from the previous update
973 return mNode->GetColor(mStage->GetEventBufferIndex());
979 void Actor::SetInheritRotation(bool inherit)
981 // non animateable so keep local copy
982 mInheritRotation = inherit;
985 // mNode is being used in a separate thread; queue a message to set the value
986 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
990 bool Actor::IsRotationInherited() const
992 return mInheritRotation;
995 void Actor::SetSizeMode(SizeMode mode)
997 // non animateable so keep local copy
1001 // mNode is being used in a separate thread; queue a message to set the value
1002 SetSizeModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
1006 void Actor::SetSizeModeFactor(const Vector3& factor)
1008 // non animateable so keep local copy
1009 mSizeModeFactor = factor;
1012 // mNode is being used in a separate thread; queue a message to set the value
1013 SetSizeModeFactorMessage( mStage->GetUpdateInterface(), *mNode, factor );
1017 SizeMode Actor::GetSizeMode() const
1022 const Vector3& Actor::GetSizeModeFactor() const
1024 return mSizeModeFactor;
1027 void Actor::SetColorMode(ColorMode colorMode)
1029 // non animateable so keep local copy
1030 mColorMode = colorMode;
1033 // mNode is being used in a separate thread; queue a message to set the value
1034 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1038 ColorMode Actor::GetColorMode() const
1040 // we have cached copy
1044 void Actor::SetSize(float width, float height)
1046 SetSize( Vector2( width, height ) );
1049 void Actor::SetSize(float width, float height, float depth)
1051 SetSize( Vector3( width, height, depth ) );
1054 void Actor::SetSize(const Vector2& size)
1056 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1059 float Actor::CalculateSizeZ( const Vector2& size ) const
1061 return std::min( size.width, size.height );
1064 void Actor::SetSize(const Vector3& size)
1070 // mNode is being used in a separate thread; queue a message to set the value & base value
1071 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1073 // Notification for derived classes
1078 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1082 // Notify deriving classes
1083 OnSizeAnimation( animation, targetSize );
1086 void Actor::SetWidth( float width )
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>::BakeX, width );
1095 void Actor::SetHeight( float height )
1099 // mNode is being used in a separate thread; queue a message to set the value & base value
1100 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1104 void Actor::SetDepth( float depth )
1108 // mNode is being used in a separate thread; queue a message to set the value & base value
1109 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1113 const Vector3& Actor::GetSize() const
1118 const Vector3& Actor::GetCurrentSize() const
1122 // mNode is being used in a separate thread; copy the value from the previous update
1123 return mNode->GetSize( mStage->GetEventBufferIndex() );
1126 return Vector3::ZERO;
1129 Vector3 Actor::GetNaturalSize() const
1131 // It is up to deriving classes to return the appropriate natural size
1132 return Vector3( 0.0f, 0.0f, 0.0f );
1136 #ifdef DYNAMICS_SUPPORT
1138 //--------------- Dynamics ---------------
1140 void Actor::DisableDynamics()
1142 if( NULL != mDynamicsData )
1144 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1146 // ensure dynamics object are disconnected from scene
1147 DisconnectDynamics();
1149 // delete joint owned by this actor
1150 while( !mDynamicsData->joints.empty() )
1152 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1155 // delete other joints referencing this actor
1156 while( !mDynamicsData->referencedJoints.empty() )
1158 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1159 ActorPtr jointOwner( joint->GetActor( true ) );
1162 jointOwner->RemoveDynamicsJoint( joint );
1166 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1169 // delete the DynamicsBody object
1170 mDynamicsData->body.Reset();
1172 // Discard Dynamics data structure
1173 delete mDynamicsData;
1174 mDynamicsData = NULL;
1178 DynamicsBodyPtr Actor::GetDynamicsBody() const
1180 DynamicsBodyPtr body;
1182 if( NULL != mDynamicsData )
1184 body = mDynamicsData->body;
1190 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1192 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1194 if( NULL == mDynamicsData )
1196 mDynamicsData = new DynamicsData( this );
1199 if( !mDynamicsData->body )
1201 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1205 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1208 if( mParent == world->GetRootActor().Get() )
1210 mDynamicsData->body->Connect(*mStage);
1216 return mDynamicsData->body;
1219 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1221 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1222 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1225 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1227 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1228 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1230 DynamicsJointPtr joint;
1232 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1236 if( NULL != mDynamicsData )
1238 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1240 if( mDynamicsData->joints.end() != it )
1242 // use existing joint
1248 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1249 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1253 bodyA = EnableDynamics( new DynamicsBodyConfig );
1258 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1261 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1262 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1264 if( OnStage() && attachedActor->OnStage() )
1266 joint->Connect(*mStage);
1269 attachedActor->ReferenceJoint( joint );
1271 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1272 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1279 const int Actor::GetNumberOfJoints() const
1281 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1284 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1286 DynamicsJointPtr joint;
1288 if( NULL != mDynamicsData )
1290 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1292 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1294 for( int i = 0; i < index; ++i )
1306 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1308 DynamicsJointPtr joint;
1310 if( NULL != mDynamicsData )
1312 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1314 if( mDynamicsData->joints.end() != it )
1316 // use existing joint
1324 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1326 if( NULL != mDynamicsData )
1328 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1329 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1331 for( ; it != endIt; ++it )
1333 if( it->second == joint.Get() )
1335 ActorPtr attachedActor( it->first );
1337 if( OnStage() && attachedActor && attachedActor->OnStage() )
1339 joint->Disconnect(*mStage);
1344 attachedActor->ReleaseJoint( joint );
1345 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1346 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1349 mDynamicsData->joints.erase(it);
1356 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1358 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1360 if( NULL != mDynamicsData )
1362 mDynamicsData->referencedJoints.push_back(joint);
1366 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1368 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1370 if( NULL != mDynamicsData )
1372 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1374 if( it != mDynamicsData->referencedJoints.end() )
1376 mDynamicsData->referencedJoints.erase( it );
1381 void Actor::SetDynamicsRoot(bool flag)
1383 if( mIsDynamicsRoot != flag )
1385 mIsDynamicsRoot = flag;
1387 if( OnStage() && mChildren )
1389 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1390 ActorIter end = mChildren->end();
1391 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1393 Actor& child = GetImplementation(*iter);
1395 if( child.GetDynamicsBody() )
1397 if( mIsDynamicsRoot )
1399 child.ConnectDynamics();
1403 child.DisconnectDynamics();
1411 bool Actor::IsDynamicsRoot() const
1413 return mIsDynamicsRoot;
1416 void Actor::AttachedActorOnStage( Dali::Actor actor )
1418 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1422 ActorPtr attachedActor( &GetImplementation(actor) );
1424 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1425 if( NULL != mDynamicsData )
1427 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1428 if( mDynamicsData->joints.end() != it )
1430 DynamicsJointPtr joint( it->second );
1431 joint->Connect(*mStage);
1437 void Actor::AttachedActorOffStage( Dali::Actor actor )
1439 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1443 ActorPtr attachedActor( &GetImplementation(actor) );
1445 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1446 if( NULL != mDynamicsData )
1448 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1449 if( mDynamicsData->joints.end() != it )
1451 DynamicsJointPtr joint( it->second );
1452 joint->Disconnect(*mStage);
1458 void Actor::ConnectDynamics()
1460 if( NULL != mDynamicsData && mDynamicsData->body )
1462 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1464 mDynamicsData->body->Connect(*mStage);
1466 // Connect all joints where attachedActor is also on stage
1467 if( !mDynamicsData->joints.empty() )
1469 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1470 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1472 for( ; it != endIt; ++it )
1474 Actor* attachedActor( it->first );
1475 if( NULL != attachedActor && attachedActor->OnStage() )
1477 DynamicsJointPtr joint( it->second );
1479 joint->Connect(*mStage);
1487 void Actor::DisconnectDynamics()
1489 if( NULL != mDynamicsData && mDynamicsData->body )
1493 mDynamicsData->body->Disconnect(*mStage);
1495 // Disconnect all joints
1496 if( !mDynamicsData->joints.empty() )
1498 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1499 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1501 for( ; it != endIt; ++it )
1503 DynamicsJointPtr joint( it->second );
1505 joint->Disconnect(*mStage);
1512 #endif // DYNAMICS_SUPPORT
1514 void Actor::SetOverlay(bool enable)
1516 // Setting STENCIL will override OVERLAY
1517 if( DrawMode::STENCIL != mDrawMode )
1519 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1523 bool Actor::IsOverlay() const
1525 return ( DrawMode::OVERLAY == mDrawMode );
1528 void Actor::SetDrawMode( DrawMode::Type drawMode )
1530 // this flag is not animatable so keep the value
1531 mDrawMode = drawMode;
1534 // mNode is being used in a separate thread; queue a message to set the value
1535 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1539 DrawMode::Type Actor::GetDrawMode() const
1544 bool Actor::ScreenToLocal( float& localX,
1547 float screenY ) const
1549 // only valid when on-stage
1552 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1554 Vector2 converted( screenX, screenY );
1556 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1557 const int taskCount = taskList.GetTaskCount();
1558 for( int i = taskCount - 1; i >= 0; --i )
1560 Dali::RenderTask task = taskList.GetTask( i );
1561 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1563 // found a task where this conversion was ok so return
1571 bool Actor::ScreenToLocal( RenderTask& renderTask,
1575 float screenY ) const
1577 bool retval = false;
1578 // only valid when on-stage
1581 CameraActor* camera = renderTask.GetCameraActor();
1585 renderTask.GetViewport( viewport );
1587 // need to translate coordinates to render tasks coordinate space
1588 Vector2 converted( screenX, screenY );
1589 if( renderTask.TranslateCoordinates( converted ) )
1591 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1598 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1599 const Matrix& projectionMatrix,
1600 const Viewport& viewport,
1604 float screenY ) const
1606 // Early-out if mNode is NULL
1612 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1614 // Calculate the ModelView matrix
1615 Matrix modelView(false/*don't init*/);
1616 // need to use the components as world matrix is only updated for actors that need it
1617 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1618 Matrix::Multiply(modelView, modelView, viewMatrix);
1620 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1621 Matrix invertedMvp(false/*don't init*/);
1622 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1623 bool success = invertedMvp.Invert();
1625 // Convert to GL coordinates
1626 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1631 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1638 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1644 if (XyPlaneIntersect(nearPos, farPos, local))
1646 Vector3 size = GetCurrentSize();
1647 localX = local.x + size.x * 0.5f;
1648 localY = local.y + size.y * 0.5f;
1659 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1662 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1664 Mathematical Formulation
1666 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1668 ( p - c ) dot ( p - c ) = r^2
1670 Given a ray with a point of origin 'o', and a direction vector 'd':
1672 ray(t) = o + td, t >= 0
1674 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1676 (o + td - c ) dot ( o + td - c ) = r^2
1678 To solve for t we first expand the above into a more recognisable quadratic equation form
1680 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1689 B = 2( o - c ) dot d
1690 C = ( o - c ) dot ( o - c ) - r^2
1692 which can be solved using a standard quadratic formula.
1694 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1696 Practical Simplification
1698 In a renderer, we often differentiate between world space and object space. In the object space
1699 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1700 into object space, the mathematical solution presented above can be simplified significantly.
1702 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1706 and we can find the t at which the (transformed) ray intersects the sphere by
1708 ( o + td ) dot ( o + td ) = r^2
1710 According to the reasoning above, we expand the above quadratic equation into the general form
1714 which now has coefficients:
1721 // Early out if mNode is NULL
1727 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1729 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1730 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1731 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1732 rayOrigin.y - translation.y,
1733 rayOrigin.z - translation.z);
1735 // Compute the radius is not needed, square radius it's enough.
1736 const Vector3& size( mNode->GetSize( bufferIndex ) );
1738 // Scale the sphere.
1739 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1741 const float width = size.width * scale.width;
1742 const float height = size.height * scale.height;
1744 float squareSphereRadius = 0.5f * ( width * width + height * height );
1746 float a = rayDir.Dot( rayDir ); // a
1747 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1748 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1750 return ( b2*b2 - a*c ) >= 0.f;
1753 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1760 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1762 // Transforms the ray to the local reference system.
1764 // Calculate the inverse of Model matrix
1765 Matrix invModelMatrix(false/*don't init*/);
1766 // need to use the components as world matrix is only updated for actors that need it
1767 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1769 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1770 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1772 // Test with the actor's XY plane (Normal = 0 0 1 1).
1774 float a = -rayOriginLocal.z;
1775 float b = rayDirLocal.z;
1777 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1779 // Ray travels distance * rayDirLocal to intersect with plane.
1782 const Vector3& size = mNode->GetSize( bufferIndex );
1784 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1785 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1787 // Test with the actor's geometry.
1788 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1795 void Actor::SetLeaveRequired(bool required)
1797 mLeaveRequired = required;
1800 bool Actor::GetLeaveRequired() const
1802 return mLeaveRequired;
1805 void Actor::SetKeyboardFocusable( bool focusable )
1807 mKeyboardFocusable = focusable;
1810 bool Actor::IsKeyboardFocusable() const
1812 return mKeyboardFocusable;
1815 bool Actor::GetTouchRequired() const
1817 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1820 bool Actor::GetHoverRequired() const
1822 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1825 bool Actor::GetMouseWheelEventRequired() const
1827 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1830 bool Actor::IsHittable() const
1832 return IsSensitive() &&
1834 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1838 ActorGestureData& Actor::GetGestureData()
1840 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1841 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1842 if ( NULL == mGestureData )
1844 mGestureData = new ActorGestureData;
1846 return *mGestureData;
1849 bool Actor::IsGestureRequred( Gesture::Type type ) const
1851 return mGestureData && mGestureData->IsGestureRequred( type );
1854 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1856 bool consumed = false;
1858 if ( !mTouchedSignal.Empty() )
1860 Dali::Actor handle( this );
1861 consumed = mTouchedSignal.Emit( handle, event );
1866 // Notification for derived classes
1867 consumed = OnTouchEvent( event );
1873 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1875 bool consumed = false;
1877 if ( !mHoveredSignal.Empty() )
1879 Dali::Actor handle( this );
1880 consumed = mHoveredSignal.Emit( handle, event );
1885 // Notification for derived classes
1886 consumed = OnHoverEvent( event );
1892 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1894 bool consumed = false;
1896 if ( !mMouseWheelEventSignal.Empty() )
1898 Dali::Actor handle( this );
1899 consumed = mMouseWheelEventSignal.Emit( handle, event );
1904 // Notification for derived classes
1905 consumed = OnMouseWheelEvent(event);
1911 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1913 return mTouchedSignal;
1916 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1918 return mHoveredSignal;
1921 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1923 return mMouseWheelEventSignal;
1926 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1928 return mOnStageSignal;
1931 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1933 return mOffStageSignal;
1936 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1938 bool connected( true );
1939 Actor* actor = dynamic_cast<Actor*>( object );
1941 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
1943 actor->TouchedSignal().Connect( tracker, functor );
1945 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
1947 actor->HoveredSignal().Connect( tracker, functor );
1949 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
1951 actor->MouseWheelEventSignal().Connect( tracker, functor );
1953 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
1955 actor->OnStageSignal().Connect( tracker, functor );
1957 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
1959 actor->OffStageSignal().Connect( tracker, functor );
1963 // signalName does not match any signal
1970 Actor::Actor( DerivedType derivedType )
1975 mParentOrigin( NULL ),
1976 mAnchorPoint( NULL ),
1977 #ifdef DYNAMICS_SUPPORT
1978 mDynamicsData( NULL ),
1980 mGestureData( NULL ),
1982 mSize( 0.0f, 0.0f, 0.0f ),
1983 mSizeModeFactor( Vector3::ONE ),
1985 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1986 mIsRoot( ROOT_LAYER == derivedType ),
1987 mIsRenderable( RENDERABLE == derivedType ),
1988 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1989 mIsOnStage( false ),
1990 mIsDynamicsRoot(false),
1992 mLeaveRequired( false ),
1993 mKeyboardFocusable( false ),
1994 mDerivedRequiresTouch( false ),
1995 mDerivedRequiresHover( false ),
1996 mDerivedRequiresMouseWheelEvent( false ),
1997 mOnStageSignalled( false ),
1998 mInheritRotation( true ),
1999 mInheritScale( true ),
2000 mDrawMode( DrawMode::NORMAL ),
2001 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2002 mColorMode( Node::DEFAULT_COLOR_MODE ),
2003 mSizeMode( Node::DEFAULT_SIZE_MODE )
2007 void Actor::Initialize()
2009 mStage = Stage::GetCurrent();
2010 DALI_ASSERT_ALWAYS( mStage && "Stage doesn't exist" );
2013 SceneGraph::Node* node = CreateNode();
2015 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2016 mNode = node; // Keep raw-pointer to Node
2020 mStage->RegisterObject( this );
2025 // Remove mParent pointers from children even if we're destroying core,
2026 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2029 ActorConstIter endIter = mChildren->end();
2030 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2032 Actor& actor = GetImplementation( *iter );
2033 actor.SetParent( NULL );
2038 // Guard to allow handle destruction after Core has been destroyed
2039 if( Stage::IsInstalled() )
2043 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2044 mNode = NULL; // Node is about to be destroyed
2047 mStage->UnregisterObject( this );
2050 #ifdef DYNAMICS_SUPPORT
2052 delete mDynamicsData;
2055 // Cleanup optional gesture data
2056 delete mGestureData;
2058 // Cleanup optional parent origin and anchor
2059 delete mParentOrigin;
2060 delete mAnchorPoint;
2063 void Actor::ConnectToStage( int index )
2065 // This container is used instead of walking the Actor hierachy.
2066 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2067 ActorContainer connectionList;
2069 // This stage is atomic i.e. not interrupted by user callbacks
2070 RecursiveConnectToStage( connectionList, index );
2072 // Notify applications about the newly connected actors.
2073 const ActorIter endIter = connectionList.end();
2074 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2076 Actor& actor = GetImplementation(*iter);
2077 actor.NotifyStageConnection();
2081 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2083 DALI_ASSERT_ALWAYS( !OnStage() );
2087 ConnectToSceneGraph(index);
2089 // Notification for internal derived classes
2090 OnStageConnectionInternal();
2092 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2093 connectionList.push_back( Dali::Actor(this) );
2095 // Recursively connect children
2098 ActorConstIter endIter = mChildren->end();
2099 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2101 Actor& actor = GetImplementation( *iter );
2102 actor.RecursiveConnectToStage( connectionList );
2108 * This method is called when the Actor is connected to the Stage.
2109 * The parent must have added its Node to the scene-graph.
2110 * The child must connect its Node to the parent's Node.
2111 * This is resursive; the child calls ConnectToStage() for its children.
2113 void Actor::ConnectToSceneGraph(int index)
2115 DALI_ASSERT_DEBUG( mNode != NULL);
2116 DALI_ASSERT_DEBUG( mParent != NULL);
2117 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2121 // Reparent Node in next Update
2122 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2125 // Notify attachment
2128 mAttachment->Connect();
2131 #ifdef DYNAMICS_SUPPORT
2133 if( NULL != mDynamicsData )
2139 // Notification for Object::Observers
2143 void Actor::NotifyStageConnection()
2145 // Actors can be removed (in a callback), before the on-stage stage is reported.
2146 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2147 if ( OnStage() && !mOnStageSignalled )
2149 // Notification for external (CustomActor) derived classes
2150 OnStageConnectionExternal();
2152 if ( !mOnStageSignal.Empty() )
2154 Dali::Actor handle( this );
2155 mOnStageSignal.Emit( handle );
2158 // Guard against Remove during callbacks
2161 mOnStageSignalled = true; // signal required next time Actor is removed
2166 void Actor::DisconnectFromStage()
2168 // This container is used instead of walking the Actor hierachy.
2169 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2170 ActorContainer disconnectionList;
2172 // This stage is atomic i.e. not interrupted by user callbacks
2173 RecursiveDisconnectFromStage( disconnectionList );
2175 // Notify applications about the newly disconnected actors.
2176 const ActorIter endIter = disconnectionList.end();
2177 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2179 Actor& actor = GetImplementation(*iter);
2180 actor.NotifyStageDisconnection();
2184 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2186 DALI_ASSERT_ALWAYS( OnStage() );
2188 // Recursively disconnect children
2191 ActorConstIter endIter = mChildren->end();
2192 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2194 Actor& actor = GetImplementation( *iter );
2195 actor.RecursiveDisconnectFromStage( disconnectionList );
2199 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2200 disconnectionList.push_back( Dali::Actor(this) );
2202 // Notification for internal derived classes
2203 OnStageDisconnectionInternal();
2205 DisconnectFromSceneGraph();
2211 * This method is called by an actor or its parent, before a node removal message is sent.
2212 * This is recursive; the child calls DisconnectFromStage() for its children.
2214 void Actor::DisconnectFromSceneGraph()
2216 // Notification for Object::Observers
2217 OnSceneObjectRemove();
2219 // Notify attachment
2222 mAttachment->Disconnect();
2225 #ifdef DYNAMICS_SUPPORT
2227 if( NULL != mDynamicsData )
2229 DisconnectDynamics();
2234 void Actor::NotifyStageDisconnection()
2236 // Actors can be added (in a callback), before the off-stage state is reported.
2237 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2238 // only do this step if there is a stage, i.e. Core is not being shut down
2239 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2241 // Notification for external (CustomeActor) derived classes
2242 OnStageDisconnectionExternal();
2244 if( !mOffStageSignal.Empty() )
2246 Dali::Actor handle( this );
2247 mOffStageSignal.Emit( handle );
2250 // Guard against Add during callbacks
2253 mOnStageSignalled = false; // signal required next time Actor is added
2258 bool Actor::IsNodeConnected() const
2260 bool connected( false );
2265 if( mNode->IsRoot() || mNode->GetParent() )
2274 unsigned int Actor::GetDefaultPropertyCount() const
2276 return DEFAULT_PROPERTY_COUNT;
2279 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2281 indices.reserve( DEFAULT_PROPERTY_COUNT );
2283 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2285 indices.push_back( i );
2289 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2291 if( index < DEFAULT_PROPERTY_COUNT )
2293 return DEFAULT_PROPERTY_DETAILS[index].name;
2299 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2301 Property::Index index = Property::INVALID_INDEX;
2303 // Look for name in default properties
2304 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2306 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2307 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2317 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2319 if( index < DEFAULT_PROPERTY_COUNT )
2321 return DEFAULT_PROPERTY_DETAILS[index].writable;
2327 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2329 if( index < DEFAULT_PROPERTY_COUNT )
2331 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2337 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2339 if( index < DEFAULT_PROPERTY_COUNT )
2341 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2347 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2349 if( index < DEFAULT_PROPERTY_COUNT )
2351 return DEFAULT_PROPERTY_DETAILS[index].type;
2354 // index out of range...return Property::NONE
2355 return Property::NONE;
2358 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2362 case Dali::Actor::Property::PARENT_ORIGIN:
2364 SetParentOrigin( property.Get<Vector3>() );
2368 case Dali::Actor::Property::PARENT_ORIGIN_X:
2370 SetParentOriginX( property.Get<float>() );
2374 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2376 SetParentOriginY( property.Get<float>() );
2380 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2382 SetParentOriginZ( property.Get<float>() );
2386 case Dali::Actor::Property::ANCHOR_POINT:
2388 SetAnchorPoint( property.Get<Vector3>() );
2392 case Dali::Actor::Property::ANCHOR_POINT_X:
2394 SetAnchorPointX( property.Get<float>() );
2398 case Dali::Actor::Property::ANCHOR_POINT_Y:
2400 SetAnchorPointY( property.Get<float>() );
2404 case Dali::Actor::Property::ANCHOR_POINT_Z:
2406 SetAnchorPointZ( property.Get<float>() );
2410 case Dali::Actor::Property::SIZE:
2412 SetSize( property.Get<Vector3>() );
2416 case Dali::Actor::Property::SIZE_WIDTH:
2418 SetWidth( property.Get<float>() );
2422 case Dali::Actor::Property::SIZE_HEIGHT:
2424 SetHeight( property.Get<float>() );
2428 case Dali::Actor::Property::SIZE_DEPTH:
2430 SetDepth( property.Get<float>() );
2434 case Dali::Actor::Property::POSITION:
2436 SetPosition( property.Get<Vector3>() );
2440 case Dali::Actor::Property::POSITION_X:
2442 SetX( property.Get<float>() );
2446 case Dali::Actor::Property::POSITION_Y:
2448 SetY( property.Get<float>() );
2452 case Dali::Actor::Property::POSITION_Z:
2454 SetZ( property.Get<float>() );
2458 case Dali::Actor::Property::ROTATION:
2460 SetRotation( property.Get<Quaternion>() );
2464 case Dali::Actor::Property::SCALE:
2466 SetScale( property.Get<Vector3>() );
2470 case Dali::Actor::Property::SCALE_X:
2472 SetScaleX( property.Get<float>() );
2476 case Dali::Actor::Property::SCALE_Y:
2478 SetScaleY( property.Get<float>() );
2482 case Dali::Actor::Property::SCALE_Z:
2484 SetScaleZ( property.Get<float>() );
2488 case Dali::Actor::Property::VISIBLE:
2490 SetVisible( property.Get<bool>() );
2494 case Dali::Actor::Property::COLOR:
2496 SetColor( property.Get<Vector4>() );
2500 case Dali::Actor::Property::COLOR_RED:
2502 SetColorRed( property.Get<float>() );
2506 case Dali::Actor::Property::COLOR_GREEN:
2508 SetColorGreen( property.Get<float>() );
2512 case Dali::Actor::Property::COLOR_BLUE:
2514 SetColorBlue( property.Get<float>() );
2518 case Dali::Actor::Property::COLOR_ALPHA:
2520 SetOpacity( property.Get<float>() );
2524 case Dali::Actor::Property::NAME:
2526 SetName( property.Get<std::string>() );
2530 case Dali::Actor::Property::SENSITIVE:
2532 SetSensitive( property.Get<bool>() );
2536 case Dali::Actor::Property::LEAVE_REQUIRED:
2538 SetLeaveRequired( property.Get<bool>() );
2542 case Dali::Actor::Property::INHERIT_ROTATION:
2544 SetInheritRotation( property.Get<bool>() );
2548 case Dali::Actor::Property::INHERIT_SCALE:
2550 SetInheritScale( property.Get<bool>() );
2554 case Dali::Actor::Property::COLOR_MODE:
2556 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2560 case Dali::Actor::Property::POSITION_INHERITANCE:
2562 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2566 case Dali::Actor::Property::DRAW_MODE:
2568 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2572 case Dali::Actor::Property::SIZE_MODE:
2574 SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SizeModeTable, SizeModeTableCount ) );
2578 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2580 SetSizeModeFactor( property.Get<Vector3>() );
2586 // this can happen in the case of a non-animatable default property so just do nothing
2592 // TODO: This method needs to be removed
2593 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2595 OnPropertySet(index, value);
2597 switch ( entry.type )
2599 case Property::BOOLEAN:
2601 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2602 DALI_ASSERT_DEBUG( NULL != property );
2604 // property is being used in a separate thread; queue a message to set the property
2605 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2610 case Property::FLOAT:
2612 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2613 DALI_ASSERT_DEBUG( NULL != property );
2615 // property is being used in a separate thread; queue a message to set the property
2616 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2621 case Property::INTEGER:
2623 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2624 DALI_ASSERT_DEBUG( NULL != property );
2626 // property is being used in a separate thread; queue a message to set the property
2627 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2632 case Property::VECTOR2:
2634 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2635 DALI_ASSERT_DEBUG( NULL != property );
2637 // property is being used in a separate thread; queue a message to set the property
2638 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2643 case Property::VECTOR3:
2645 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2646 DALI_ASSERT_DEBUG( NULL != property );
2648 // property is being used in a separate thread; queue a message to set the property
2649 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2654 case Property::VECTOR4:
2656 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2657 DALI_ASSERT_DEBUG( NULL != property );
2659 // property is being used in a separate thread; queue a message to set the property
2660 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2665 case Property::ROTATION:
2667 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2668 DALI_ASSERT_DEBUG( NULL != property );
2670 // property is being used in a separate thread; queue a message to set the property
2671 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2676 case Property::MATRIX:
2678 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2679 DALI_ASSERT_DEBUG( NULL != property );
2681 // property is being used in a separate thread; queue a message to set the property
2682 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2687 case Property::MATRIX3:
2689 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2690 DALI_ASSERT_DEBUG( NULL != property );
2692 // property is being used in a separate thread; queue a message to set the property
2693 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2700 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2706 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2708 Property::Value value;
2712 case Dali::Actor::Property::PARENT_ORIGIN:
2714 value = GetCurrentParentOrigin();
2718 case Dali::Actor::Property::PARENT_ORIGIN_X:
2720 value = GetCurrentParentOrigin().x;
2724 case Dali::Actor::Property::PARENT_ORIGIN_Y:
2726 value = GetCurrentParentOrigin().y;
2730 case Dali::Actor::Property::PARENT_ORIGIN_Z:
2732 value = GetCurrentParentOrigin().z;
2736 case Dali::Actor::Property::ANCHOR_POINT:
2738 value = GetCurrentAnchorPoint();
2742 case Dali::Actor::Property::ANCHOR_POINT_X:
2744 value = GetCurrentAnchorPoint().x;
2748 case Dali::Actor::Property::ANCHOR_POINT_Y:
2750 value = GetCurrentAnchorPoint().y;
2754 case Dali::Actor::Property::ANCHOR_POINT_Z:
2756 value = GetCurrentAnchorPoint().z;
2760 case Dali::Actor::Property::SIZE:
2762 value = GetCurrentSize();
2766 case Dali::Actor::Property::SIZE_WIDTH:
2768 value = GetCurrentSize().width;
2772 case Dali::Actor::Property::SIZE_HEIGHT:
2774 value = GetCurrentSize().height;
2778 case Dali::Actor::Property::SIZE_DEPTH:
2780 value = GetCurrentSize().depth;
2784 case Dali::Actor::Property::POSITION:
2786 value = GetCurrentPosition();
2790 case Dali::Actor::Property::POSITION_X:
2792 value = GetCurrentPosition().x;
2796 case Dali::Actor::Property::POSITION_Y:
2798 value = GetCurrentPosition().y;
2802 case Dali::Actor::Property::POSITION_Z:
2804 value = GetCurrentPosition().z;
2808 case Dali::Actor::Property::WORLD_POSITION:
2810 value = GetCurrentWorldPosition();
2814 case Dali::Actor::Property::WORLD_POSITION_X:
2816 value = GetCurrentWorldPosition().x;
2820 case Dali::Actor::Property::WORLD_POSITION_Y:
2822 value = GetCurrentWorldPosition().y;
2826 case Dali::Actor::Property::WORLD_POSITION_Z:
2828 value = GetCurrentWorldPosition().z;
2832 case Dali::Actor::Property::ROTATION:
2834 value = GetCurrentRotation();
2838 case Dali::Actor::Property::WORLD_ROTATION:
2840 value = GetCurrentWorldRotation();
2844 case Dali::Actor::Property::SCALE:
2846 value = GetCurrentScale();
2850 case Dali::Actor::Property::SCALE_X:
2852 value = GetCurrentScale().x;
2856 case Dali::Actor::Property::SCALE_Y:
2858 value = GetCurrentScale().y;
2862 case Dali::Actor::Property::SCALE_Z:
2864 value = GetCurrentScale().z;
2868 case Dali::Actor::Property::WORLD_SCALE:
2870 value = GetCurrentWorldScale();
2874 case Dali::Actor::Property::VISIBLE:
2876 value = IsVisible();
2880 case Dali::Actor::Property::COLOR:
2882 value = GetCurrentColor();
2886 case Dali::Actor::Property::COLOR_RED:
2888 value = GetCurrentColor().r;
2892 case Dali::Actor::Property::COLOR_GREEN:
2894 value = GetCurrentColor().g;
2898 case Dali::Actor::Property::COLOR_BLUE:
2900 value = GetCurrentColor().b;
2904 case Dali::Actor::Property::COLOR_ALPHA:
2906 value = GetCurrentColor().a;
2910 case Dali::Actor::Property::WORLD_COLOR:
2912 value = GetCurrentWorldColor();
2916 case Dali::Actor::Property::WORLD_MATRIX:
2918 value = GetCurrentWorldMatrix();
2922 case Dali::Actor::Property::NAME:
2928 case Dali::Actor::Property::SENSITIVE:
2930 value = IsSensitive();
2934 case Dali::Actor::Property::LEAVE_REQUIRED:
2936 value = GetLeaveRequired();
2940 case Dali::Actor::Property::INHERIT_ROTATION:
2942 value = IsRotationInherited();
2946 case Dali::Actor::Property::INHERIT_SCALE:
2948 value = IsScaleInherited();
2952 case Dali::Actor::Property::COLOR_MODE:
2954 value = Scripting::GetColorMode( GetColorMode() );
2958 case Dali::Actor::Property::POSITION_INHERITANCE:
2960 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2964 case Dali::Actor::Property::DRAW_MODE:
2966 value = Scripting::GetDrawMode( GetDrawMode() );
2970 case Dali::Actor::Property::SIZE_MODE:
2972 value = Scripting::GetLinearEnumerationName< SizeMode >( GetSizeMode(), SizeModeTable, SizeModeTableCount );
2976 case Dali::Actor::Property::SIZE_MODE_FACTOR:
2978 value = GetSizeModeFactor();
2984 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2992 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
2997 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2999 // This method should only return an object connected to the scene-graph
3000 return OnStage() ? mNode : NULL;
3003 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3005 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3007 const PropertyBase* property( NULL );
3009 // This method should only return a property of an object connected to the scene-graph
3015 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3017 CustomProperty* custom = FindCustomProperty( index );
3018 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3020 property = custom->GetSceneGraphProperty();
3022 else if( NULL != mNode )
3026 case Dali::Actor::Property::SIZE:
3027 property = &mNode->mSize;
3030 case Dali::Actor::Property::SIZE_WIDTH:
3031 property = &mNode->mSize;
3034 case Dali::Actor::Property::SIZE_HEIGHT:
3035 property = &mNode->mSize;
3038 case Dali::Actor::Property::SIZE_DEPTH:
3039 property = &mNode->mSize;
3042 case Dali::Actor::Property::POSITION:
3043 property = &mNode->mPosition;
3046 case Dali::Actor::Property::POSITION_X:
3047 property = &mNode->mPosition;
3050 case Dali::Actor::Property::POSITION_Y:
3051 property = &mNode->mPosition;
3054 case Dali::Actor::Property::POSITION_Z:
3055 property = &mNode->mPosition;
3058 case Dali::Actor::Property::ROTATION:
3059 property = &mNode->mRotation;
3062 case Dali::Actor::Property::SCALE:
3063 property = &mNode->mScale;
3066 case Dali::Actor::Property::SCALE_X:
3067 property = &mNode->mScale;
3070 case Dali::Actor::Property::SCALE_Y:
3071 property = &mNode->mScale;
3074 case Dali::Actor::Property::SCALE_Z:
3075 property = &mNode->mScale;
3078 case Dali::Actor::Property::VISIBLE:
3079 property = &mNode->mVisible;
3082 case Dali::Actor::Property::COLOR:
3083 property = &mNode->mColor;
3086 case Dali::Actor::Property::COLOR_RED:
3087 property = &mNode->mColor;
3090 case Dali::Actor::Property::COLOR_GREEN:
3091 property = &mNode->mColor;
3094 case Dali::Actor::Property::COLOR_BLUE:
3095 property = &mNode->mColor;
3098 case Dali::Actor::Property::COLOR_ALPHA:
3099 property = &mNode->mColor;
3110 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3112 const PropertyInputImpl* property( NULL );
3114 // This method should only return a property of an object connected to the scene-graph
3120 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3122 CustomProperty* custom = FindCustomProperty( index );
3123 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3124 property = custom->GetSceneGraphProperty();
3126 else if( NULL != mNode )
3130 case Dali::Actor::Property::PARENT_ORIGIN:
3131 property = &mNode->mParentOrigin;
3134 case Dali::Actor::Property::PARENT_ORIGIN_X:
3135 property = &mNode->mParentOrigin;
3138 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3139 property = &mNode->mParentOrigin;
3142 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3143 property = &mNode->mParentOrigin;
3146 case Dali::Actor::Property::ANCHOR_POINT:
3147 property = &mNode->mAnchorPoint;
3150 case Dali::Actor::Property::ANCHOR_POINT_X:
3151 property = &mNode->mAnchorPoint;
3154 case Dali::Actor::Property::ANCHOR_POINT_Y:
3155 property = &mNode->mAnchorPoint;
3158 case Dali::Actor::Property::ANCHOR_POINT_Z:
3159 property = &mNode->mAnchorPoint;
3162 case Dali::Actor::Property::SIZE:
3163 property = &mNode->mSize;
3166 case Dali::Actor::Property::SIZE_WIDTH:
3167 property = &mNode->mSize;
3170 case Dali::Actor::Property::SIZE_HEIGHT:
3171 property = &mNode->mSize;
3174 case Dali::Actor::Property::SIZE_DEPTH:
3175 property = &mNode->mSize;
3178 case Dali::Actor::Property::POSITION:
3179 property = &mNode->mPosition;
3182 case Dali::Actor::Property::POSITION_X:
3183 property = &mNode->mPosition;
3186 case Dali::Actor::Property::POSITION_Y:
3187 property = &mNode->mPosition;
3190 case Dali::Actor::Property::POSITION_Z:
3191 property = &mNode->mPosition;
3194 case Dali::Actor::Property::WORLD_POSITION:
3195 property = &mNode->mWorldPosition;
3198 case Dali::Actor::Property::WORLD_POSITION_X:
3199 property = &mNode->mWorldPosition;
3202 case Dali::Actor::Property::WORLD_POSITION_Y:
3203 property = &mNode->mWorldPosition;
3206 case Dali::Actor::Property::WORLD_POSITION_Z:
3207 property = &mNode->mWorldPosition;
3210 case Dali::Actor::Property::ROTATION:
3211 property = &mNode->mRotation;
3214 case Dali::Actor::Property::WORLD_ROTATION:
3215 property = &mNode->mWorldRotation;
3218 case Dali::Actor::Property::SCALE:
3219 property = &mNode->mScale;
3222 case Dali::Actor::Property::SCALE_X:
3223 property = &mNode->mScale;
3226 case Dali::Actor::Property::SCALE_Y:
3227 property = &mNode->mScale;
3230 case Dali::Actor::Property::SCALE_Z:
3231 property = &mNode->mScale;
3234 case Dali::Actor::Property::WORLD_SCALE:
3235 property = &mNode->mWorldScale;
3238 case Dali::Actor::Property::VISIBLE:
3239 property = &mNode->mVisible;
3242 case Dali::Actor::Property::COLOR:
3243 property = &mNode->mColor;
3246 case Dali::Actor::Property::COLOR_RED:
3247 property = &mNode->mColor;
3250 case Dali::Actor::Property::COLOR_GREEN:
3251 property = &mNode->mColor;
3254 case Dali::Actor::Property::COLOR_BLUE:
3255 property = &mNode->mColor;
3258 case Dali::Actor::Property::COLOR_ALPHA:
3259 property = &mNode->mColor;
3262 case Dali::Actor::Property::WORLD_COLOR:
3263 property = &mNode->mWorldColor;
3266 case Dali::Actor::Property::WORLD_MATRIX:
3267 property = &mNode->mWorldMatrix;
3278 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3280 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3284 case Dali::Actor::Property::PARENT_ORIGIN_X:
3285 case Dali::Actor::Property::ANCHOR_POINT_X:
3286 case Dali::Actor::Property::SIZE_WIDTH:
3287 case Dali::Actor::Property::POSITION_X:
3288 case Dali::Actor::Property::WORLD_POSITION_X:
3289 case Dali::Actor::Property::SCALE_X:
3290 case Dali::Actor::Property::COLOR_RED:
3296 case Dali::Actor::Property::PARENT_ORIGIN_Y:
3297 case Dali::Actor::Property::ANCHOR_POINT_Y:
3298 case Dali::Actor::Property::SIZE_HEIGHT:
3299 case Dali::Actor::Property::POSITION_Y:
3300 case Dali::Actor::Property::WORLD_POSITION_Y:
3301 case Dali::Actor::Property::SCALE_Y:
3302 case Dali::Actor::Property::COLOR_GREEN:
3308 case Dali::Actor::Property::PARENT_ORIGIN_Z:
3309 case Dali::Actor::Property::ANCHOR_POINT_Z:
3310 case Dali::Actor::Property::SIZE_DEPTH:
3311 case Dali::Actor::Property::POSITION_Z:
3312 case Dali::Actor::Property::WORLD_POSITION_Z:
3313 case Dali::Actor::Property::SCALE_Z:
3314 case Dali::Actor::Property::COLOR_BLUE:
3320 case Dali::Actor::Property::COLOR_ALPHA:
3333 return componentIndex;
3336 void Actor::SetParent(Actor* parent, int index)
3340 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3344 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3347 // Instruct each actor to create a corresponding node in the scene graph
3348 ConnectToStage( index );
3351 else // parent being set to NULL
3353 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3357 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3360 DALI_ASSERT_ALWAYS(mNode != NULL);
3364 // Disconnect the Node & its children from the scene-graph.
3365 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3368 // Instruct each actor to discard pointers to the scene-graph
3369 DisconnectFromStage();
3374 SceneGraph::Node* Actor::CreateNode() const
3379 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
3382 Actor* actor = dynamic_cast<Actor*>( object );
3386 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3388 actor->SetVisible(true);
3391 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3393 actor->SetVisible(false);
3401 } // namespace Internal