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-index-ranges.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/common/property-owner-messages.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;
69 const Property::Index Actor::PARENT_ORIGIN = 0;
70 const Property::Index Actor::PARENT_ORIGIN_X = 1;
71 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
72 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
73 const Property::Index Actor::ANCHOR_POINT = 4;
74 const Property::Index Actor::ANCHOR_POINT_X = 5;
75 const Property::Index Actor::ANCHOR_POINT_Y = 6;
76 const Property::Index Actor::ANCHOR_POINT_Z = 7;
77 const Property::Index Actor::SIZE = 8;
78 const Property::Index Actor::SIZE_WIDTH = 9;
79 const Property::Index Actor::SIZE_HEIGHT = 10;
80 const Property::Index Actor::SIZE_DEPTH = 11;
81 const Property::Index Actor::POSITION = 12;
82 const Property::Index Actor::POSITION_X = 13;
83 const Property::Index Actor::POSITION_Y = 14;
84 const Property::Index Actor::POSITION_Z = 15;
85 const Property::Index Actor::WORLD_POSITION = 16;
86 const Property::Index Actor::WORLD_POSITION_X = 17;
87 const Property::Index Actor::WORLD_POSITION_Y = 18;
88 const Property::Index Actor::WORLD_POSITION_Z = 19;
89 const Property::Index Actor::ROTATION = 20;
90 const Property::Index Actor::WORLD_ROTATION = 21;
91 const Property::Index Actor::SCALE = 22;
92 const Property::Index Actor::SCALE_X = 23;
93 const Property::Index Actor::SCALE_Y = 24;
94 const Property::Index Actor::SCALE_Z = 25;
95 const Property::Index Actor::WORLD_SCALE = 26;
96 const Property::Index Actor::VISIBLE = 27;
97 const Property::Index Actor::COLOR = 28;
98 const Property::Index Actor::COLOR_RED = 29;
99 const Property::Index Actor::COLOR_GREEN = 30;
100 const Property::Index Actor::COLOR_BLUE = 31;
101 const Property::Index Actor::COLOR_ALPHA = 32;
102 const Property::Index Actor::WORLD_COLOR = 33;
103 const Property::Index Actor::WORLD_MATRIX = 34;
104 const Property::Index Actor::NAME = 35;
105 const Property::Index Actor::SENSITIVE = 36;
106 const Property::Index Actor::LEAVE_REQUIRED = 37;
107 const Property::Index Actor::INHERIT_ROTATION = 38;
108 const Property::Index Actor::INHERIT_SCALE = 39;
109 const Property::Index Actor::COLOR_MODE = 40;
110 const Property::Index Actor::POSITION_INHERITANCE = 41;
111 const Property::Index Actor::DRAW_MODE = 42;
113 namespace // unnamed namespace
117 * We want to discourage the use of property strings (minimize string comparisons),
118 * particularly for the default properties.
120 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
122 // Name Type writable animatable constraint-input
123 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
124 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
125 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
126 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
127 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
128 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
129 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
130 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
131 { "size", Property::VECTOR3, true, true, true }, // SIZE
132 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
133 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
134 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
135 { "position", Property::VECTOR3, true, true, true }, // POSITION
136 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
137 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
138 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
139 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
140 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
141 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
142 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
143 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
144 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
145 { "scale", Property::VECTOR3, true, true, true }, // SCALE
146 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
147 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
148 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
149 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
150 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
151 { "color", Property::VECTOR4, true, true, true }, // COLOR
152 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
153 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
154 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
155 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
156 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
157 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
158 { "name", Property::STRING, true, false, false }, // NAME
159 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
160 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
161 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
162 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
163 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
164 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
165 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
167 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
169 } // unnamed namespace
174 unsigned int Actor::mActorCounter = 0;
175 ActorContainer Actor::mNullChildren;
177 #ifdef DYNAMICS_SUPPORT
179 // Encapsulate actor related dynamics data
182 DynamicsData( Actor* slotOwner )
183 : slotDelegate( slotOwner )
187 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
188 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
190 DynamicsBodyPtr body;
191 JointContainer joints;
192 ReferencedJointContainer referencedJoints;
194 SlotDelegate< Actor > slotDelegate;
197 #endif // DYNAMICS_SUPPORT
202 using namespace Dali;
204 BaseHandle CreateActor()
206 return Dali::Actor::New();
209 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
211 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
212 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
213 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
214 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
216 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
217 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
221 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
223 ActorPtr Actor::New()
225 ActorPtr actor( new Actor( BASIC ) );
227 // Second-phase construction
233 const std::string& Actor::GetName() const
238 void Actor::SetName(const std::string& name)
244 // ATTENTION: string for debug purposes is not thread safe.
245 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
249 unsigned int Actor::GetId() const
254 void Actor::Attach( ActorAttachment& attachment )
256 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
260 attachment.Connect();
263 mAttachment = ActorAttachmentPtr(&attachment);
266 ActorAttachmentPtr Actor::GetAttachment()
271 bool Actor::OnStage() const
276 Dali::Layer Actor::GetLayer()
280 // Short-circuit for Layer derived actors
283 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
286 // Find the immediate Layer parent
287 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
289 if( parent->IsLayer() )
291 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
298 void Actor::Add(Actor& child)
300 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
301 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
305 mChildren = new ActorContainer;
308 Actor* const oldParent( child.mParent );
310 // child might already be ours
311 if( this != oldParent )
313 // if we already have parent, unparent us first
316 oldParent->Remove( child ); // This causes OnChildRemove callback
319 // Guard against Add() during previous OnChildRemove callback
320 if ( !child.mParent )
322 // Do this first, since user callbacks from within SetParent() may need to remove child
323 mChildren->push_back(Dali::Actor(&child));
325 // SetParent asserts that child can be added
326 child.SetParent(this);
328 // Notification for derived classes
334 void Actor::Insert(unsigned int index, Actor& child)
336 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
337 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
341 mChildren = new ActorContainer;
344 Actor* const oldParent( child.mParent );
346 // since an explicit position has been given, always insert, even if already a child
349 oldParent->Remove( child ); // This causes OnChildRemove callback
352 // Guard against Add() during previous OnChildRemove callback
353 if ( !child.mParent )
355 // Do this first, since user callbacks from within SetParent() may need to remove child
356 if (index < child.GetChildCount())
358 ActorIter it = mChildren->begin();
359 std::advance(it, index);
360 mChildren->insert(it, Dali::Actor(&child));
364 mChildren->push_back(Dali::Actor(&child));
366 // SetParent asserts that child can be added
367 child.SetParent(this, index);
369 // Notification for derived classes
374 void Actor::Remove(Actor& child)
376 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
386 // Find the child in mChildren, and unparent it
387 ActorIter end = mChildren->end();
388 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
390 Actor& actor = GetImplementation(*iter);
392 if( &actor == &child )
394 // Keep handle for OnChildRemove notification
395 removed = Dali::Actor( &actor );
397 // Do this first, since user callbacks from within SetParent() may need to add the child
398 mChildren->erase(iter);
400 DALI_ASSERT_DEBUG( actor.GetParent() == this );
401 actor.SetParent( NULL );
409 // Notification for derived classes
410 OnChildRemove( GetImplementation(removed) );
414 void Actor::Unparent()
418 mParent->Remove( *this );
422 unsigned int Actor::GetChildCount() const
424 return ( NULL != mChildren ) ? mChildren->size() : 0;
427 Dali::Actor Actor::GetChildAt(unsigned int index) const
429 DALI_ASSERT_ALWAYS( index < GetChildCount() );
431 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
434 ActorContainer Actor::GetChildren()
436 if( NULL != mChildren )
441 // return copy of mNullChildren
442 return mNullChildren;
445 const ActorContainer& Actor::GetChildren() const
447 if( NULL != mChildren )
452 // return const reference to mNullChildren
453 return mNullChildren;
456 ActorPtr Actor::FindChildByName(const std::string& actorName)
459 if (actorName == mName)
465 ActorIter end = mChildren->end();
466 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
468 child = GetImplementation(*iter).FindChildByName(actorName);
479 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
481 Dali::Actor child = DoGetChildByAlias(actorAlias);
483 // If not found then search by name.
486 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
489 child = Dali::Actor(child_ptr.Get());
496 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
498 Dali::Actor child = GetChildByAlias(actorAlias);
500 if (!child && mChildren )
502 ActorIter end = mChildren->end();
503 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
505 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
517 ActorPtr Actor::FindChildById(const unsigned int id)
526 ActorIter end = mChildren->end();
527 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
529 child = GetImplementation(*iter).FindChildById(id);
540 void Actor::SetParentOrigin( const Vector3& origin )
544 // mNode is being used in a separate thread; queue a message to set the value & base value
545 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
548 // Cache for event-thread access
551 // not allocated, check if different from default
552 if( ParentOrigin::DEFAULT != origin )
554 mParentOrigin = new Vector3( origin );
559 // check if different from current costs more than just set
560 *mParentOrigin = origin;
564 void Actor::SetParentOriginX( float x )
566 const Vector3& current = GetCurrentParentOrigin();
568 SetParentOrigin( Vector3( x, current.y, current.z ) );
571 void Actor::SetParentOriginY( float y )
573 const Vector3& current = GetCurrentParentOrigin();
575 SetParentOrigin( Vector3( current.x, y, current.z ) );
578 void Actor::SetParentOriginZ( float z )
580 const Vector3& current = GetCurrentParentOrigin();
582 SetParentOrigin( Vector3( current.x, current.y, z ) );
585 const Vector3& Actor::GetCurrentParentOrigin() const
587 // Cached for event-thread access
588 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
591 void Actor::SetAnchorPoint(const Vector3& anchor)
595 // mNode is being used in a separate thread; queue a message to set the value & base value
596 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
599 // Cache for event-thread access
602 // not allocated, check if different from default
603 if( AnchorPoint::DEFAULT != anchor )
605 mAnchorPoint = new Vector3( anchor );
610 // check if different from current costs more than just set
611 *mAnchorPoint = anchor;
615 void Actor::SetAnchorPointX( float x )
617 const Vector3& current = GetCurrentAnchorPoint();
619 SetAnchorPoint( Vector3( x, current.y, current.z ) );
622 void Actor::SetAnchorPointY( float y )
624 const Vector3& current = GetCurrentAnchorPoint();
626 SetAnchorPoint( Vector3( current.x, y, current.z ) );
629 void Actor::SetAnchorPointZ( float z )
631 const Vector3& current = GetCurrentAnchorPoint();
633 SetAnchorPoint( Vector3( current.x, current.y, z ) );
636 const Vector3& Actor::GetCurrentAnchorPoint() const
638 // Cached for event-thread access
639 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
642 void Actor::SetPosition(float x, float y)
644 SetPosition(Vector3(x, y, 0.0f));
647 void Actor::SetPosition(float x, float y, float z)
649 SetPosition(Vector3(x, y, z));
652 void Actor::SetPosition(const Vector3& position)
656 // mNode is being used in a separate thread; queue a message to set the value & base value
657 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
661 void Actor::SetX(float x)
665 // mNode is being used in a separate thread; queue a message to set the value & base value
666 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
670 void Actor::SetY(float y)
674 // mNode is being used in a separate thread; queue a message to set the value & base value
675 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
679 void Actor::SetZ(float z)
683 // mNode is being used in a separate thread; queue a message to set the value & base value
684 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
688 void Actor::MoveBy(const Vector3& distance)
692 // mNode is being used in a separate thread; queue a message to set the value & base value
693 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
697 const Vector3& Actor::GetCurrentPosition() const
701 // mNode is being used in a separate thread; copy the value from the previous update
702 return mNode->GetPosition(mStage->GetEventBufferIndex());
705 return Vector3::ZERO;
708 const Vector3& Actor::GetCurrentWorldPosition() const
712 // mNode is being used in a separate thread; copy the value from the previous update
713 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
716 return Vector3::ZERO;
719 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
721 // this flag is not animatable so keep the value
722 mPositionInheritanceMode = mode;
725 // mNode is being used in a separate thread; queue a message to set the value
726 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
730 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
732 // Cached for event-thread access
733 return mPositionInheritanceMode;
736 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
738 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
739 normalizedAxis.Normalize();
741 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
743 SetRotation(rotation);
746 void Actor::SetRotation(const Quaternion& rotation)
750 // mNode is being used in a separate thread; queue a message to set the value & base value
751 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
755 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
759 // mNode is being used in a separate thread; queue a message to set the value & base value
760 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
764 void Actor::RotateBy(const Quaternion& relativeRotation)
768 // mNode is being used in a separate thread; queue a message to set the value & base value
769 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
773 const Quaternion& Actor::GetCurrentRotation() const
777 // mNode is being used in a separate thread; copy the value from the previous update
778 return mNode->GetRotation(mStage->GetEventBufferIndex());
781 return Quaternion::IDENTITY;
784 const Quaternion& Actor::GetCurrentWorldRotation() const
788 // mNode is being used in a separate thread; copy the value from the previous update
789 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
792 return Quaternion::IDENTITY;
795 void Actor::SetScale(float scale)
797 SetScale(Vector3(scale, scale, scale));
800 void Actor::SetScale(float x, float y, float z)
802 SetScale(Vector3(x, y, z));
805 void Actor::SetScale(const Vector3& scale)
809 // mNode is being used in a separate thread; queue a message to set the value & base value
810 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
814 void Actor::SetScaleX( float x )
818 // mNode is being used in a separate thread; queue a message to set the value & base value
819 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
823 void Actor::SetScaleY( float y )
827 // mNode is being used in a separate thread; queue a message to set the value & base value
828 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
832 void Actor::SetScaleZ( float z )
836 // mNode is being used in a separate thread; queue a message to set the value & base value
837 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
841 void Actor::SetInitialVolume(const Vector3& volume)
845 // mNode is being used in a separate thread; queue a message to set the value
846 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
850 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
854 // mNode is being used in a separate thread; queue a message to set the value
855 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
859 bool Actor::GetTransmitGeometryScaling() const
863 // mNode is being used in a separate thread; copy the value from the previous update
864 return mNode->GetTransmitGeometryScaling();
870 void Actor::ScaleBy(const Vector3& relativeScale)
874 // mNode is being used in a separate thread; queue a message to set the value & base value
875 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
879 const Vector3& Actor::GetCurrentScale() const
883 // mNode is being used in a separate thread; copy the value from the previous update
884 return mNode->GetScale(mStage->GetEventBufferIndex());
890 const Vector3& Actor::GetCurrentWorldScale() const
894 // mNode is being used in a separate thread; copy the value from the previous update
895 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
901 void Actor::SetInheritScale( bool inherit )
903 // non animateable so keep local copy
904 mInheritScale = inherit;
907 // mNode is being used in a separate thread; queue a message to set the value
908 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
912 bool Actor::IsScaleInherited() const
914 return mInheritScale;
917 Matrix Actor::GetCurrentWorldMatrix() const
921 // World matrix is no longer updated unless there is something observing the node.
922 // Need to calculate it from node's world position, rotation and scale:
923 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
924 Matrix worldMatrix(false);
925 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
926 mNode->GetWorldRotation( updateBufferIndex ),
927 mNode->GetWorldPosition( updateBufferIndex ) );
931 return Matrix::IDENTITY;
934 void Actor::SetVisible(bool visible)
938 // mNode is being used in a separate thread; queue a message to set the value & base value
939 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
943 bool Actor::IsVisible() const
947 // mNode is being used in a separate thread; copy the value from the previous update
948 return mNode->IsVisible( mStage->GetEventBufferIndex() );
954 void Actor::SetOpacity(float opacity)
958 // mNode is being used in a separate thread; queue a message to set the value & base value
959 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
963 void Actor::OpacityBy(float relativeOpacity)
967 // mNode is being used in a separate thread; queue a message to set the value & base value
968 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
972 float Actor::GetCurrentOpacity() const
976 // mNode is being used in a separate thread; copy the value from the previous update
977 return mNode->GetOpacity(mStage->GetEventBufferIndex());
983 const Vector4& Actor::GetCurrentWorldColor() const
987 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
993 void Actor::SetColor(const Vector4& color)
997 // mNode is being used in a separate thread; queue a message to set the value & base value
998 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1002 void Actor::SetColorRed( float red )
1006 // mNode is being used in a separate thread; queue a message to set the value & base value
1007 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1011 void Actor::SetColorGreen( float green )
1015 // mNode is being used in a separate thread; queue a message to set the value & base value
1016 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1020 void Actor::SetColorBlue( float blue )
1024 // mNode is being used in a separate thread; queue a message to set the value & base value
1025 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1029 void Actor::ColorBy(const Vector4& relativeColor)
1033 // mNode is being used in a separate thread; queue a message to set the value & base value
1034 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1038 const Vector4& Actor::GetCurrentColor() const
1042 // mNode is being used in a separate thread; copy the value from the previous update
1043 return mNode->GetColor(mStage->GetEventBufferIndex());
1046 return Color::WHITE;
1049 void Actor::SetInheritRotation(bool inherit)
1051 // non animateable so keep local copy
1052 mInheritRotation = inherit;
1055 // mNode is being used in a separate thread; queue a message to set the value
1056 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1060 bool Actor::IsRotationInherited() const
1062 return mInheritRotation;
1065 void Actor::SetColorMode(ColorMode colorMode)
1067 // non animateable so keep local copy
1068 mColorMode = colorMode;
1071 // mNode is being used in a separate thread; queue a message to set the value
1072 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1076 ColorMode Actor::GetColorMode() const
1078 // we have cached copy
1082 void Actor::SetSize(float width, float height)
1084 SetSize( Vector2( width, height ) );
1087 void Actor::SetSize(float width, float height, float depth)
1089 SetSize( Vector3( width, height, depth ) );
1092 void Actor::SetSize(const Vector2& size)
1094 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1097 float Actor::CalculateSizeZ( const Vector2& size ) const
1099 return std::min( size.width, size.height );
1102 void Actor::SetSize(const Vector3& size)
1106 // mNode is being used in a separate thread; queue a message to set the value & base value
1107 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1109 // Notification for derived classes
1112 // Emit signal for application developer
1114 if( !mSetSizeSignalV2.Empty() )
1116 Dali::Actor handle( this );
1117 mSetSizeSignalV2.Emit( handle, size );
1122 void Actor::SetWidth( float width )
1126 // mNode is being used in a separate thread; queue a message to set the value & base value
1127 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1131 void Actor::SetHeight( float height )
1135 // mNode is being used in a separate thread; queue a message to set the value & base value
1136 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1140 void Actor::SetDepth( float depth )
1144 // mNode is being used in a separate thread; queue a message to set the value & base value
1145 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1149 const Vector3& Actor::GetCurrentSize() const
1153 // mNode is being used in a separate thread; copy the value from the previous update
1154 return mNode->GetSize( mStage->GetEventBufferIndex() );
1157 return Vector3::ZERO;
1160 Vector3 Actor::GetNaturalSize() const
1162 // It is up to deriving classes to return the appropriate natural size
1163 return Vector3( 0.0f, 0.0f, 0.0f );
1167 #ifdef DYNAMICS_SUPPORT
1169 //--------------- Dynamics ---------------
1171 void Actor::DisableDynamics()
1173 if( NULL != mDynamicsData )
1175 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1177 // ensure dynamics object are disconnected from scene
1178 DisconnectDynamics();
1180 // delete joint owned by this actor
1181 while( !mDynamicsData->joints.empty() )
1183 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1186 // delete other joints referencing this actor
1187 while( !mDynamicsData->referencedJoints.empty() )
1189 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1190 ActorPtr jointOwner( joint->GetActor( true ) );
1193 jointOwner->RemoveDynamicsJoint( joint );
1197 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1200 // delete the DynamicsBody object
1201 mDynamicsData->body.Reset();
1203 // Discard Dynamics data structure
1204 delete mDynamicsData;
1205 mDynamicsData = NULL;
1209 DynamicsBodyPtr Actor::GetDynamicsBody() const
1211 DynamicsBodyPtr body;
1213 if( NULL != mDynamicsData )
1215 body = mDynamicsData->body;
1221 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1223 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1225 if( NULL == mDynamicsData )
1227 mDynamicsData = new DynamicsData( this );
1230 if( !mDynamicsData->body )
1232 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1236 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1239 if( mParent == world->GetRootActor().Get() )
1241 mDynamicsData->body->Connect(*mStage);
1247 return mDynamicsData->body;
1250 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1252 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1253 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1256 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1258 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1259 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1261 DynamicsJointPtr joint;
1263 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1267 if( NULL != mDynamicsData )
1269 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1271 if( mDynamicsData->joints.end() != it )
1273 // use existing joint
1279 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1280 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1284 bodyA = EnableDynamics( new DynamicsBodyConfig );
1289 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1292 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1293 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1295 if( OnStage() && attachedActor->OnStage() )
1297 joint->Connect(*mStage);
1300 attachedActor->ReferenceJoint( joint );
1302 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1303 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1310 const int Actor::GetNumberOfJoints() const
1312 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1315 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1317 DynamicsJointPtr joint;
1319 if( NULL != mDynamicsData )
1321 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1323 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1325 for( int i = 0; i < index; ++i )
1337 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1339 DynamicsJointPtr joint;
1341 if( NULL != mDynamicsData )
1343 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1345 if( mDynamicsData->joints.end() != it )
1347 // use existing joint
1355 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1357 if( NULL != mDynamicsData )
1359 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1360 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1362 for( ; it != endIt; ++it )
1364 if( it->second == joint.Get() )
1366 ActorPtr attachedActor( it->first );
1368 if( OnStage() && attachedActor && attachedActor->OnStage() )
1370 joint->Disconnect(*mStage);
1375 attachedActor->ReleaseJoint( joint );
1376 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1377 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1380 mDynamicsData->joints.erase(it);
1387 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1389 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1391 if( NULL != mDynamicsData )
1393 mDynamicsData->referencedJoints.push_back(joint);
1397 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1399 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1401 if( NULL != mDynamicsData )
1403 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1405 if( it != mDynamicsData->referencedJoints.end() )
1407 mDynamicsData->referencedJoints.erase( it );
1412 void Actor::SetDynamicsRoot(bool flag)
1414 if( mIsDynamicsRoot != flag )
1416 mIsDynamicsRoot = flag;
1418 if( OnStage() && mChildren )
1420 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1421 ActorIter end = mChildren->end();
1422 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1424 Actor& child = GetImplementation(*iter);
1426 if( child.GetDynamicsBody() )
1428 if( mIsDynamicsRoot )
1430 child.ConnectDynamics();
1434 child.DisconnectDynamics();
1442 bool Actor::IsDynamicsRoot() const
1444 return mIsDynamicsRoot;
1447 void Actor::AttachedActorOnStage( Dali::Actor actor )
1449 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1453 ActorPtr attachedActor( &GetImplementation(actor) );
1455 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1456 if( NULL != mDynamicsData )
1458 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1459 if( mDynamicsData->joints.end() != it )
1461 DynamicsJointPtr joint( it->second );
1462 joint->Connect(*mStage);
1468 void Actor::AttachedActorOffStage( Dali::Actor actor )
1470 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1474 ActorPtr attachedActor( &GetImplementation(actor) );
1476 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1477 if( NULL != mDynamicsData )
1479 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1480 if( mDynamicsData->joints.end() != it )
1482 DynamicsJointPtr joint( it->second );
1483 joint->Disconnect(*mStage);
1489 void Actor::ConnectDynamics()
1491 if( NULL != mDynamicsData && mDynamicsData->body )
1493 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1495 mDynamicsData->body->Connect(*mStage);
1497 // Connect all joints where attachedActor is also on stage
1498 if( !mDynamicsData->joints.empty() )
1500 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1501 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1503 for( ; it != endIt; ++it )
1505 Actor* attachedActor( it->first );
1506 if( NULL != attachedActor && attachedActor->OnStage() )
1508 DynamicsJointPtr joint( it->second );
1510 joint->Connect(*mStage);
1518 void Actor::DisconnectDynamics()
1520 if( NULL != mDynamicsData && mDynamicsData->body )
1524 mDynamicsData->body->Disconnect(*mStage);
1526 // Disconnect all joints
1527 if( !mDynamicsData->joints.empty() )
1529 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1530 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1532 for( ; it != endIt; ++it )
1534 DynamicsJointPtr joint( it->second );
1536 joint->Disconnect(*mStage);
1543 #endif // DYNAMICS_SUPPORT
1545 void Actor::SetOverlay(bool enable)
1547 // Setting STENCIL will override OVERLAY
1548 if( DrawMode::STENCIL != mDrawMode )
1550 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1554 bool Actor::IsOverlay() const
1556 return ( DrawMode::OVERLAY == mDrawMode );
1559 void Actor::SetDrawMode( DrawMode::Type drawMode )
1561 // this flag is not animatable so keep the value
1562 mDrawMode = drawMode;
1565 // mNode is being used in a separate thread; queue a message to set the value
1566 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1570 DrawMode::Type Actor::GetDrawMode() const
1575 bool Actor::ScreenToLocal( float& localX,
1578 float screenY ) const
1580 // only valid when on-stage
1583 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1585 Vector2 converted( screenX, screenY );
1587 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1588 const int taskCount = taskList.GetTaskCount();
1589 for( int i = taskCount - 1; i >= 0; --i )
1591 Dali::RenderTask task = taskList.GetTask( i );
1592 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1594 // found a task where this conversion was ok so return
1602 bool Actor::ScreenToLocal( RenderTask& renderTask,
1606 float screenY ) const
1608 bool retval = false;
1609 // only valid when on-stage
1612 CameraActor* camera = renderTask.GetCameraActor();
1616 renderTask.GetViewport( viewport );
1618 // need to translate coordinates to render tasks coordinate space
1619 Vector2 converted( screenX, screenY );
1620 if( renderTask.TranslateCoordinates( converted ) )
1622 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1629 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1630 const Matrix& projectionMatrix,
1631 const Viewport& viewport,
1635 float screenY ) const
1637 // Early-out if mNode is NULL
1643 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1645 // Calculate the ModelView matrix
1646 Matrix modelView(false/*don't init*/);
1647 // need to use the components as world matrix is only updated for actors that need it
1648 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1649 Matrix::Multiply(modelView, modelView, viewMatrix);
1651 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1652 Matrix invertedMvp(false/*don't init*/);
1653 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1654 bool success = invertedMvp.Invert();
1656 // Convert to GL coordinates
1657 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1662 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1669 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1675 if (XyPlaneIntersect(nearPos, farPos, local))
1677 Vector3 size = GetCurrentSize();
1678 localX = local.x + size.x * 0.5f;
1679 localY = local.y + size.y * 0.5f;
1690 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1693 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1695 Mathematical Formulation
1697 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1699 ( p - c ) dot ( p - c ) = r^2
1701 Given a ray with a point of origin 'o', and a direction vector 'd':
1703 ray(t) = o + td, t >= 0
1705 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1707 (o + td - c ) dot ( o + td - c ) = r^2
1709 To solve for t we first expand the above into a more recognisable quadratic equation form
1711 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1720 B = 2( o - c ) dot d
1721 C = ( o - c ) dot ( o - c ) - r^2
1723 which can be solved using a standard quadratic formula.
1725 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1727 Practical Simplification
1729 In a renderer, we often differentiate between world space and object space. In the object space
1730 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1731 into object space, the mathematical solution presented above can be simplified significantly.
1733 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1737 and we can find the t at which the (transformed) ray intersects the sphere by
1739 ( o + td ) dot ( o + td ) = r^2
1741 According to the reasoning above, we expand the above quadratic equation into the general form
1745 which now has coefficients:
1752 // Early out if mNode is NULL
1758 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1760 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1761 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1762 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1763 rayOrigin.y - translation.y,
1764 rayOrigin.z - translation.z);
1766 // Compute the radius is not needed, square radius it's enough.
1767 const Vector3& size( mNode->GetSize( bufferIndex ) );
1769 // Scale the sphere.
1770 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1772 const float width = size.width * scale.width;
1773 const float height = size.height * scale.height;
1775 float squareSphereRadius = 0.5f * ( width * width + height * height );
1777 float a = rayDir.Dot( rayDir ); // a
1778 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1779 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1781 return ( b2*b2 - a*c ) >= 0.f;
1784 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1791 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1793 // Transforms the ray to the local reference system.
1795 // Calculate the inverse of Model matrix
1796 Matrix invModelMatrix(false/*don't init*/);
1797 // need to use the components as world matrix is only updated for actors that need it
1798 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1800 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1801 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1803 // Test with the actor's XY plane (Normal = 0 0 1 1).
1805 float a = -rayOriginLocal.z;
1806 float b = rayDirLocal.z;
1808 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1810 // Ray travels distance * rayDirLocal to intersect with plane.
1813 const Vector3& size = mNode->GetSize( bufferIndex );
1815 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1816 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1818 // Test with the actor's geometry.
1819 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1826 void Actor::SetLeaveRequired(bool required)
1828 mLeaveRequired = required;
1831 bool Actor::GetLeaveRequired() const
1833 return mLeaveRequired;
1836 void Actor::SetKeyboardFocusable( bool focusable )
1838 mKeyboardFocusable = focusable;
1841 bool Actor::IsKeyboardFocusable() const
1843 return mKeyboardFocusable;
1846 bool Actor::GetTouchRequired() const
1848 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1851 bool Actor::GetMouseWheelEventRequired() const
1853 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1856 bool Actor::IsHittable() const
1858 return IsSensitive() &&
1860 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1864 ActorGestureData& Actor::GetGestureData()
1866 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1867 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1868 if ( NULL == mGestureData )
1870 mGestureData = new ActorGestureData;
1872 return *mGestureData;
1875 bool Actor::IsGestureRequred( Gesture::Type type ) const
1877 return mGestureData && mGestureData->IsGestureRequred( type );
1880 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1882 bool consumed = false;
1884 if ( !mTouchedSignalV2.Empty() )
1886 Dali::Actor handle( this );
1887 consumed = mTouchedSignalV2.Emit( handle, event );
1892 // Notification for derived classes
1893 consumed = OnTouchEvent( event );
1899 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1901 bool consumed = false;
1903 if ( !mMouseWheelEventSignalV2.Empty() )
1905 Dali::Actor handle( this );
1906 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1911 // Notification for derived classes
1912 consumed = OnMouseWheelEvent(event);
1918 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1920 return mTouchedSignalV2;
1923 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1925 return mMouseWheelEventSignalV2;
1928 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1930 return mSetSizeSignalV2;
1933 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1935 return mOnStageSignalV2;
1938 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1940 return mOffStageSignalV2;
1943 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1945 bool connected( true );
1946 Actor* actor = dynamic_cast<Actor*>(object);
1948 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1950 actor->TouchedSignal().Connect( tracker, functor );
1952 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1954 actor->MouseWheelEventSignal().Connect( tracker, functor );
1956 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1958 actor->SetSizeSignal().Connect( tracker, functor );
1960 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1962 actor->OnStageSignal().Connect( tracker, functor );
1964 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1966 actor->OffStageSignal().Connect( tracker, functor );
1970 // signalName does not match any signal
1977 Actor::Actor( DerivedType derivedType )
1982 mParentOrigin( NULL ),
1983 mAnchorPoint( NULL ),
1984 #ifdef DYNAMICS_SUPPORT
1985 mDynamicsData( NULL ),
1987 mGestureData( NULL ),
1990 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1991 mIsRoot( ROOT_LAYER == derivedType ),
1992 mIsRenderable( RENDERABLE == derivedType ),
1993 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1994 mIsOnStage( false ),
1995 mIsDynamicsRoot(false),
1997 mLeaveRequired( false ),
1998 mKeyboardFocusable( false ),
1999 mDerivedRequiresTouch( false ),
2000 mDerivedRequiresMouseWheelEvent( false ),
2001 mOnStageSignalled( false ),
2002 mInheritRotation( true ),
2003 mInheritScale( true ),
2004 mDrawMode( DrawMode::NORMAL ),
2005 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2006 mColorMode( Node::DEFAULT_COLOR_MODE )
2010 void Actor::Initialize()
2012 mStage = Stage::GetCurrent();
2015 SceneGraph::Node* node = CreateNode();
2017 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2018 mNode = node; // Keep raw-pointer to Node
2020 if(!mDefaultPropertyLookup)
2022 mDefaultPropertyLookup = new DefaultPropertyLookup();
2024 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2026 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2037 // Remove mParent pointers from children even if we're destroying core,
2038 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2041 ActorConstIter endIter = mChildren->end();
2042 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2044 Actor& actor = GetImplementation( *iter );
2045 actor.SetParent( NULL );
2050 // Guard to allow handle destruction after Core has been destroyed
2051 if( Stage::IsInstalled() )
2055 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2056 mNode = NULL; // Node is about to be destroyed
2062 #ifdef DYNAMICS_SUPPORT
2064 delete mDynamicsData;
2067 // Cleanup optional gesture data
2068 delete mGestureData;
2070 // Cleanup optional parent origin and anchor
2071 delete mParentOrigin;
2072 delete mAnchorPoint;
2075 void Actor::ConnectToStage( Stage& stage, int index )
2077 // This container is used instead of walking the Actor hierachy.
2078 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2079 ActorContainer connectionList;
2081 // This stage is atomic i.e. not interrupted by user callbacks
2082 RecursiveConnectToStage( stage, connectionList, index );
2084 // Notify applications about the newly connected actors.
2085 const ActorIter endIter = connectionList.end();
2086 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2088 Actor& actor = GetImplementation(*iter);
2089 actor.NotifyStageConnection();
2093 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList, int index )
2095 DALI_ASSERT_ALWAYS( !OnStage() );
2099 ConnectToSceneGraph(index);
2101 // Notification for internal derived classes
2102 OnStageConnectionInternal();
2104 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2105 connectionList.push_back( Dali::Actor(this) );
2107 // Recursively connect children
2110 ActorConstIter endIter = mChildren->end();
2111 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2113 Actor& actor = GetImplementation( *iter );
2114 actor.RecursiveConnectToStage( stage, connectionList );
2120 * This method is called when the Actor is connected to the Stage.
2121 * The parent must have added its Node to the scene-graph.
2122 * The child must connect its Node to the parent's Node.
2123 * This is resursive; the child calls ConnectToStage() for its children.
2125 void Actor::ConnectToSceneGraph(int index)
2127 DALI_ASSERT_DEBUG( mNode != NULL);
2128 DALI_ASSERT_DEBUG( mParent != NULL);
2129 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2133 // Reparent Node in next Update
2134 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2137 // Notify attachment
2140 mAttachment->Connect();
2143 #ifdef DYNAMICS_SUPPORT
2145 if( NULL != mDynamicsData )
2151 // Notification for ProxyObject::Observers
2155 void Actor::NotifyStageConnection()
2157 // Actors can be removed (in a callback), before the on-stage stage is reported.
2158 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2159 if ( OnStage() && !mOnStageSignalled )
2161 // Notification for external (CustomActor) derived classes
2162 OnStageConnectionExternal();
2164 if ( !mOnStageSignalV2.Empty() )
2166 Dali::Actor handle( this );
2167 mOnStageSignalV2.Emit( handle );
2170 // Guard against Remove during callbacks
2173 mOnStageSignalled = true; // signal required next time Actor is removed
2178 void Actor::DisconnectFromStage()
2180 // This container is used instead of walking the Actor hierachy.
2181 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2182 ActorContainer disconnectionList;
2184 // This stage is atomic i.e. not interrupted by user callbacks
2185 RecursiveDisconnectFromStage( disconnectionList );
2187 // Notify applications about the newly disconnected actors.
2188 const ActorIter endIter = disconnectionList.end();
2189 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2191 Actor& actor = GetImplementation(*iter);
2192 actor.NotifyStageDisconnection();
2196 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2198 DALI_ASSERT_ALWAYS( OnStage() );
2200 // Recursively disconnect children
2203 ActorConstIter endIter = mChildren->end();
2204 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2206 Actor& actor = GetImplementation( *iter );
2207 actor.RecursiveDisconnectFromStage( disconnectionList );
2211 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2212 disconnectionList.push_back( Dali::Actor(this) );
2214 // Notification for internal derived classes
2215 OnStageDisconnectionInternal();
2217 DisconnectFromSceneGraph();
2223 * This method is called by an actor or its parent, before a node removal message is sent.
2224 * This is recursive; the child calls DisconnectFromStage() for its children.
2226 void Actor::DisconnectFromSceneGraph()
2228 // Notification for ProxyObject::Observers
2229 OnSceneObjectRemove();
2231 // Notify attachment
2234 mAttachment->Disconnect();
2237 #ifdef DYNAMICS_SUPPORT
2239 if( NULL != mDynamicsData )
2241 DisconnectDynamics();
2246 void Actor::NotifyStageDisconnection()
2248 // Actors can be added (in a callback), before the off-stage state is reported.
2249 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2250 // only do this step if there is a stage, i.e. Core is not being shut down
2251 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2253 // Notification for external (CustomeActor) derived classes
2254 OnStageDisconnectionExternal();
2256 if( !mOffStageSignalV2.Empty() )
2258 Dali::Actor handle( this );
2259 mOffStageSignalV2.Emit( handle );
2262 // Guard against Add during callbacks
2265 mOnStageSignalled = false; // signal required next time Actor is added
2270 bool Actor::IsNodeConnected() const
2272 bool connected( false );
2277 if( mNode->IsRoot() || mNode->GetParent() )
2286 bool Actor::IsSceneObjectRemovable() const
2291 unsigned int Actor::GetDefaultPropertyCount() const
2293 return DEFAULT_PROPERTY_COUNT;
2296 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2298 indices.reserve( DEFAULT_PROPERTY_COUNT );
2300 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2302 indices.push_back( i );
2306 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2308 if( index < DEFAULT_PROPERTY_COUNT )
2310 return DEFAULT_PROPERTY_DETAILS[index].name;
2314 // index out of range..return empty string
2315 return String::EMPTY;
2319 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2321 Property::Index index = Property::INVALID_INDEX;
2323 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2325 // Look for name in default properties
2326 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2327 if ( mDefaultPropertyLookup->end() != result )
2329 index = result->second;
2335 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2337 if( index < DEFAULT_PROPERTY_COUNT )
2339 return DEFAULT_PROPERTY_DETAILS[index].writable;
2347 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2349 if( index < DEFAULT_PROPERTY_COUNT )
2351 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2359 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2361 if( index < DEFAULT_PROPERTY_COUNT )
2363 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2371 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2373 if( index < DEFAULT_PROPERTY_COUNT )
2375 return DEFAULT_PROPERTY_DETAILS[index].type;
2379 // index out of range...return Property::NONE
2380 return Property::NONE;
2384 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2388 case Dali::Actor::PARENT_ORIGIN:
2390 SetParentOrigin( property.Get<Vector3>() );
2394 case Dali::Actor::PARENT_ORIGIN_X:
2396 SetParentOriginX( property.Get<float>() );
2400 case Dali::Actor::PARENT_ORIGIN_Y:
2402 SetParentOriginY( property.Get<float>() );
2406 case Dali::Actor::PARENT_ORIGIN_Z:
2408 SetParentOriginZ( property.Get<float>() );
2412 case Dali::Actor::ANCHOR_POINT:
2414 SetAnchorPoint( property.Get<Vector3>() );
2418 case Dali::Actor::ANCHOR_POINT_X:
2420 SetAnchorPointX( property.Get<float>() );
2424 case Dali::Actor::ANCHOR_POINT_Y:
2426 SetAnchorPointY( property.Get<float>() );
2430 case Dali::Actor::ANCHOR_POINT_Z:
2432 SetAnchorPointZ( property.Get<float>() );
2436 case Dali::Actor::SIZE:
2438 SetSize( property.Get<Vector3>() );
2442 case Dali::Actor::SIZE_WIDTH:
2444 SetWidth( property.Get<float>() );
2448 case Dali::Actor::SIZE_HEIGHT:
2450 SetHeight( property.Get<float>() );
2454 case Dali::Actor::SIZE_DEPTH:
2456 SetDepth( property.Get<float>() );
2460 case Dali::Actor::POSITION:
2462 SetPosition( property.Get<Vector3>() );
2466 case Dali::Actor::POSITION_X:
2468 SetX( property.Get<float>() );
2472 case Dali::Actor::POSITION_Y:
2474 SetY( property.Get<float>() );
2478 case Dali::Actor::POSITION_Z:
2480 SetZ( property.Get<float>() );
2484 case Dali::Actor::ROTATION:
2486 SetRotation( property.Get<Quaternion>() );
2490 case Dali::Actor::SCALE:
2492 SetScale( property.Get<Vector3>() );
2496 case Dali::Actor::SCALE_X:
2498 SetScaleX( property.Get<float>() );
2502 case Dali::Actor::SCALE_Y:
2504 SetScaleY( property.Get<float>() );
2508 case Dali::Actor::SCALE_Z:
2510 SetScaleZ( property.Get<float>() );
2514 case Dali::Actor::VISIBLE:
2516 SetVisible( property.Get<bool>() );
2520 case Dali::Actor::COLOR:
2522 SetColor( property.Get<Vector4>() );
2526 case Dali::Actor::COLOR_RED:
2528 SetColorRed( property.Get<float>() );
2532 case Dali::Actor::COLOR_GREEN:
2534 SetColorGreen( property.Get<float>() );
2538 case Dali::Actor::COLOR_BLUE:
2540 SetColorBlue( property.Get<float>() );
2544 case Dali::Actor::COLOR_ALPHA:
2546 SetOpacity( property.Get<float>() );
2550 case Dali::Actor::NAME:
2552 SetName( property.Get<std::string>() );
2556 case Dali::Actor::SENSITIVE:
2558 SetSensitive( property.Get<bool>() );
2562 case Dali::Actor::LEAVE_REQUIRED:
2564 SetLeaveRequired( property.Get<bool>() );
2568 case Dali::Actor::INHERIT_ROTATION:
2570 SetInheritRotation( property.Get<bool>() );
2574 case Dali::Actor::INHERIT_SCALE:
2576 SetInheritScale( property.Get<bool>() );
2580 case Dali::Actor::COLOR_MODE:
2582 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2586 case Dali::Actor::POSITION_INHERITANCE:
2588 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2592 case Dali::Actor::DRAW_MODE:
2594 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2600 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2606 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2608 // TODO: This should be deprecated
2609 OnPropertySet(index, value);
2611 if(entry.IsAnimatable())
2613 // TODO: ADD MATRIX & MATRIX3 types
2615 switch ( entry.type )
2617 case Property::BOOLEAN:
2619 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2620 DALI_ASSERT_DEBUG( NULL != property );
2622 // property is being used in a separate thread; queue a message to set the property
2623 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2628 case Property::FLOAT:
2630 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2631 DALI_ASSERT_DEBUG( NULL != property );
2633 // property is being used in a separate thread; queue a message to set the property
2634 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2639 case Property::INTEGER:
2641 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2642 DALI_ASSERT_DEBUG( NULL != property );
2644 // property is being used in a separate thread; queue a message to set the property
2645 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2650 case Property::VECTOR2:
2652 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2653 DALI_ASSERT_DEBUG( NULL != property );
2655 // property is being used in a separate thread; queue a message to set the property
2656 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2661 case Property::VECTOR3:
2663 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2664 DALI_ASSERT_DEBUG( NULL != property );
2666 // property is being used in a separate thread; queue a message to set the property
2667 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2672 case Property::VECTOR4:
2674 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2675 DALI_ASSERT_DEBUG( NULL != property );
2677 // property is being used in a separate thread; queue a message to set the property
2678 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2683 case Property::ROTATION:
2685 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2686 DALI_ASSERT_DEBUG( NULL != property );
2688 // property is being used in a separate thread; queue a message to set the property
2689 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2696 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2703 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2705 Property::Value value;
2709 case Dali::Actor::PARENT_ORIGIN:
2711 value = GetCurrentParentOrigin();
2715 case Dali::Actor::PARENT_ORIGIN_X:
2717 value = GetCurrentParentOrigin().x;
2721 case Dali::Actor::PARENT_ORIGIN_Y:
2723 value = GetCurrentParentOrigin().y;
2727 case Dali::Actor::PARENT_ORIGIN_Z:
2729 value = GetCurrentParentOrigin().z;
2733 case Dali::Actor::ANCHOR_POINT:
2735 value = GetCurrentAnchorPoint();
2739 case Dali::Actor::ANCHOR_POINT_X:
2741 value = GetCurrentAnchorPoint().x;
2745 case Dali::Actor::ANCHOR_POINT_Y:
2747 value = GetCurrentAnchorPoint().y;
2751 case Dali::Actor::ANCHOR_POINT_Z:
2753 value = GetCurrentAnchorPoint().z;
2757 case Dali::Actor::SIZE:
2759 value = GetCurrentSize();
2763 case Dali::Actor::SIZE_WIDTH:
2765 value = GetCurrentSize().width;
2769 case Dali::Actor::SIZE_HEIGHT:
2771 value = GetCurrentSize().height;
2775 case Dali::Actor::SIZE_DEPTH:
2777 value = GetCurrentSize().depth;
2781 case Dali::Actor::POSITION:
2783 value = GetCurrentPosition();
2787 case Dali::Actor::POSITION_X:
2789 value = GetCurrentPosition().x;
2793 case Dali::Actor::POSITION_Y:
2795 value = GetCurrentPosition().y;
2799 case Dali::Actor::POSITION_Z:
2801 value = GetCurrentPosition().z;
2805 case Dali::Actor::WORLD_POSITION:
2807 value = GetCurrentWorldPosition();
2811 case Dali::Actor::WORLD_POSITION_X:
2813 value = GetCurrentWorldPosition().x;
2817 case Dali::Actor::WORLD_POSITION_Y:
2819 value = GetCurrentWorldPosition().y;
2823 case Dali::Actor::WORLD_POSITION_Z:
2825 value = GetCurrentWorldPosition().z;
2829 case Dali::Actor::ROTATION:
2831 value = GetCurrentRotation();
2835 case Dali::Actor::WORLD_ROTATION:
2837 value = GetCurrentWorldRotation();
2841 case Dali::Actor::SCALE:
2843 value = GetCurrentScale();
2847 case Dali::Actor::SCALE_X:
2849 value = GetCurrentScale().x;
2853 case Dali::Actor::SCALE_Y:
2855 value = GetCurrentScale().y;
2859 case Dali::Actor::SCALE_Z:
2861 value = GetCurrentScale().z;
2865 case Dali::Actor::WORLD_SCALE:
2867 value = GetCurrentWorldScale();
2871 case Dali::Actor::VISIBLE:
2873 value = IsVisible();
2877 case Dali::Actor::COLOR:
2879 value = GetCurrentColor();
2883 case Dali::Actor::COLOR_RED:
2885 value = GetCurrentColor().r;
2889 case Dali::Actor::COLOR_GREEN:
2891 value = GetCurrentColor().g;
2895 case Dali::Actor::COLOR_BLUE:
2897 value = GetCurrentColor().b;
2901 case Dali::Actor::COLOR_ALPHA:
2903 value = GetCurrentColor().a;
2907 case Dali::Actor::WORLD_COLOR:
2909 value = GetCurrentWorldColor();
2913 case Dali::Actor::WORLD_MATRIX:
2915 value = GetCurrentWorldMatrix();
2919 case Dali::Actor::NAME:
2925 case Dali::Actor::SENSITIVE:
2927 value = IsSensitive();
2931 case Dali::Actor::LEAVE_REQUIRED:
2933 value = GetLeaveRequired();
2937 case Dali::Actor::INHERIT_ROTATION:
2939 value = IsRotationInherited();
2943 case Dali::Actor::INHERIT_SCALE:
2945 value = IsScaleInherited();
2949 case Dali::Actor::COLOR_MODE:
2951 value = Scripting::GetColorMode( GetColorMode() );
2955 case Dali::Actor::POSITION_INHERITANCE:
2957 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2961 case Dali::Actor::DRAW_MODE:
2963 value = Scripting::GetDrawMode( GetDrawMode() );
2969 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2977 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2981 // mNode is being used in a separate thread; queue a message to add the property
2982 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2986 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2988 // This method should only return an object connected to the scene-graph
2989 return OnStage() ? mNode : NULL;
2992 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2994 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2996 const PropertyBase* property( NULL );
2998 // This method should only return a property of an object connected to the scene-graph
3004 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3006 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3008 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3010 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3012 else if( NULL != mNode )
3016 case Dali::Actor::SIZE:
3017 property = &mNode->mSize;
3020 case Dali::Actor::SIZE_WIDTH:
3021 property = &mNode->mSize;
3024 case Dali::Actor::SIZE_HEIGHT:
3025 property = &mNode->mSize;
3028 case Dali::Actor::SIZE_DEPTH:
3029 property = &mNode->mSize;
3032 case Dali::Actor::POSITION:
3033 property = &mNode->mPosition;
3036 case Dali::Actor::POSITION_X:
3037 property = &mNode->mPosition;
3040 case Dali::Actor::POSITION_Y:
3041 property = &mNode->mPosition;
3044 case Dali::Actor::POSITION_Z:
3045 property = &mNode->mPosition;
3048 case Dali::Actor::ROTATION:
3049 property = &mNode->mRotation;
3052 case Dali::Actor::SCALE:
3053 property = &mNode->mScale;
3056 case Dali::Actor::SCALE_X:
3057 property = &mNode->mScale;
3060 case Dali::Actor::SCALE_Y:
3061 property = &mNode->mScale;
3064 case Dali::Actor::SCALE_Z:
3065 property = &mNode->mScale;
3068 case Dali::Actor::VISIBLE:
3069 property = &mNode->mVisible;
3072 case Dali::Actor::COLOR:
3073 property = &mNode->mColor;
3076 case Dali::Actor::COLOR_RED:
3077 property = &mNode->mColor;
3080 case Dali::Actor::COLOR_GREEN:
3081 property = &mNode->mColor;
3084 case Dali::Actor::COLOR_BLUE:
3085 property = &mNode->mColor;
3088 case Dali::Actor::COLOR_ALPHA:
3089 property = &mNode->mColor;
3100 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3102 const PropertyInputImpl* property( NULL );
3104 // This method should only return a property of an object connected to the scene-graph
3110 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3112 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3114 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3116 property = entry->second.GetSceneGraphProperty();
3118 else if( NULL != mNode )
3122 case Dali::Actor::PARENT_ORIGIN:
3123 property = &mNode->mParentOrigin;
3126 case Dali::Actor::PARENT_ORIGIN_X:
3127 property = &mNode->mParentOrigin;
3130 case Dali::Actor::PARENT_ORIGIN_Y:
3131 property = &mNode->mParentOrigin;
3134 case Dali::Actor::PARENT_ORIGIN_Z:
3135 property = &mNode->mParentOrigin;
3138 case Dali::Actor::ANCHOR_POINT:
3139 property = &mNode->mAnchorPoint;
3142 case Dali::Actor::ANCHOR_POINT_X:
3143 property = &mNode->mAnchorPoint;
3146 case Dali::Actor::ANCHOR_POINT_Y:
3147 property = &mNode->mAnchorPoint;
3150 case Dali::Actor::ANCHOR_POINT_Z:
3151 property = &mNode->mAnchorPoint;
3154 case Dali::Actor::SIZE:
3155 property = &mNode->mSize;
3158 case Dali::Actor::SIZE_WIDTH:
3159 property = &mNode->mSize;
3162 case Dali::Actor::SIZE_HEIGHT:
3163 property = &mNode->mSize;
3166 case Dali::Actor::SIZE_DEPTH:
3167 property = &mNode->mSize;
3170 case Dali::Actor::POSITION:
3171 property = &mNode->mPosition;
3174 case Dali::Actor::POSITION_X:
3175 property = &mNode->mPosition;
3178 case Dali::Actor::POSITION_Y:
3179 property = &mNode->mPosition;
3182 case Dali::Actor::POSITION_Z:
3183 property = &mNode->mPosition;
3186 case Dali::Actor::WORLD_POSITION:
3187 property = &mNode->mWorldPosition;
3190 case Dali::Actor::WORLD_POSITION_X:
3191 property = &mNode->mWorldPosition;
3194 case Dali::Actor::WORLD_POSITION_Y:
3195 property = &mNode->mWorldPosition;
3198 case Dali::Actor::WORLD_POSITION_Z:
3199 property = &mNode->mWorldPosition;
3202 case Dali::Actor::ROTATION:
3203 property = &mNode->mRotation;
3206 case Dali::Actor::WORLD_ROTATION:
3207 property = &mNode->mWorldRotation;
3210 case Dali::Actor::SCALE:
3211 property = &mNode->mScale;
3214 case Dali::Actor::SCALE_X:
3215 property = &mNode->mScale;
3218 case Dali::Actor::SCALE_Y:
3219 property = &mNode->mScale;
3222 case Dali::Actor::SCALE_Z:
3223 property = &mNode->mScale;
3226 case Dali::Actor::WORLD_SCALE:
3227 property = &mNode->mWorldScale;
3230 case Dali::Actor::VISIBLE:
3231 property = &mNode->mVisible;
3234 case Dali::Actor::COLOR:
3235 property = &mNode->mColor;
3238 case Dali::Actor::COLOR_RED:
3239 property = &mNode->mColor;
3242 case Dali::Actor::COLOR_GREEN:
3243 property = &mNode->mColor;
3246 case Dali::Actor::COLOR_BLUE:
3247 property = &mNode->mColor;
3250 case Dali::Actor::COLOR_ALPHA:
3251 property = &mNode->mColor;
3254 case Dali::Actor::WORLD_COLOR:
3255 property = &mNode->mWorldColor;
3258 case Dali::Actor::WORLD_MATRIX:
3259 property = &mNode->mWorldMatrix;
3270 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3272 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3276 case Dali::Actor::PARENT_ORIGIN_X:
3277 case Dali::Actor::ANCHOR_POINT_X:
3278 case Dali::Actor::SIZE_WIDTH:
3279 case Dali::Actor::POSITION_X:
3280 case Dali::Actor::SCALE_X:
3281 case Dali::Actor::COLOR_RED:
3282 case Dali::Actor::WORLD_POSITION_X:
3288 case Dali::Actor::PARENT_ORIGIN_Y:
3289 case Dali::Actor::ANCHOR_POINT_Y:
3290 case Dali::Actor::SIZE_HEIGHT:
3291 case Dali::Actor::POSITION_Y:
3292 case Dali::Actor::SCALE_Y:
3293 case Dali::Actor::COLOR_GREEN:
3294 case Dali::Actor::WORLD_POSITION_Y:
3300 case Dali::Actor::PARENT_ORIGIN_Z:
3301 case Dali::Actor::ANCHOR_POINT_Z:
3302 case Dali::Actor::SIZE_DEPTH:
3303 case Dali::Actor::POSITION_Z:
3304 case Dali::Actor::SCALE_Z:
3305 case Dali::Actor::COLOR_BLUE:
3306 case Dali::Actor::WORLD_POSITION_Z:
3312 case Dali::Actor::COLOR_ALPHA:
3325 return componentIndex;
3328 void Actor::SetParent(Actor* parent, int index)
3332 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3336 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3339 StagePtr stage = parent->mStage;
3341 // Instruct each actor to create a corresponding node in the scene graph
3342 ConnectToStage(*stage, index);
3345 else // parent being set to NULL
3347 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3351 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3354 DALI_ASSERT_ALWAYS(mNode != NULL);
3358 // Disconnect the Node & its children from the scene-graph.
3359 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3362 // Instruct each actor to discard pointers to the scene-graph
3363 DisconnectFromStage();
3368 SceneGraph::Node* Actor::CreateNode() const
3373 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3376 Actor* actor = dynamic_cast<Actor*>(object);
3380 if(Dali::Actor::ACTION_SHOW == actionName)
3382 actor->SetVisible(true);
3385 else if(Dali::Actor::ACTION_HIDE == actionName)
3387 actor->SetVisible(false);
3395 } // namespace Internal