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/actor-attachments/renderer-attachment-impl.h>
43 #include <dali/internal/event/animation/constraint-impl.h>
44 #include <dali/internal/event/common/projection.h>
45 #include <dali/internal/update/common/animatable-property.h>
46 #include <dali/internal/update/nodes/node-messages.h>
47 #include <dali/internal/update/nodes/node-declarations.h>
48 #include <dali/internal/update/animation/scene-graph-constraint.h>
49 #include <dali/internal/event/events/actor-gesture-data.h>
50 #include <dali/internal/common/message.h>
51 #include <dali/integration-api/debug.h>
53 #ifdef DYNAMICS_SUPPORT
54 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
60 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::AnimatableProperty;
62 using Dali::Internal::SceneGraph::PropertyBase;
70 unsigned int Actor::mActorCounter = 0;
71 ActorContainer Actor::mNullChildren;
73 #ifdef DYNAMICS_SUPPORT
75 // Encapsulate actor related dynamics data
78 DynamicsData( Actor* slotOwner )
79 : slotDelegate( slotOwner )
83 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
84 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
87 JointContainer joints;
88 ReferencedJointContainer referencedJoints;
90 SlotDelegate< Actor > slotDelegate;
93 #endif // DYNAMICS_SUPPORT
95 namespace // unnamed namespace
101 * We want to discourage the use of property strings (minimize string comparisons),
102 * particularly for the default properties.
103 * Name Type writable animatable constraint-input enum for index-checking
105 DALI_PROPERTY_TABLE_BEGIN
106 DALI_PROPERTY( "parent-origin", VECTOR3, true, false, true, Dali::Actor::Property::ParentOrigin )
107 DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::ParentOriginX )
108 DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::ParentOriginY )
109 DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::ParentOriginZ )
110 DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::AnchorPoint )
111 DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::AnchorPointX )
112 DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::AnchorPointY )
113 DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::AnchorPointZ )
114 DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::Size )
115 DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SizeWidth )
116 DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SizeHeight )
117 DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SizeDepth )
118 DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::Position )
119 DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::PositionX )
120 DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::PositionY )
121 DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::PositionZ )
122 DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WorldPosition )
123 DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WorldPositionX )
124 DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WorldPositionY )
125 DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WorldPositionZ )
126 DALI_PROPERTY( "rotation", ROTATION, true, true, true, Dali::Actor::Property::Rotation )
127 DALI_PROPERTY( "world-rotation", ROTATION, false, false, true, Dali::Actor::Property::WorldRotation )
128 DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::Scale )
129 DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::ScaleX )
130 DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::ScaleY )
131 DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::ScaleZ )
132 DALI_PROPERTY( "world-scale", VECTOR3, false, false, true, Dali::Actor::Property::WorldScale )
133 DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::Visible )
134 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::Color )
135 DALI_PROPERTY( "color-red", FLOAT, true, true, true, Dali::Actor::Property::ColorRed )
136 DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::ColorGreen )
137 DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::ColorBlue )
138 DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::ColorAlpha )
139 DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WorldColor )
140 DALI_PROPERTY( "world-matrix", MATRIX, false, false, true, Dali::Actor::Property::WorldMatrix )
141 DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::Name )
142 DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::Sensitive )
143 DALI_PROPERTY( "leave-required", BOOLEAN, true, false, false, Dali::Actor::Property::LeaveRequired )
144 DALI_PROPERTY( "inherit-rotation", BOOLEAN, true, false, false, Dali::Actor::Property::InheritRotation )
145 DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::InheritScale )
146 DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::ColorMode )
147 DALI_PROPERTY( "position-inheritance", STRING, true, false, false, Dali::Actor::Property::PositionInheritance )
148 DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DrawMode )
149 DALI_PROPERTY( "size-mode", STRING, true, false, false, Dali::Actor::Property::SizeMode )
150 DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SizeModeFactor )
151 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
155 const char* const SIGNAL_TOUCHED = "touched";
156 const char* const SIGNAL_HOVERED = "hovered";
157 const char* const SIGNAL_MOUSE_WHEEL_EVENT = "mouse-wheel-event";
158 const char* const SIGNAL_ON_STAGE = "on-stage";
159 const char* const SIGNAL_OFF_STAGE = "off-stage";
163 const char* const ACTION_SHOW = "show";
164 const char* const ACTION_HIDE = "hide";
166 // Enumeration to / from string conversion tables
168 DALI_ENUM_TO_STRING_TABLE_BEGIN( SizeMode )
169 DALI_ENUM_TO_STRING( USE_OWN_SIZE )
170 DALI_ENUM_TO_STRING( SIZE_EQUAL_TO_PARENT )
171 DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT )
172 DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT )
173 DALI_ENUM_TO_STRING_TABLE_END( SizeMode )
175 BaseHandle CreateActor()
177 return Dali::Actor::New();
180 TypeRegistration mType( typeid( Dali::Actor ), typeid( Dali::Handle ), CreateActor );
182 SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
183 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
184 SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
185 SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
187 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
188 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
190 } // unnamed namespace
192 ActorPtr Actor::New()
194 ActorPtr actor( new Actor( BASIC ) );
196 // Second-phase construction
202 const std::string& Actor::GetName() const
207 void Actor::SetName(const std::string& name)
213 // ATTENTION: string for debug purposes is not thread safe.
214 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
218 unsigned int Actor::GetId() const
223 void Actor::Attach( ActorAttachment& attachment )
225 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
229 attachment.Connect();
232 mAttachment = ActorAttachmentPtr(&attachment);
235 ActorAttachmentPtr Actor::GetAttachment()
240 bool Actor::OnStage() const
245 Dali::Layer Actor::GetLayer()
249 // Short-circuit for Layer derived actors
252 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
255 // Find the immediate Layer parent
256 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
258 if( parent->IsLayer() )
260 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
267 void Actor::Add(Actor& child)
269 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
270 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
274 mChildren = new ActorContainer;
277 Actor* const oldParent( child.mParent );
279 // child might already be ours
280 if( this != oldParent )
282 // if we already have parent, unparent us first
285 oldParent->Remove( child ); // This causes OnChildRemove callback
288 // Guard against Add() during previous OnChildRemove callback
289 if ( !child.mParent )
291 // Do this first, since user callbacks from within SetParent() may need to remove child
292 mChildren->push_back(Dali::Actor(&child));
294 // SetParent asserts that child can be added
295 child.SetParent(this);
297 // Notification for derived classes
303 void Actor::Insert(unsigned int index, Actor& child)
305 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
306 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
310 mChildren = new ActorContainer;
313 Actor* const oldParent( child.mParent );
315 // since an explicit position has been given, always insert, even if already a child
318 oldParent->Remove( child ); // This causes OnChildRemove callback
321 // Guard against Add() during previous OnChildRemove callback
322 if ( !child.mParent )
324 // Do this first, since user callbacks from within SetParent() may need to remove child
325 if (index < GetChildCount())
327 ActorIter it = mChildren->begin();
328 std::advance(it, index);
329 mChildren->insert(it, Dali::Actor(&child));
333 mChildren->push_back(Dali::Actor(&child));
335 // SetParent asserts that child can be added
336 child.SetParent(this, index);
338 // Notification for derived classes
343 void Actor::Remove(Actor& child)
345 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
355 // Find the child in mChildren, and unparent it
356 ActorIter end = mChildren->end();
357 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
359 Actor& actor = GetImplementation(*iter);
361 if( &actor == &child )
363 // Keep handle for OnChildRemove notification
364 removed = Dali::Actor( &actor );
366 // Do this first, since user callbacks from within SetParent() may need to add the child
367 mChildren->erase(iter);
369 DALI_ASSERT_DEBUG( actor.GetParent() == this );
370 actor.SetParent( NULL );
378 // Notification for derived classes
379 OnChildRemove( GetImplementation(removed) );
383 void Actor::Unparent()
387 mParent->Remove( *this );
391 unsigned int Actor::GetChildCount() const
393 return ( NULL != mChildren ) ? mChildren->size() : 0;
396 Dali::Actor Actor::GetChildAt(unsigned int index) const
398 DALI_ASSERT_ALWAYS( index < GetChildCount() );
400 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
403 ActorContainer Actor::GetChildren()
405 if( NULL != mChildren )
410 // return copy of mNullChildren
411 return mNullChildren;
414 const ActorContainer& Actor::GetChildren() const
416 if( NULL != mChildren )
421 // return const reference to mNullChildren
422 return mNullChildren;
425 ActorPtr Actor::FindChildByName(const std::string& actorName)
428 if (actorName == mName)
434 ActorIter end = mChildren->end();
435 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
437 child = GetImplementation(*iter).FindChildByName(actorName);
448 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
450 Dali::Actor child = DoGetChildByAlias(actorAlias);
452 // If not found then search by name.
455 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
458 child = Dali::Actor(child_ptr.Get());
465 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
467 Dali::Actor child = GetChildByAlias(actorAlias);
469 if (!child && mChildren )
471 ActorIter end = mChildren->end();
472 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
474 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
486 ActorPtr Actor::FindChildById(const unsigned int id)
495 ActorIter end = mChildren->end();
496 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
498 child = GetImplementation(*iter).FindChildById(id);
509 void Actor::SetParentOrigin( const Vector3& origin )
513 // mNode is being used in a separate thread; queue a message to set the value & base value
514 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
517 // Cache for event-thread access
520 // not allocated, check if different from default
521 if( ParentOrigin::DEFAULT != origin )
523 mParentOrigin = new Vector3( origin );
528 // check if different from current costs more than just set
529 *mParentOrigin = origin;
533 void Actor::SetParentOriginX( float x )
535 const Vector3& current = GetCurrentParentOrigin();
537 SetParentOrigin( Vector3( x, current.y, current.z ) );
540 void Actor::SetParentOriginY( float y )
542 const Vector3& current = GetCurrentParentOrigin();
544 SetParentOrigin( Vector3( current.x, y, current.z ) );
547 void Actor::SetParentOriginZ( float z )
549 const Vector3& current = GetCurrentParentOrigin();
551 SetParentOrigin( Vector3( current.x, current.y, z ) );
554 const Vector3& Actor::GetCurrentParentOrigin() const
556 // Cached for event-thread access
557 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
560 void Actor::SetAnchorPoint(const Vector3& anchor)
564 // mNode is being used in a separate thread; queue a message to set the value & base value
565 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
568 // Cache for event-thread access
571 // not allocated, check if different from default
572 if( AnchorPoint::DEFAULT != anchor )
574 mAnchorPoint = new Vector3( anchor );
579 // check if different from current costs more than just set
580 *mAnchorPoint = anchor;
584 void Actor::SetAnchorPointX( float x )
586 const Vector3& current = GetCurrentAnchorPoint();
588 SetAnchorPoint( Vector3( x, current.y, current.z ) );
591 void Actor::SetAnchorPointY( float y )
593 const Vector3& current = GetCurrentAnchorPoint();
595 SetAnchorPoint( Vector3( current.x, y, current.z ) );
598 void Actor::SetAnchorPointZ( float z )
600 const Vector3& current = GetCurrentAnchorPoint();
602 SetAnchorPoint( Vector3( current.x, current.y, z ) );
605 const Vector3& Actor::GetCurrentAnchorPoint() const
607 // Cached for event-thread access
608 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
611 void Actor::SetPosition(float x, float y)
613 SetPosition(Vector3(x, y, 0.0f));
616 void Actor::SetPosition(float x, float y, float z)
618 SetPosition(Vector3(x, y, z));
621 void Actor::SetPosition(const Vector3& position)
625 // mNode is being used in a separate thread; queue a message to set the value & base value
626 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
630 void Actor::SetX(float x)
634 // mNode is being used in a separate thread; queue a message to set the value & base value
635 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
639 void Actor::SetY(float y)
643 // mNode is being used in a separate thread; queue a message to set the value & base value
644 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
648 void Actor::SetZ(float z)
652 // mNode is being used in a separate thread; queue a message to set the value & base value
653 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
657 void Actor::MoveBy(const Vector3& distance)
661 // mNode is being used in a separate thread; queue a message to set the value & base value
662 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
666 const Vector3& Actor::GetCurrentPosition() const
670 // mNode is being used in a separate thread; copy the value from the previous update
671 return mNode->GetPosition(mStage->GetEventBufferIndex());
674 return Vector3::ZERO;
677 const Vector3& Actor::GetCurrentWorldPosition() const
681 // mNode is being used in a separate thread; copy the value from the previous update
682 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
685 return Vector3::ZERO;
688 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
690 // this flag is not animatable so keep the value
691 mPositionInheritanceMode = mode;
694 // mNode is being used in a separate thread; queue a message to set the value
695 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
699 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
701 // Cached for event-thread access
702 return mPositionInheritanceMode;
705 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
707 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
708 normalizedAxis.Normalize();
710 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
712 SetRotation(rotation);
715 void Actor::SetRotation(const Quaternion& rotation)
719 // mNode is being used in a separate thread; queue a message to set the value & base value
720 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
724 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
728 // mNode is being used in a separate thread; queue a message to set the value & base value
729 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
733 void Actor::RotateBy(const Quaternion& relativeRotation)
737 // mNode is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
742 const Quaternion& Actor::GetCurrentRotation() const
746 // mNode is being used in a separate thread; copy the value from the previous update
747 return mNode->GetRotation(mStage->GetEventBufferIndex());
750 return Quaternion::IDENTITY;
753 const Quaternion& Actor::GetCurrentWorldRotation() const
757 // mNode is being used in a separate thread; copy the value from the previous update
758 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
761 return Quaternion::IDENTITY;
764 void Actor::SetScale(float scale)
766 SetScale(Vector3(scale, scale, scale));
769 void Actor::SetScale(float x, float y, float z)
771 SetScale(Vector3(x, y, z));
774 void Actor::SetScale(const Vector3& scale)
778 // mNode is being used in a separate thread; queue a message to set the value & base value
779 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
783 void Actor::SetScaleX( float x )
787 // mNode is being used in a separate thread; queue a message to set the value & base value
788 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
792 void Actor::SetScaleY( float y )
796 // mNode is being used in a separate thread; queue a message to set the value & base value
797 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
801 void Actor::SetScaleZ( float z )
805 // mNode is being used in a separate thread; queue a message to set the value & base value
806 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
810 void Actor::ScaleBy(const Vector3& relativeScale)
814 // mNode is being used in a separate thread; queue a message to set the value & base value
815 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
819 const Vector3& Actor::GetCurrentScale() const
823 // mNode is being used in a separate thread; copy the value from the previous update
824 return mNode->GetScale(mStage->GetEventBufferIndex());
830 const Vector3& Actor::GetCurrentWorldScale() const
834 // mNode is being used in a separate thread; copy the value from the previous update
835 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
841 void Actor::SetInheritScale( bool inherit )
843 // non animateable so keep local copy
844 mInheritScale = inherit;
847 // mNode is being used in a separate thread; queue a message to set the value
848 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
852 bool Actor::IsScaleInherited() const
854 return mInheritScale;
857 Matrix Actor::GetCurrentWorldMatrix() const
861 // World matrix is no longer updated unless there is something observing the node.
862 // Need to calculate it from node's world position, rotation and scale:
863 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
864 Matrix worldMatrix(false);
865 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
866 mNode->GetWorldRotation( updateBufferIndex ),
867 mNode->GetWorldPosition( updateBufferIndex ) );
871 return Matrix::IDENTITY;
874 void Actor::SetVisible(bool visible)
878 // mNode is being used in a separate thread; queue a message to set the value & base value
879 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
883 bool Actor::IsVisible() const
887 // mNode is being used in a separate thread; copy the value from the previous update
888 return mNode->IsVisible( mStage->GetEventBufferIndex() );
894 void Actor::SetOpacity(float opacity)
898 // mNode is being used in a separate thread; queue a message to set the value & base value
899 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
903 void Actor::OpacityBy(float relativeOpacity)
907 // mNode is being used in a separate thread; queue a message to set the value & base value
908 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
912 float Actor::GetCurrentOpacity() const
916 // mNode is being used in a separate thread; copy the value from the previous update
917 return mNode->GetOpacity(mStage->GetEventBufferIndex());
923 const Vector4& Actor::GetCurrentWorldColor() const
927 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
933 void Actor::SetColor(const Vector4& color)
937 // mNode is being used in a separate thread; queue a message to set the value & base value
938 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
942 void Actor::SetColorRed( float red )
946 // mNode is being used in a separate thread; queue a message to set the value & base value
947 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
951 void Actor::SetColorGreen( float green )
955 // mNode is being used in a separate thread; queue a message to set the value & base value
956 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
960 void Actor::SetColorBlue( float blue )
964 // mNode is being used in a separate thread; queue a message to set the value & base value
965 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
969 void Actor::ColorBy(const Vector4& relativeColor)
973 // mNode is being used in a separate thread; queue a message to set the value & base value
974 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
978 const Vector4& Actor::GetCurrentColor() const
982 // mNode is being used in a separate thread; copy the value from the previous update
983 return mNode->GetColor(mStage->GetEventBufferIndex());
989 void Actor::SetInheritRotation(bool inherit)
991 // non animateable so keep local copy
992 mInheritRotation = inherit;
995 // mNode is being used in a separate thread; queue a message to set the value
996 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1000 bool Actor::IsRotationInherited() const
1002 return mInheritRotation;
1005 void Actor::SetSizeMode(SizeMode mode)
1007 // non animateable so keep local copy
1011 // mNode is being used in a separate thread; queue a message to set the value
1012 SetSizeModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
1016 void Actor::SetSizeModeFactor(const Vector3& factor)
1018 // non animateable so keep local copy
1019 mSizeModeFactor = factor;
1022 // mNode is being used in a separate thread; queue a message to set the value
1023 SetSizeModeFactorMessage( mStage->GetUpdateInterface(), *mNode, factor );
1027 SizeMode Actor::GetSizeMode() const
1032 const Vector3& Actor::GetSizeModeFactor() const
1034 return mSizeModeFactor;
1037 void Actor::SetColorMode(ColorMode colorMode)
1039 // non animateable so keep local copy
1040 mColorMode = colorMode;
1043 // mNode is being used in a separate thread; queue a message to set the value
1044 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1048 ColorMode Actor::GetColorMode() const
1050 // we have cached copy
1054 void Actor::SetSize(float width, float height)
1056 SetSize( Vector2( width, height ) );
1059 void Actor::SetSize(float width, float height, float depth)
1061 SetSize( Vector3( width, height, depth ) );
1064 void Actor::SetSize(const Vector2& size)
1066 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1069 float Actor::CalculateSizeZ( const Vector2& size ) const
1071 return std::min( size.width, size.height );
1074 void Actor::SetSize(const Vector3& size)
1080 // mNode is being used in a separate thread; queue a message to set the value & base value
1081 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1083 // Notification for derived classes
1088 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1092 // Notify deriving classes
1093 OnSizeAnimation( animation, targetSize );
1096 void Actor::SetWidth( float width )
1100 // mNode is being used in a separate thread; queue a message to set the value & base value
1101 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1105 void Actor::SetHeight( float height )
1109 // mNode is being used in a separate thread; queue a message to set the value & base value
1110 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1114 void Actor::SetDepth( float depth )
1118 // mNode is being used in a separate thread; queue a message to set the value & base value
1119 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1123 const Vector3& Actor::GetSize() const
1128 const Vector3& Actor::GetCurrentSize() const
1132 // mNode is being used in a separate thread; copy the value from the previous update
1133 return mNode->GetSize( mStage->GetEventBufferIndex() );
1136 return Vector3::ZERO;
1139 Vector3 Actor::GetNaturalSize() const
1141 // It is up to deriving classes to return the appropriate natural size
1142 return Vector3( 0.0f, 0.0f, 0.0f );
1145 unsigned int Actor::AddRenderer( Renderer& renderer )
1147 //TODO: MESH_REWORK : Check this
1148 //TODO: MESH_REWORK : Add support for multiple renderers
1149 if ( ! mAttachment )
1151 mAttachment = RendererAttachment::New( *mStage, *mNode, renderer );
1157 unsigned int Actor::GetRendererCount() const
1159 //TODO: MESH_REWORK : Check this
1160 //TODO: MESH_REWORK : Add support for multiple renderers
1161 RendererAttachment* attachment = dynamic_cast<RendererAttachment*>(mAttachment.Get());
1162 return attachment ? 1u : 0u;
1165 Renderer& Actor::GetRendererAt( unsigned int index )
1167 //TODO: MESH_REWORK : Check this
1168 //TODO: MESH_REWORK : Add support for multiple renderers
1169 DALI_ASSERT_DEBUG( index == 0 && "Only one renderer is supported." );
1171 //TODO: MESH_REWORK : Temporary code
1172 RendererAttachment* attachment = dynamic_cast<RendererAttachment*>(mAttachment.Get());
1173 DALI_ASSERT_ALWAYS( attachment && "Actor doesn't have a renderer" );
1175 return attachment->GetRenderer();
1178 void Actor::RemoveRenderer( Renderer& renderer )
1180 //TODO: MESH_REWORK : Check this
1181 //TODO: MESH_REWORK : Add support for multiple renderers
1185 void Actor::RemoveRenderer( unsigned int index )
1187 //TODO: MESH_REWORK : Check this
1188 //TODO: MESH_REWORK : Add support for multiple renderers
1192 #ifdef DYNAMICS_SUPPORT
1194 //--------------- Dynamics ---------------
1196 void Actor::DisableDynamics()
1198 if( NULL != mDynamicsData )
1200 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1202 // ensure dynamics object are disconnected from scene
1203 DisconnectDynamics();
1205 // delete joint owned by this actor
1206 while( !mDynamicsData->joints.empty() )
1208 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1211 // delete other joints referencing this actor
1212 while( !mDynamicsData->referencedJoints.empty() )
1214 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1215 ActorPtr jointOwner( joint->GetActor( true ) );
1218 jointOwner->RemoveDynamicsJoint( joint );
1222 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1225 // delete the DynamicsBody object
1226 mDynamicsData->body.Reset();
1228 // Discard Dynamics data structure
1229 delete mDynamicsData;
1230 mDynamicsData = NULL;
1234 DynamicsBodyPtr Actor::GetDynamicsBody() const
1236 DynamicsBodyPtr body;
1238 if( NULL != mDynamicsData )
1240 body = mDynamicsData->body;
1246 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1248 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1250 if( NULL == mDynamicsData )
1252 mDynamicsData = new DynamicsData( this );
1255 if( !mDynamicsData->body )
1257 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1261 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1264 if( mParent == world->GetRootActor().Get() )
1266 mDynamicsData->body->Connect(*mStage);
1272 return mDynamicsData->body;
1275 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1277 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1278 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1281 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1283 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1284 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1286 DynamicsJointPtr joint;
1288 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1292 if( NULL != mDynamicsData )
1294 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1296 if( mDynamicsData->joints.end() != it )
1298 // use existing joint
1304 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1305 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1309 bodyA = EnableDynamics( new DynamicsBodyConfig );
1314 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1317 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1318 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1320 if( OnStage() && attachedActor->OnStage() )
1322 joint->Connect(*mStage);
1325 attachedActor->ReferenceJoint( joint );
1327 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1328 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1335 const int Actor::GetNumberOfJoints() const
1337 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1340 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1342 DynamicsJointPtr joint;
1344 if( NULL != mDynamicsData )
1346 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1348 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1350 for( int i = 0; i < index; ++i )
1362 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1364 DynamicsJointPtr joint;
1366 if( NULL != mDynamicsData )
1368 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1370 if( mDynamicsData->joints.end() != it )
1372 // use existing joint
1380 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1382 if( NULL != mDynamicsData )
1384 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1385 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1387 for( ; it != endIt; ++it )
1389 if( it->second == joint.Get() )
1391 ActorPtr attachedActor( it->first );
1393 if( OnStage() && attachedActor && attachedActor->OnStage() )
1395 joint->Disconnect(*mStage);
1400 attachedActor->ReleaseJoint( joint );
1401 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1402 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1405 mDynamicsData->joints.erase(it);
1412 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1414 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1416 if( NULL != mDynamicsData )
1418 mDynamicsData->referencedJoints.push_back(joint);
1422 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1424 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1426 if( NULL != mDynamicsData )
1428 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1430 if( it != mDynamicsData->referencedJoints.end() )
1432 mDynamicsData->referencedJoints.erase( it );
1437 void Actor::SetDynamicsRoot(bool flag)
1439 if( mIsDynamicsRoot != flag )
1441 mIsDynamicsRoot = flag;
1443 if( OnStage() && mChildren )
1445 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1446 ActorIter end = mChildren->end();
1447 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1449 Actor& child = GetImplementation(*iter);
1451 if( child.GetDynamicsBody() )
1453 if( mIsDynamicsRoot )
1455 child.ConnectDynamics();
1459 child.DisconnectDynamics();
1467 bool Actor::IsDynamicsRoot() const
1469 return mIsDynamicsRoot;
1472 void Actor::AttachedActorOnStage( Dali::Actor actor )
1474 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1478 ActorPtr attachedActor( &GetImplementation(actor) );
1480 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1481 if( NULL != mDynamicsData )
1483 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1484 if( mDynamicsData->joints.end() != it )
1486 DynamicsJointPtr joint( it->second );
1487 joint->Connect(*mStage);
1493 void Actor::AttachedActorOffStage( Dali::Actor actor )
1495 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1499 ActorPtr attachedActor( &GetImplementation(actor) );
1501 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1502 if( NULL != mDynamicsData )
1504 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1505 if( mDynamicsData->joints.end() != it )
1507 DynamicsJointPtr joint( it->second );
1508 joint->Disconnect(*mStage);
1514 void Actor::ConnectDynamics()
1516 if( NULL != mDynamicsData && mDynamicsData->body )
1518 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1520 mDynamicsData->body->Connect(*mStage);
1522 // Connect all joints where attachedActor is also on stage
1523 if( !mDynamicsData->joints.empty() )
1525 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1526 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1528 for( ; it != endIt; ++it )
1530 Actor* attachedActor( it->first );
1531 if( NULL != attachedActor && attachedActor->OnStage() )
1533 DynamicsJointPtr joint( it->second );
1535 joint->Connect(*mStage);
1543 void Actor::DisconnectDynamics()
1545 if( NULL != mDynamicsData && mDynamicsData->body )
1549 mDynamicsData->body->Disconnect(*mStage);
1551 // Disconnect all joints
1552 if( !mDynamicsData->joints.empty() )
1554 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1555 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1557 for( ; it != endIt; ++it )
1559 DynamicsJointPtr joint( it->second );
1561 joint->Disconnect(*mStage);
1568 #endif // DYNAMICS_SUPPORT
1570 void Actor::SetOverlay(bool enable)
1572 // Setting STENCIL will override OVERLAY
1573 if( DrawMode::STENCIL != mDrawMode )
1575 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1579 bool Actor::IsOverlay() const
1581 return ( DrawMode::OVERLAY == mDrawMode );
1584 void Actor::SetDrawMode( DrawMode::Type drawMode )
1586 // this flag is not animatable so keep the value
1587 mDrawMode = drawMode;
1590 // mNode is being used in a separate thread; queue a message to set the value
1591 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1595 DrawMode::Type Actor::GetDrawMode() const
1600 bool Actor::ScreenToLocal( float& localX,
1603 float screenY ) const
1605 // only valid when on-stage
1608 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1610 Vector2 converted( screenX, screenY );
1612 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1613 const int taskCount = taskList.GetTaskCount();
1614 for( int i = taskCount - 1; i >= 0; --i )
1616 Dali::RenderTask task = taskList.GetTask( i );
1617 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1619 // found a task where this conversion was ok so return
1627 bool Actor::ScreenToLocal( RenderTask& renderTask,
1631 float screenY ) const
1633 bool retval = false;
1634 // only valid when on-stage
1637 CameraActor* camera = renderTask.GetCameraActor();
1641 renderTask.GetViewport( viewport );
1643 // need to translate coordinates to render tasks coordinate space
1644 Vector2 converted( screenX, screenY );
1645 if( renderTask.TranslateCoordinates( converted ) )
1647 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1654 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1655 const Matrix& projectionMatrix,
1656 const Viewport& viewport,
1660 float screenY ) const
1662 // Early-out if mNode is NULL
1668 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1670 // Calculate the ModelView matrix
1671 Matrix modelView(false/*don't init*/);
1672 // need to use the components as world matrix is only updated for actors that need it
1673 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1674 Matrix::Multiply(modelView, modelView, viewMatrix);
1676 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1677 Matrix invertedMvp(false/*don't init*/);
1678 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1679 bool success = invertedMvp.Invert();
1681 // Convert to GL coordinates
1682 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1687 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1694 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1700 if (XyPlaneIntersect(nearPos, farPos, local))
1702 Vector3 size = GetCurrentSize();
1703 localX = local.x + size.x * 0.5f;
1704 localY = local.y + size.y * 0.5f;
1715 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1718 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1720 Mathematical Formulation
1722 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1724 ( p - c ) dot ( p - c ) = r^2
1726 Given a ray with a point of origin 'o', and a direction vector 'd':
1728 ray(t) = o + td, t >= 0
1730 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1732 (o + td - c ) dot ( o + td - c ) = r^2
1734 To solve for t we first expand the above into a more recognisable quadratic equation form
1736 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1745 B = 2( o - c ) dot d
1746 C = ( o - c ) dot ( o - c ) - r^2
1748 which can be solved using a standard quadratic formula.
1750 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1752 Practical Simplification
1754 In a renderer, we often differentiate between world space and object space. In the object space
1755 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1756 into object space, the mathematical solution presented above can be simplified significantly.
1758 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1762 and we can find the t at which the (transformed) ray intersects the sphere by
1764 ( o + td ) dot ( o + td ) = r^2
1766 According to the reasoning above, we expand the above quadratic equation into the general form
1770 which now has coefficients:
1777 // Early out if mNode is NULL
1783 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1785 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1786 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1787 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1788 rayOrigin.y - translation.y,
1789 rayOrigin.z - translation.z);
1791 // Compute the radius is not needed, square radius it's enough.
1792 const Vector3& size( mNode->GetSize( bufferIndex ) );
1794 // Scale the sphere.
1795 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1797 const float width = size.width * scale.width;
1798 const float height = size.height * scale.height;
1800 float squareSphereRadius = 0.5f * ( width * width + height * height );
1802 float a = rayDir.Dot( rayDir ); // a
1803 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1804 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1806 return ( b2*b2 - a*c ) >= 0.f;
1809 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1816 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1818 // Transforms the ray to the local reference system.
1820 // Calculate the inverse of Model matrix
1821 Matrix invModelMatrix(false/*don't init*/);
1822 // need to use the components as world matrix is only updated for actors that need it
1823 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1825 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1826 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1828 // Test with the actor's XY plane (Normal = 0 0 1 1).
1830 float a = -rayOriginLocal.z;
1831 float b = rayDirLocal.z;
1833 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1835 // Ray travels distance * rayDirLocal to intersect with plane.
1838 const Vector3& size = mNode->GetSize( bufferIndex );
1840 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1841 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1843 // Test with the actor's geometry.
1844 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1851 void Actor::SetLeaveRequired(bool required)
1853 mLeaveRequired = required;
1856 bool Actor::GetLeaveRequired() const
1858 return mLeaveRequired;
1861 void Actor::SetKeyboardFocusable( bool focusable )
1863 mKeyboardFocusable = focusable;
1866 bool Actor::IsKeyboardFocusable() const
1868 return mKeyboardFocusable;
1871 bool Actor::GetTouchRequired() const
1873 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1876 bool Actor::GetHoverRequired() const
1878 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1881 bool Actor::GetMouseWheelEventRequired() const
1883 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1886 bool Actor::IsHittable() const
1888 return IsSensitive() &&
1890 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1894 ActorGestureData& Actor::GetGestureData()
1896 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1897 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1898 if ( NULL == mGestureData )
1900 mGestureData = new ActorGestureData;
1902 return *mGestureData;
1905 bool Actor::IsGestureRequred( Gesture::Type type ) const
1907 return mGestureData && mGestureData->IsGestureRequred( type );
1910 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1912 bool consumed = false;
1914 if ( !mTouchedSignal.Empty() )
1916 Dali::Actor handle( this );
1917 consumed = mTouchedSignal.Emit( handle, event );
1922 // Notification for derived classes
1923 consumed = OnTouchEvent( event );
1929 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1931 bool consumed = false;
1933 if ( !mHoveredSignal.Empty() )
1935 Dali::Actor handle( this );
1936 consumed = mHoveredSignal.Emit( handle, event );
1941 // Notification for derived classes
1942 consumed = OnHoverEvent( event );
1948 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1950 bool consumed = false;
1952 if ( !mMouseWheelEventSignal.Empty() )
1954 Dali::Actor handle( this );
1955 consumed = mMouseWheelEventSignal.Emit( handle, event );
1960 // Notification for derived classes
1961 consumed = OnMouseWheelEvent(event);
1967 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1969 return mTouchedSignal;
1972 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1974 return mHoveredSignal;
1977 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1979 return mMouseWheelEventSignal;
1982 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1984 return mOnStageSignal;
1987 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1989 return mOffStageSignal;
1992 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1994 bool connected( true );
1995 Actor* actor = dynamic_cast<Actor*>( object );
1997 if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
1999 actor->TouchedSignal().Connect( tracker, functor );
2001 else if( 0 == strcmp( signalName.c_str(), SIGNAL_HOVERED ) )
2003 actor->HoveredSignal().Connect( tracker, functor );
2005 else if( 0 == strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) )
2007 actor->MouseWheelEventSignal().Connect( tracker, functor );
2009 else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
2011 actor->OnStageSignal().Connect( tracker, functor );
2013 else if( 0 == strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) )
2015 actor->OffStageSignal().Connect( tracker, functor );
2019 // signalName does not match any signal
2026 Actor::Actor( DerivedType derivedType )
2031 mParentOrigin( NULL ),
2032 mAnchorPoint( NULL ),
2033 #ifdef DYNAMICS_SUPPORT
2034 mDynamicsData( NULL ),
2036 mGestureData( NULL ),
2038 mSize( 0.0f, 0.0f, 0.0f ),
2039 mSizeModeFactor( Vector3::ONE ),
2041 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2042 mIsRoot( ROOT_LAYER == derivedType ),
2043 mIsRenderable( RENDERABLE == derivedType ),
2044 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2045 mIsOnStage( false ),
2046 mIsDynamicsRoot(false),
2048 mLeaveRequired( false ),
2049 mKeyboardFocusable( false ),
2050 mDerivedRequiresTouch( false ),
2051 mDerivedRequiresHover( false ),
2052 mDerivedRequiresMouseWheelEvent( false ),
2053 mOnStageSignalled( false ),
2054 mInheritRotation( true ),
2055 mInheritScale( true ),
2056 mDrawMode( DrawMode::NORMAL ),
2057 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2058 mColorMode( Node::DEFAULT_COLOR_MODE ),
2059 mSizeMode( Node::DEFAULT_SIZE_MODE )
2063 void Actor::Initialize()
2065 mStage = Stage::GetCurrent();
2066 DALI_ASSERT_ALWAYS( mStage && "Stage doesn't exist" );
2069 SceneGraph::Node* node = CreateNode();
2071 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2072 mNode = node; // Keep raw-pointer to Node
2076 mStage->RegisterObject( this );
2081 // Remove mParent pointers from children even if we're destroying core,
2082 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2085 ActorConstIter endIter = mChildren->end();
2086 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2088 Actor& actor = GetImplementation( *iter );
2089 actor.SetParent( NULL );
2094 // Guard to allow handle destruction after Core has been destroyed
2095 if( Stage::IsInstalled() )
2099 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2100 mNode = NULL; // Node is about to be destroyed
2103 mStage->UnregisterObject( this );
2106 #ifdef DYNAMICS_SUPPORT
2108 delete mDynamicsData;
2111 // Cleanup optional gesture data
2112 delete mGestureData;
2114 // Cleanup optional parent origin and anchor
2115 delete mParentOrigin;
2116 delete mAnchorPoint;
2119 void Actor::ConnectToStage( int index )
2121 // This container is used instead of walking the Actor hierachy.
2122 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2123 ActorContainer connectionList;
2125 // This stage is atomic i.e. not interrupted by user callbacks
2126 RecursiveConnectToStage( connectionList, index );
2128 // Notify applications about the newly connected actors.
2129 const ActorIter endIter = connectionList.end();
2130 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2132 Actor& actor = GetImplementation(*iter);
2133 actor.NotifyStageConnection();
2137 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2139 DALI_ASSERT_ALWAYS( !OnStage() );
2143 ConnectToSceneGraph(index);
2145 // Notification for internal derived classes
2146 OnStageConnectionInternal();
2148 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2149 connectionList.push_back( Dali::Actor(this) );
2151 // Recursively connect children
2154 ActorConstIter endIter = mChildren->end();
2155 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2157 Actor& actor = GetImplementation( *iter );
2158 actor.RecursiveConnectToStage( connectionList );
2164 * This method is called when the Actor is connected to the Stage.
2165 * The parent must have added its Node to the scene-graph.
2166 * The child must connect its Node to the parent's Node.
2167 * This is resursive; the child calls ConnectToStage() for its children.
2169 void Actor::ConnectToSceneGraph(int index)
2171 DALI_ASSERT_DEBUG( mNode != NULL);
2172 DALI_ASSERT_DEBUG( mParent != NULL);
2173 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2177 // Reparent Node in next Update
2178 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2181 // Notify attachment
2184 mAttachment->Connect();
2187 #ifdef DYNAMICS_SUPPORT
2189 if( NULL != mDynamicsData )
2195 // Notification for Object::Observers
2199 void Actor::NotifyStageConnection()
2201 // Actors can be removed (in a callback), before the on-stage stage is reported.
2202 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2203 if ( OnStage() && !mOnStageSignalled )
2205 // Notification for external (CustomActor) derived classes
2206 OnStageConnectionExternal();
2208 if ( !mOnStageSignal.Empty() )
2210 Dali::Actor handle( this );
2211 mOnStageSignal.Emit( handle );
2214 // Guard against Remove during callbacks
2217 mOnStageSignalled = true; // signal required next time Actor is removed
2222 void Actor::DisconnectFromStage()
2224 // This container is used instead of walking the Actor hierachy.
2225 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2226 ActorContainer disconnectionList;
2228 // This stage is atomic i.e. not interrupted by user callbacks
2229 RecursiveDisconnectFromStage( disconnectionList );
2231 // Notify applications about the newly disconnected actors.
2232 const ActorIter endIter = disconnectionList.end();
2233 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2235 Actor& actor = GetImplementation(*iter);
2236 actor.NotifyStageDisconnection();
2240 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2242 DALI_ASSERT_ALWAYS( OnStage() );
2244 // Recursively disconnect children
2247 ActorConstIter endIter = mChildren->end();
2248 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2250 Actor& actor = GetImplementation( *iter );
2251 actor.RecursiveDisconnectFromStage( disconnectionList );
2255 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2256 disconnectionList.push_back( Dali::Actor(this) );
2258 // Notification for internal derived classes
2259 OnStageDisconnectionInternal();
2261 DisconnectFromSceneGraph();
2267 * This method is called by an actor or its parent, before a node removal message is sent.
2268 * This is recursive; the child calls DisconnectFromStage() for its children.
2270 void Actor::DisconnectFromSceneGraph()
2272 // Notification for Object::Observers
2273 OnSceneObjectRemove();
2275 // Notify attachment
2278 mAttachment->Disconnect();
2281 #ifdef DYNAMICS_SUPPORT
2283 if( NULL != mDynamicsData )
2285 DisconnectDynamics();
2290 void Actor::NotifyStageDisconnection()
2292 // Actors can be added (in a callback), before the off-stage state is reported.
2293 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2294 // only do this step if there is a stage, i.e. Core is not being shut down
2295 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2297 // Notification for external (CustomeActor) derived classes
2298 OnStageDisconnectionExternal();
2300 if( !mOffStageSignal.Empty() )
2302 Dali::Actor handle( this );
2303 mOffStageSignal.Emit( handle );
2306 // Guard against Add during callbacks
2309 mOnStageSignalled = false; // signal required next time Actor is added
2314 bool Actor::IsNodeConnected() const
2316 bool connected( false );
2321 if( mNode->IsRoot() || mNode->GetParent() )
2330 unsigned int Actor::GetDefaultPropertyCount() const
2332 return DEFAULT_PROPERTY_COUNT;
2335 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2337 indices.reserve( DEFAULT_PROPERTY_COUNT );
2339 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2341 indices.push_back( i );
2345 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2347 if( index < DEFAULT_PROPERTY_COUNT )
2349 return DEFAULT_PROPERTY_DETAILS[index].name;
2355 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2357 Property::Index index = Property::INVALID_INDEX;
2359 // Look for name in default properties
2360 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2362 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2363 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2373 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2375 if( index < DEFAULT_PROPERTY_COUNT )
2377 return DEFAULT_PROPERTY_DETAILS[index].writable;
2383 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2385 if( index < DEFAULT_PROPERTY_COUNT )
2387 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2393 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2395 if( index < DEFAULT_PROPERTY_COUNT )
2397 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2403 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2405 if( index < DEFAULT_PROPERTY_COUNT )
2407 return DEFAULT_PROPERTY_DETAILS[index].type;
2410 // index out of range...return Property::NONE
2411 return Property::NONE;
2414 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2418 case Dali::Actor::Property::ParentOrigin:
2420 SetParentOrigin( property.Get<Vector3>() );
2424 case Dali::Actor::Property::ParentOriginX:
2426 SetParentOriginX( property.Get<float>() );
2430 case Dali::Actor::Property::ParentOriginY:
2432 SetParentOriginY( property.Get<float>() );
2436 case Dali::Actor::Property::ParentOriginZ:
2438 SetParentOriginZ( property.Get<float>() );
2442 case Dali::Actor::Property::AnchorPoint:
2444 SetAnchorPoint( property.Get<Vector3>() );
2448 case Dali::Actor::Property::AnchorPointX:
2450 SetAnchorPointX( property.Get<float>() );
2454 case Dali::Actor::Property::AnchorPointY:
2456 SetAnchorPointY( property.Get<float>() );
2460 case Dali::Actor::Property::AnchorPointZ:
2462 SetAnchorPointZ( property.Get<float>() );
2466 case Dali::Actor::Property::Size:
2468 SetSize( property.Get<Vector3>() );
2472 case Dali::Actor::Property::SizeWidth:
2474 SetWidth( property.Get<float>() );
2478 case Dali::Actor::Property::SizeHeight:
2480 SetHeight( property.Get<float>() );
2484 case Dali::Actor::Property::SizeDepth:
2486 SetDepth( property.Get<float>() );
2490 case Dali::Actor::Property::Position:
2492 SetPosition( property.Get<Vector3>() );
2496 case Dali::Actor::Property::PositionX:
2498 SetX( property.Get<float>() );
2502 case Dali::Actor::Property::PositionY:
2504 SetY( property.Get<float>() );
2508 case Dali::Actor::Property::PositionZ:
2510 SetZ( property.Get<float>() );
2514 case Dali::Actor::Property::Rotation:
2516 SetRotation( property.Get<Quaternion>() );
2520 case Dali::Actor::Property::Scale:
2522 SetScale( property.Get<Vector3>() );
2526 case Dali::Actor::Property::ScaleX:
2528 SetScaleX( property.Get<float>() );
2532 case Dali::Actor::Property::ScaleY:
2534 SetScaleY( property.Get<float>() );
2538 case Dali::Actor::Property::ScaleZ:
2540 SetScaleZ( property.Get<float>() );
2544 case Dali::Actor::Property::Visible:
2546 SetVisible( property.Get<bool>() );
2550 case Dali::Actor::Property::Color:
2552 SetColor( property.Get<Vector4>() );
2556 case Dali::Actor::Property::ColorRed:
2558 SetColorRed( property.Get<float>() );
2562 case Dali::Actor::Property::ColorGreen:
2564 SetColorGreen( property.Get<float>() );
2568 case Dali::Actor::Property::ColorBlue:
2570 SetColorBlue( property.Get<float>() );
2574 case Dali::Actor::Property::ColorAlpha:
2576 SetOpacity( property.Get<float>() );
2580 case Dali::Actor::Property::Name:
2582 SetName( property.Get<std::string>() );
2586 case Dali::Actor::Property::Sensitive:
2588 SetSensitive( property.Get<bool>() );
2592 case Dali::Actor::Property::LeaveRequired:
2594 SetLeaveRequired( property.Get<bool>() );
2598 case Dali::Actor::Property::InheritRotation:
2600 SetInheritRotation( property.Get<bool>() );
2604 case Dali::Actor::Property::InheritScale:
2606 SetInheritScale( property.Get<bool>() );
2610 case Dali::Actor::Property::ColorMode:
2612 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2616 case Dali::Actor::Property::PositionInheritance:
2618 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2622 case Dali::Actor::Property::DrawMode:
2624 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2628 case Dali::Actor::Property::SizeMode:
2630 SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SizeModeTable, SizeModeTableCount ) );
2634 case Dali::Actor::Property::SizeModeFactor:
2636 SetSizeModeFactor( property.Get<Vector3>() );
2642 // this can happen in the case of a non-animatable default property so just do nothing
2648 // TODO: This method needs to be removed
2649 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2651 OnPropertySet(index, value);
2653 switch ( entry.type )
2655 case Property::BOOLEAN:
2657 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2658 DALI_ASSERT_DEBUG( NULL != property );
2660 // property is being used in a separate thread; queue a message to set the property
2661 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2666 case Property::FLOAT:
2668 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2669 DALI_ASSERT_DEBUG( NULL != property );
2671 // property is being used in a separate thread; queue a message to set the property
2672 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2677 case Property::INTEGER:
2679 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2680 DALI_ASSERT_DEBUG( NULL != property );
2682 // property is being used in a separate thread; queue a message to set the property
2683 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2688 case Property::VECTOR2:
2690 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2691 DALI_ASSERT_DEBUG( NULL != property );
2693 // property is being used in a separate thread; queue a message to set the property
2694 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2699 case Property::VECTOR3:
2701 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2702 DALI_ASSERT_DEBUG( NULL != property );
2704 // property is being used in a separate thread; queue a message to set the property
2705 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2710 case Property::VECTOR4:
2712 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2713 DALI_ASSERT_DEBUG( NULL != property );
2715 // property is being used in a separate thread; queue a message to set the property
2716 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2721 case Property::ROTATION:
2723 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2724 DALI_ASSERT_DEBUG( NULL != property );
2726 // property is being used in a separate thread; queue a message to set the property
2727 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2732 case Property::MATRIX:
2734 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2735 DALI_ASSERT_DEBUG( NULL != property );
2737 // property is being used in a separate thread; queue a message to set the property
2738 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2743 case Property::MATRIX3:
2745 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2746 DALI_ASSERT_DEBUG( NULL != property );
2748 // property is being used in a separate thread; queue a message to set the property
2749 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2756 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2762 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
2764 Property::Value value;
2768 case Dali::Actor::Property::ParentOrigin:
2770 value = GetCurrentParentOrigin();
2774 case Dali::Actor::Property::ParentOriginX:
2776 value = GetCurrentParentOrigin().x;
2780 case Dali::Actor::Property::ParentOriginY:
2782 value = GetCurrentParentOrigin().y;
2786 case Dali::Actor::Property::ParentOriginZ:
2788 value = GetCurrentParentOrigin().z;
2792 case Dali::Actor::Property::AnchorPoint:
2794 value = GetCurrentAnchorPoint();
2798 case Dali::Actor::Property::AnchorPointX:
2800 value = GetCurrentAnchorPoint().x;
2804 case Dali::Actor::Property::AnchorPointY:
2806 value = GetCurrentAnchorPoint().y;
2810 case Dali::Actor::Property::AnchorPointZ:
2812 value = GetCurrentAnchorPoint().z;
2816 case Dali::Actor::Property::Size:
2818 value = GetCurrentSize();
2822 case Dali::Actor::Property::SizeWidth:
2824 value = GetCurrentSize().width;
2828 case Dali::Actor::Property::SizeHeight:
2830 value = GetCurrentSize().height;
2834 case Dali::Actor::Property::SizeDepth:
2836 value = GetCurrentSize().depth;
2840 case Dali::Actor::Property::Position:
2842 value = GetCurrentPosition();
2846 case Dali::Actor::Property::PositionX:
2848 value = GetCurrentPosition().x;
2852 case Dali::Actor::Property::PositionY:
2854 value = GetCurrentPosition().y;
2858 case Dali::Actor::Property::PositionZ:
2860 value = GetCurrentPosition().z;
2864 case Dali::Actor::Property::WorldPosition:
2866 value = GetCurrentWorldPosition();
2870 case Dali::Actor::Property::WorldPositionX:
2872 value = GetCurrentWorldPosition().x;
2876 case Dali::Actor::Property::WorldPositionY:
2878 value = GetCurrentWorldPosition().y;
2882 case Dali::Actor::Property::WorldPositionZ:
2884 value = GetCurrentWorldPosition().z;
2888 case Dali::Actor::Property::Rotation:
2890 value = GetCurrentRotation();
2894 case Dali::Actor::Property::WorldRotation:
2896 value = GetCurrentWorldRotation();
2900 case Dali::Actor::Property::Scale:
2902 value = GetCurrentScale();
2906 case Dali::Actor::Property::ScaleX:
2908 value = GetCurrentScale().x;
2912 case Dali::Actor::Property::ScaleY:
2914 value = GetCurrentScale().y;
2918 case Dali::Actor::Property::ScaleZ:
2920 value = GetCurrentScale().z;
2924 case Dali::Actor::Property::WorldScale:
2926 value = GetCurrentWorldScale();
2930 case Dali::Actor::Property::Visible:
2932 value = IsVisible();
2936 case Dali::Actor::Property::Color:
2938 value = GetCurrentColor();
2942 case Dali::Actor::Property::ColorRed:
2944 value = GetCurrentColor().r;
2948 case Dali::Actor::Property::ColorGreen:
2950 value = GetCurrentColor().g;
2954 case Dali::Actor::Property::ColorBlue:
2956 value = GetCurrentColor().b;
2960 case Dali::Actor::Property::ColorAlpha:
2962 value = GetCurrentColor().a;
2966 case Dali::Actor::Property::WorldColor:
2968 value = GetCurrentWorldColor();
2972 case Dali::Actor::Property::WorldMatrix:
2974 value = GetCurrentWorldMatrix();
2978 case Dali::Actor::Property::Name:
2984 case Dali::Actor::Property::Sensitive:
2986 value = IsSensitive();
2990 case Dali::Actor::Property::LeaveRequired:
2992 value = GetLeaveRequired();
2996 case Dali::Actor::Property::InheritRotation:
2998 value = IsRotationInherited();
3002 case Dali::Actor::Property::InheritScale:
3004 value = IsScaleInherited();
3008 case Dali::Actor::Property::ColorMode:
3010 value = Scripting::GetColorMode( GetColorMode() );
3014 case Dali::Actor::Property::PositionInheritance:
3016 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3020 case Dali::Actor::Property::DrawMode:
3022 value = Scripting::GetDrawMode( GetDrawMode() );
3026 case Dali::Actor::Property::SizeMode:
3028 value = Scripting::GetLinearEnumerationName< SizeMode >( GetSizeMode(), SizeModeTable, SizeModeTableCount );
3032 case Dali::Actor::Property::SizeModeFactor:
3034 value = GetSizeModeFactor();
3040 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3048 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3053 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3055 // This method should only return an object connected to the scene-graph
3056 return OnStage() ? mNode : NULL;
3059 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3061 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3063 const PropertyBase* property( NULL );
3065 // This method should only return a property of an object connected to the scene-graph
3071 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3073 CustomProperty* custom = FindCustomProperty( index );
3074 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3076 property = custom->GetSceneGraphProperty();
3078 else if( NULL != mNode )
3082 case Dali::Actor::Property::Size:
3083 property = &mNode->mSize;
3086 case Dali::Actor::Property::SizeWidth:
3087 property = &mNode->mSize;
3090 case Dali::Actor::Property::SizeHeight:
3091 property = &mNode->mSize;
3094 case Dali::Actor::Property::SizeDepth:
3095 property = &mNode->mSize;
3098 case Dali::Actor::Property::Position:
3099 property = &mNode->mPosition;
3102 case Dali::Actor::Property::PositionX:
3103 property = &mNode->mPosition;
3106 case Dali::Actor::Property::PositionY:
3107 property = &mNode->mPosition;
3110 case Dali::Actor::Property::PositionZ:
3111 property = &mNode->mPosition;
3114 case Dali::Actor::Property::Rotation:
3115 property = &mNode->mRotation;
3118 case Dali::Actor::Property::Scale:
3119 property = &mNode->mScale;
3122 case Dali::Actor::Property::ScaleX:
3123 property = &mNode->mScale;
3126 case Dali::Actor::Property::ScaleY:
3127 property = &mNode->mScale;
3130 case Dali::Actor::Property::ScaleZ:
3131 property = &mNode->mScale;
3134 case Dali::Actor::Property::Visible:
3135 property = &mNode->mVisible;
3138 case Dali::Actor::Property::Color:
3139 property = &mNode->mColor;
3142 case Dali::Actor::Property::ColorRed:
3143 property = &mNode->mColor;
3146 case Dali::Actor::Property::ColorGreen:
3147 property = &mNode->mColor;
3150 case Dali::Actor::Property::ColorBlue:
3151 property = &mNode->mColor;
3154 case Dali::Actor::Property::ColorAlpha:
3155 property = &mNode->mColor;
3166 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3168 const PropertyInputImpl* property( NULL );
3170 // This method should only return a property of an object connected to the scene-graph
3176 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3178 CustomProperty* custom = FindCustomProperty( index );
3179 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3180 property = custom->GetSceneGraphProperty();
3182 else if( NULL != mNode )
3186 case Dali::Actor::Property::ParentOrigin:
3187 property = &mNode->mParentOrigin;
3190 case Dali::Actor::Property::ParentOriginX:
3191 property = &mNode->mParentOrigin;
3194 case Dali::Actor::Property::ParentOriginY:
3195 property = &mNode->mParentOrigin;
3198 case Dali::Actor::Property::ParentOriginZ:
3199 property = &mNode->mParentOrigin;
3202 case Dali::Actor::Property::AnchorPoint:
3203 property = &mNode->mAnchorPoint;
3206 case Dali::Actor::Property::AnchorPointX:
3207 property = &mNode->mAnchorPoint;
3210 case Dali::Actor::Property::AnchorPointY:
3211 property = &mNode->mAnchorPoint;
3214 case Dali::Actor::Property::AnchorPointZ:
3215 property = &mNode->mAnchorPoint;
3218 case Dali::Actor::Property::Size:
3219 property = &mNode->mSize;
3222 case Dali::Actor::Property::SizeWidth:
3223 property = &mNode->mSize;
3226 case Dali::Actor::Property::SizeHeight:
3227 property = &mNode->mSize;
3230 case Dali::Actor::Property::SizeDepth:
3231 property = &mNode->mSize;
3234 case Dali::Actor::Property::Position:
3235 property = &mNode->mPosition;
3238 case Dali::Actor::Property::PositionX:
3239 property = &mNode->mPosition;
3242 case Dali::Actor::Property::PositionY:
3243 property = &mNode->mPosition;
3246 case Dali::Actor::Property::PositionZ:
3247 property = &mNode->mPosition;
3250 case Dali::Actor::Property::WorldPosition:
3251 property = &mNode->mWorldPosition;
3254 case Dali::Actor::Property::WorldPositionX:
3255 property = &mNode->mWorldPosition;
3258 case Dali::Actor::Property::WorldPositionY:
3259 property = &mNode->mWorldPosition;
3262 case Dali::Actor::Property::WorldPositionZ:
3263 property = &mNode->mWorldPosition;
3266 case Dali::Actor::Property::Rotation:
3267 property = &mNode->mRotation;
3270 case Dali::Actor::Property::WorldRotation:
3271 property = &mNode->mWorldRotation;
3274 case Dali::Actor::Property::Scale:
3275 property = &mNode->mScale;
3278 case Dali::Actor::Property::ScaleX:
3279 property = &mNode->mScale;
3282 case Dali::Actor::Property::ScaleY:
3283 property = &mNode->mScale;
3286 case Dali::Actor::Property::ScaleZ:
3287 property = &mNode->mScale;
3290 case Dali::Actor::Property::WorldScale:
3291 property = &mNode->mWorldScale;
3294 case Dali::Actor::Property::Visible:
3295 property = &mNode->mVisible;
3298 case Dali::Actor::Property::Color:
3299 property = &mNode->mColor;
3302 case Dali::Actor::Property::ColorRed:
3303 property = &mNode->mColor;
3306 case Dali::Actor::Property::ColorGreen:
3307 property = &mNode->mColor;
3310 case Dali::Actor::Property::ColorBlue:
3311 property = &mNode->mColor;
3314 case Dali::Actor::Property::ColorAlpha:
3315 property = &mNode->mColor;
3318 case Dali::Actor::Property::WorldColor:
3319 property = &mNode->mWorldColor;
3322 case Dali::Actor::Property::WorldMatrix:
3323 property = &mNode->mWorldMatrix;
3334 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3336 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3340 case Dali::Actor::Property::ParentOriginX:
3341 case Dali::Actor::Property::AnchorPointX:
3342 case Dali::Actor::Property::SizeWidth:
3343 case Dali::Actor::Property::PositionX:
3344 case Dali::Actor::Property::WorldPositionX:
3345 case Dali::Actor::Property::ScaleX:
3346 case Dali::Actor::Property::ColorRed:
3352 case Dali::Actor::Property::ParentOriginY:
3353 case Dali::Actor::Property::AnchorPointY:
3354 case Dali::Actor::Property::SizeHeight:
3355 case Dali::Actor::Property::PositionY:
3356 case Dali::Actor::Property::WorldPositionY:
3357 case Dali::Actor::Property::ScaleY:
3358 case Dali::Actor::Property::ColorGreen:
3364 case Dali::Actor::Property::ParentOriginZ:
3365 case Dali::Actor::Property::AnchorPointZ:
3366 case Dali::Actor::Property::SizeDepth:
3367 case Dali::Actor::Property::PositionZ:
3368 case Dali::Actor::Property::WorldPositionZ:
3369 case Dali::Actor::Property::ScaleZ:
3370 case Dali::Actor::Property::ColorBlue:
3376 case Dali::Actor::Property::ColorAlpha:
3389 return componentIndex;
3392 void Actor::SetParent(Actor* parent, int index)
3396 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3400 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3403 // Instruct each actor to create a corresponding node in the scene graph
3404 ConnectToStage( index );
3407 else // parent being set to NULL
3409 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3413 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3416 DALI_ASSERT_ALWAYS(mNode != NULL);
3420 // Disconnect the Node & its children from the scene-graph.
3421 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3424 // Instruct each actor to discard pointers to the scene-graph
3425 DisconnectFromStage();
3430 SceneGraph::Node* Actor::CreateNode() const
3435 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
3438 Actor* actor = dynamic_cast<Actor*>( object );
3442 if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
3444 actor->SetVisible(true);
3447 else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
3449 actor->SetVisible(false);
3457 } // namespace Internal