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)
1108 // mNode is being used in a separate thread; queue a message to set the value & base value
1109 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1111 // Notification for derived classes
1114 // Emit signal for application developer
1116 if( !mSetSizeSignalV2.Empty() )
1118 Dali::Actor handle( this );
1119 mSetSizeSignalV2.Emit( handle, mSize );
1124 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1128 // Notify deriving classes
1129 OnSizeAnimation( animation, targetSize );
1132 void Actor::SetWidth( float width )
1136 // mNode is being used in a separate thread; queue a message to set the value & base value
1137 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1141 void Actor::SetHeight( float height )
1145 // mNode is being used in a separate thread; queue a message to set the value & base value
1146 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1150 void Actor::SetDepth( float depth )
1154 // mNode is being used in a separate thread; queue a message to set the value & base value
1155 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1159 const Vector3& Actor::GetSize() const
1164 const Vector3& Actor::GetCurrentSize() const
1168 // mNode is being used in a separate thread; copy the value from the previous update
1169 return mNode->GetSize( mStage->GetEventBufferIndex() );
1172 return Vector3::ZERO;
1175 Vector3 Actor::GetNaturalSize() const
1177 // It is up to deriving classes to return the appropriate natural size
1178 return Vector3( 0.0f, 0.0f, 0.0f );
1182 #ifdef DYNAMICS_SUPPORT
1184 //--------------- Dynamics ---------------
1186 void Actor::DisableDynamics()
1188 if( NULL != mDynamicsData )
1190 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1192 // ensure dynamics object are disconnected from scene
1193 DisconnectDynamics();
1195 // delete joint owned by this actor
1196 while( !mDynamicsData->joints.empty() )
1198 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1201 // delete other joints referencing this actor
1202 while( !mDynamicsData->referencedJoints.empty() )
1204 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1205 ActorPtr jointOwner( joint->GetActor( true ) );
1208 jointOwner->RemoveDynamicsJoint( joint );
1212 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1215 // delete the DynamicsBody object
1216 mDynamicsData->body.Reset();
1218 // Discard Dynamics data structure
1219 delete mDynamicsData;
1220 mDynamicsData = NULL;
1224 DynamicsBodyPtr Actor::GetDynamicsBody() const
1226 DynamicsBodyPtr body;
1228 if( NULL != mDynamicsData )
1230 body = mDynamicsData->body;
1236 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1238 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1240 if( NULL == mDynamicsData )
1242 mDynamicsData = new DynamicsData( this );
1245 if( !mDynamicsData->body )
1247 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1251 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1254 if( mParent == world->GetRootActor().Get() )
1256 mDynamicsData->body->Connect(*mStage);
1262 return mDynamicsData->body;
1265 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1267 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1268 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1271 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1273 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1274 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1276 DynamicsJointPtr joint;
1278 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1282 if( NULL != mDynamicsData )
1284 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1286 if( mDynamicsData->joints.end() != it )
1288 // use existing joint
1294 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1295 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1299 bodyA = EnableDynamics( new DynamicsBodyConfig );
1304 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1307 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1308 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1310 if( OnStage() && attachedActor->OnStage() )
1312 joint->Connect(*mStage);
1315 attachedActor->ReferenceJoint( joint );
1317 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1318 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1325 const int Actor::GetNumberOfJoints() const
1327 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1330 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1332 DynamicsJointPtr joint;
1334 if( NULL != mDynamicsData )
1336 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1338 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1340 for( int i = 0; i < index; ++i )
1352 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1354 DynamicsJointPtr joint;
1356 if( NULL != mDynamicsData )
1358 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1360 if( mDynamicsData->joints.end() != it )
1362 // use existing joint
1370 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1372 if( NULL != mDynamicsData )
1374 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1375 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1377 for( ; it != endIt; ++it )
1379 if( it->second == joint.Get() )
1381 ActorPtr attachedActor( it->first );
1383 if( OnStage() && attachedActor && attachedActor->OnStage() )
1385 joint->Disconnect(*mStage);
1390 attachedActor->ReleaseJoint( joint );
1391 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1392 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1395 mDynamicsData->joints.erase(it);
1402 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1404 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1406 if( NULL != mDynamicsData )
1408 mDynamicsData->referencedJoints.push_back(joint);
1412 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1414 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1416 if( NULL != mDynamicsData )
1418 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1420 if( it != mDynamicsData->referencedJoints.end() )
1422 mDynamicsData->referencedJoints.erase( it );
1427 void Actor::SetDynamicsRoot(bool flag)
1429 if( mIsDynamicsRoot != flag )
1431 mIsDynamicsRoot = flag;
1433 if( OnStage() && mChildren )
1435 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1436 ActorIter end = mChildren->end();
1437 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1439 Actor& child = GetImplementation(*iter);
1441 if( child.GetDynamicsBody() )
1443 if( mIsDynamicsRoot )
1445 child.ConnectDynamics();
1449 child.DisconnectDynamics();
1457 bool Actor::IsDynamicsRoot() const
1459 return mIsDynamicsRoot;
1462 void Actor::AttachedActorOnStage( Dali::Actor actor )
1464 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1468 ActorPtr attachedActor( &GetImplementation(actor) );
1470 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1471 if( NULL != mDynamicsData )
1473 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1474 if( mDynamicsData->joints.end() != it )
1476 DynamicsJointPtr joint( it->second );
1477 joint->Connect(*mStage);
1483 void Actor::AttachedActorOffStage( Dali::Actor actor )
1485 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1489 ActorPtr attachedActor( &GetImplementation(actor) );
1491 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1492 if( NULL != mDynamicsData )
1494 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1495 if( mDynamicsData->joints.end() != it )
1497 DynamicsJointPtr joint( it->second );
1498 joint->Disconnect(*mStage);
1504 void Actor::ConnectDynamics()
1506 if( NULL != mDynamicsData && mDynamicsData->body )
1508 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1510 mDynamicsData->body->Connect(*mStage);
1512 // Connect all joints where attachedActor is also on stage
1513 if( !mDynamicsData->joints.empty() )
1515 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1516 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1518 for( ; it != endIt; ++it )
1520 Actor* attachedActor( it->first );
1521 if( NULL != attachedActor && attachedActor->OnStage() )
1523 DynamicsJointPtr joint( it->second );
1525 joint->Connect(*mStage);
1533 void Actor::DisconnectDynamics()
1535 if( NULL != mDynamicsData && mDynamicsData->body )
1539 mDynamicsData->body->Disconnect(*mStage);
1541 // Disconnect all joints
1542 if( !mDynamicsData->joints.empty() )
1544 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1545 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1547 for( ; it != endIt; ++it )
1549 DynamicsJointPtr joint( it->second );
1551 joint->Disconnect(*mStage);
1558 #endif // DYNAMICS_SUPPORT
1560 void Actor::SetOverlay(bool enable)
1562 // Setting STENCIL will override OVERLAY
1563 if( DrawMode::STENCIL != mDrawMode )
1565 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1569 bool Actor::IsOverlay() const
1571 return ( DrawMode::OVERLAY == mDrawMode );
1574 void Actor::SetDrawMode( DrawMode::Type drawMode )
1576 // this flag is not animatable so keep the value
1577 mDrawMode = drawMode;
1580 // mNode is being used in a separate thread; queue a message to set the value
1581 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1585 DrawMode::Type Actor::GetDrawMode() const
1590 bool Actor::ScreenToLocal( float& localX,
1593 float screenY ) const
1595 // only valid when on-stage
1598 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1600 Vector2 converted( screenX, screenY );
1602 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1603 const int taskCount = taskList.GetTaskCount();
1604 for( int i = taskCount - 1; i >= 0; --i )
1606 Dali::RenderTask task = taskList.GetTask( i );
1607 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1609 // found a task where this conversion was ok so return
1617 bool Actor::ScreenToLocal( RenderTask& renderTask,
1621 float screenY ) const
1623 bool retval = false;
1624 // only valid when on-stage
1627 CameraActor* camera = renderTask.GetCameraActor();
1631 renderTask.GetViewport( viewport );
1633 // need to translate coordinates to render tasks coordinate space
1634 Vector2 converted( screenX, screenY );
1635 if( renderTask.TranslateCoordinates( converted ) )
1637 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1644 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1645 const Matrix& projectionMatrix,
1646 const Viewport& viewport,
1650 float screenY ) const
1652 // Early-out if mNode is NULL
1658 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1660 // Calculate the ModelView matrix
1661 Matrix modelView(false/*don't init*/);
1662 // need to use the components as world matrix is only updated for actors that need it
1663 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1664 Matrix::Multiply(modelView, modelView, viewMatrix);
1666 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1667 Matrix invertedMvp(false/*don't init*/);
1668 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1669 bool success = invertedMvp.Invert();
1671 // Convert to GL coordinates
1672 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1677 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1684 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1690 if (XyPlaneIntersect(nearPos, farPos, local))
1692 Vector3 size = GetCurrentSize();
1693 localX = local.x + size.x * 0.5f;
1694 localY = local.y + size.y * 0.5f;
1705 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1708 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1710 Mathematical Formulation
1712 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1714 ( p - c ) dot ( p - c ) = r^2
1716 Given a ray with a point of origin 'o', and a direction vector 'd':
1718 ray(t) = o + td, t >= 0
1720 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1722 (o + td - c ) dot ( o + td - c ) = r^2
1724 To solve for t we first expand the above into a more recognisable quadratic equation form
1726 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1735 B = 2( o - c ) dot d
1736 C = ( o - c ) dot ( o - c ) - r^2
1738 which can be solved using a standard quadratic formula.
1740 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1742 Practical Simplification
1744 In a renderer, we often differentiate between world space and object space. In the object space
1745 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1746 into object space, the mathematical solution presented above can be simplified significantly.
1748 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1752 and we can find the t at which the (transformed) ray intersects the sphere by
1754 ( o + td ) dot ( o + td ) = r^2
1756 According to the reasoning above, we expand the above quadratic equation into the general form
1760 which now has coefficients:
1767 // Early out if mNode is NULL
1773 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1775 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1776 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1777 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1778 rayOrigin.y - translation.y,
1779 rayOrigin.z - translation.z);
1781 // Compute the radius is not needed, square radius it's enough.
1782 const Vector3& size( mNode->GetSize( bufferIndex ) );
1784 // Scale the sphere.
1785 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1787 const float width = size.width * scale.width;
1788 const float height = size.height * scale.height;
1790 float squareSphereRadius = 0.5f * ( width * width + height * height );
1792 float a = rayDir.Dot( rayDir ); // a
1793 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1794 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1796 return ( b2*b2 - a*c ) >= 0.f;
1799 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1806 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1808 // Transforms the ray to the local reference system.
1810 // Calculate the inverse of Model matrix
1811 Matrix invModelMatrix(false/*don't init*/);
1812 // need to use the components as world matrix is only updated for actors that need it
1813 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1815 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1816 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1818 // Test with the actor's XY plane (Normal = 0 0 1 1).
1820 float a = -rayOriginLocal.z;
1821 float b = rayDirLocal.z;
1823 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1825 // Ray travels distance * rayDirLocal to intersect with plane.
1828 const Vector3& size = mNode->GetSize( bufferIndex );
1830 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1831 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1833 // Test with the actor's geometry.
1834 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1841 void Actor::SetLeaveRequired(bool required)
1843 mLeaveRequired = required;
1846 bool Actor::GetLeaveRequired() const
1848 return mLeaveRequired;
1851 void Actor::SetKeyboardFocusable( bool focusable )
1853 mKeyboardFocusable = focusable;
1856 bool Actor::IsKeyboardFocusable() const
1858 return mKeyboardFocusable;
1861 bool Actor::GetTouchRequired() const
1863 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1866 bool Actor::GetMouseWheelEventRequired() const
1868 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1871 bool Actor::IsHittable() const
1873 return IsSensitive() &&
1875 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1879 ActorGestureData& Actor::GetGestureData()
1881 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1882 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1883 if ( NULL == mGestureData )
1885 mGestureData = new ActorGestureData;
1887 return *mGestureData;
1890 bool Actor::IsGestureRequred( Gesture::Type type ) const
1892 return mGestureData && mGestureData->IsGestureRequred( type );
1895 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1897 bool consumed = false;
1899 if ( !mTouchedSignalV2.Empty() )
1901 Dali::Actor handle( this );
1902 consumed = mTouchedSignalV2.Emit( handle, event );
1907 // Notification for derived classes
1908 consumed = OnTouchEvent( event );
1914 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1916 bool consumed = false;
1918 if ( !mMouseWheelEventSignalV2.Empty() )
1920 Dali::Actor handle( this );
1921 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1926 // Notification for derived classes
1927 consumed = OnMouseWheelEvent(event);
1933 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1935 return mTouchedSignalV2;
1938 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1940 return mMouseWheelEventSignalV2;
1943 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1945 return mSetSizeSignalV2;
1948 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1950 return mOnStageSignalV2;
1953 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1955 return mOffStageSignalV2;
1958 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1960 bool connected( true );
1961 Actor* actor = dynamic_cast<Actor*>(object);
1963 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1965 actor->TouchedSignal().Connect( tracker, functor );
1967 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1969 actor->MouseWheelEventSignal().Connect( tracker, functor );
1971 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1973 actor->SetSizeSignal().Connect( tracker, functor );
1975 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1977 actor->OnStageSignal().Connect( tracker, functor );
1979 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1981 actor->OffStageSignal().Connect( tracker, functor );
1985 // signalName does not match any signal
1992 Actor::Actor( DerivedType derivedType )
1997 mParentOrigin( NULL ),
1998 mAnchorPoint( NULL ),
1999 #ifdef DYNAMICS_SUPPORT
2000 mDynamicsData( NULL ),
2002 mGestureData( NULL ),
2004 mSize( 0.0f, 0.0f, 0.0f ),
2006 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2007 mIsRoot( ROOT_LAYER == derivedType ),
2008 mIsRenderable( RENDERABLE == derivedType ),
2009 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2010 mIsOnStage( false ),
2011 mIsDynamicsRoot(false),
2013 mLeaveRequired( false ),
2014 mKeyboardFocusable( false ),
2015 mDerivedRequiresTouch( false ),
2016 mDerivedRequiresMouseWheelEvent( false ),
2017 mOnStageSignalled( false ),
2018 mInheritRotation( true ),
2019 mInheritScale( true ),
2020 mDrawMode( DrawMode::NORMAL ),
2021 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2022 mColorMode( Node::DEFAULT_COLOR_MODE )
2026 void Actor::Initialize()
2028 mStage = Stage::GetCurrent();
2031 SceneGraph::Node* node = CreateNode();
2033 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2034 mNode = node; // Keep raw-pointer to Node
2036 if(!mDefaultPropertyLookup)
2038 mDefaultPropertyLookup = new DefaultPropertyLookup();
2040 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2042 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2053 // Remove mParent pointers from children even if we're destroying core,
2054 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2057 ActorConstIter endIter = mChildren->end();
2058 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2060 Actor& actor = GetImplementation( *iter );
2061 actor.SetParent( NULL );
2066 // Guard to allow handle destruction after Core has been destroyed
2067 if( Stage::IsInstalled() )
2071 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2072 mNode = NULL; // Node is about to be destroyed
2078 #ifdef DYNAMICS_SUPPORT
2080 delete mDynamicsData;
2083 // Cleanup optional gesture data
2084 delete mGestureData;
2086 // Cleanup optional parent origin and anchor
2087 delete mParentOrigin;
2088 delete mAnchorPoint;
2091 void Actor::ConnectToStage( Stage& stage, int index )
2093 // This container is used instead of walking the Actor hierachy.
2094 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2095 ActorContainer connectionList;
2097 // This stage is atomic i.e. not interrupted by user callbacks
2098 RecursiveConnectToStage( stage, connectionList, index );
2100 // Notify applications about the newly connected actors.
2101 const ActorIter endIter = connectionList.end();
2102 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2104 Actor& actor = GetImplementation(*iter);
2105 actor.NotifyStageConnection();
2109 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList, int index )
2111 DALI_ASSERT_ALWAYS( !OnStage() );
2115 ConnectToSceneGraph(index);
2117 // Notification for internal derived classes
2118 OnStageConnectionInternal();
2120 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2121 connectionList.push_back( Dali::Actor(this) );
2123 // Recursively connect children
2126 ActorConstIter endIter = mChildren->end();
2127 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2129 Actor& actor = GetImplementation( *iter );
2130 actor.RecursiveConnectToStage( stage, connectionList );
2136 * This method is called when the Actor is connected to the Stage.
2137 * The parent must have added its Node to the scene-graph.
2138 * The child must connect its Node to the parent's Node.
2139 * This is resursive; the child calls ConnectToStage() for its children.
2141 void Actor::ConnectToSceneGraph(int index)
2143 DALI_ASSERT_DEBUG( mNode != NULL);
2144 DALI_ASSERT_DEBUG( mParent != NULL);
2145 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2149 // Reparent Node in next Update
2150 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2153 // Notify attachment
2156 mAttachment->Connect();
2159 #ifdef DYNAMICS_SUPPORT
2161 if( NULL != mDynamicsData )
2167 // Notification for ProxyObject::Observers
2171 void Actor::NotifyStageConnection()
2173 // Actors can be removed (in a callback), before the on-stage stage is reported.
2174 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2175 if ( OnStage() && !mOnStageSignalled )
2177 // Notification for external (CustomActor) derived classes
2178 OnStageConnectionExternal();
2180 if ( !mOnStageSignalV2.Empty() )
2182 Dali::Actor handle( this );
2183 mOnStageSignalV2.Emit( handle );
2186 // Guard against Remove during callbacks
2189 mOnStageSignalled = true; // signal required next time Actor is removed
2194 void Actor::DisconnectFromStage()
2196 // This container is used instead of walking the Actor hierachy.
2197 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2198 ActorContainer disconnectionList;
2200 // This stage is atomic i.e. not interrupted by user callbacks
2201 RecursiveDisconnectFromStage( disconnectionList );
2203 // Notify applications about the newly disconnected actors.
2204 const ActorIter endIter = disconnectionList.end();
2205 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2207 Actor& actor = GetImplementation(*iter);
2208 actor.NotifyStageDisconnection();
2212 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2214 DALI_ASSERT_ALWAYS( OnStage() );
2216 // Recursively disconnect children
2219 ActorConstIter endIter = mChildren->end();
2220 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2222 Actor& actor = GetImplementation( *iter );
2223 actor.RecursiveDisconnectFromStage( disconnectionList );
2227 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2228 disconnectionList.push_back( Dali::Actor(this) );
2230 // Notification for internal derived classes
2231 OnStageDisconnectionInternal();
2233 DisconnectFromSceneGraph();
2239 * This method is called by an actor or its parent, before a node removal message is sent.
2240 * This is recursive; the child calls DisconnectFromStage() for its children.
2242 void Actor::DisconnectFromSceneGraph()
2244 // Notification for ProxyObject::Observers
2245 OnSceneObjectRemove();
2247 // Notify attachment
2250 mAttachment->Disconnect();
2253 #ifdef DYNAMICS_SUPPORT
2255 if( NULL != mDynamicsData )
2257 DisconnectDynamics();
2262 void Actor::NotifyStageDisconnection()
2264 // Actors can be added (in a callback), before the off-stage state is reported.
2265 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2266 // only do this step if there is a stage, i.e. Core is not being shut down
2267 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2269 // Notification for external (CustomeActor) derived classes
2270 OnStageDisconnectionExternal();
2272 if( !mOffStageSignalV2.Empty() )
2274 Dali::Actor handle( this );
2275 mOffStageSignalV2.Emit( handle );
2278 // Guard against Add during callbacks
2281 mOnStageSignalled = false; // signal required next time Actor is added
2286 bool Actor::IsNodeConnected() const
2288 bool connected( false );
2293 if( mNode->IsRoot() || mNode->GetParent() )
2302 bool Actor::IsSceneObjectRemovable() const
2307 unsigned int Actor::GetDefaultPropertyCount() const
2309 return DEFAULT_PROPERTY_COUNT;
2312 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2314 indices.reserve( DEFAULT_PROPERTY_COUNT );
2316 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2318 indices.push_back( i );
2322 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2324 if( index < DEFAULT_PROPERTY_COUNT )
2326 return DEFAULT_PROPERTY_DETAILS[index].name;
2330 // index out of range..return empty string
2331 return String::EMPTY;
2335 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2337 Property::Index index = Property::INVALID_INDEX;
2339 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2341 // Look for name in default properties
2342 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2343 if ( mDefaultPropertyLookup->end() != result )
2345 index = result->second;
2351 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2353 if( index < DEFAULT_PROPERTY_COUNT )
2355 return DEFAULT_PROPERTY_DETAILS[index].writable;
2363 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2365 if( index < DEFAULT_PROPERTY_COUNT )
2367 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2375 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2377 if( index < DEFAULT_PROPERTY_COUNT )
2379 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2387 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2389 if( index < DEFAULT_PROPERTY_COUNT )
2391 return DEFAULT_PROPERTY_DETAILS[index].type;
2395 // index out of range...return Property::NONE
2396 return Property::NONE;
2400 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2404 case Dali::Actor::PARENT_ORIGIN:
2406 SetParentOrigin( property.Get<Vector3>() );
2410 case Dali::Actor::PARENT_ORIGIN_X:
2412 SetParentOriginX( property.Get<float>() );
2416 case Dali::Actor::PARENT_ORIGIN_Y:
2418 SetParentOriginY( property.Get<float>() );
2422 case Dali::Actor::PARENT_ORIGIN_Z:
2424 SetParentOriginZ( property.Get<float>() );
2428 case Dali::Actor::ANCHOR_POINT:
2430 SetAnchorPoint( property.Get<Vector3>() );
2434 case Dali::Actor::ANCHOR_POINT_X:
2436 SetAnchorPointX( property.Get<float>() );
2440 case Dali::Actor::ANCHOR_POINT_Y:
2442 SetAnchorPointY( property.Get<float>() );
2446 case Dali::Actor::ANCHOR_POINT_Z:
2448 SetAnchorPointZ( property.Get<float>() );
2452 case Dali::Actor::SIZE:
2454 SetSize( property.Get<Vector3>() );
2458 case Dali::Actor::SIZE_WIDTH:
2460 SetWidth( property.Get<float>() );
2464 case Dali::Actor::SIZE_HEIGHT:
2466 SetHeight( property.Get<float>() );
2470 case Dali::Actor::SIZE_DEPTH:
2472 SetDepth( property.Get<float>() );
2476 case Dali::Actor::POSITION:
2478 SetPosition( property.Get<Vector3>() );
2482 case Dali::Actor::POSITION_X:
2484 SetX( property.Get<float>() );
2488 case Dali::Actor::POSITION_Y:
2490 SetY( property.Get<float>() );
2494 case Dali::Actor::POSITION_Z:
2496 SetZ( property.Get<float>() );
2500 case Dali::Actor::ROTATION:
2502 SetRotation( property.Get<Quaternion>() );
2506 case Dali::Actor::SCALE:
2508 SetScale( property.Get<Vector3>() );
2512 case Dali::Actor::SCALE_X:
2514 SetScaleX( property.Get<float>() );
2518 case Dali::Actor::SCALE_Y:
2520 SetScaleY( property.Get<float>() );
2524 case Dali::Actor::SCALE_Z:
2526 SetScaleZ( property.Get<float>() );
2530 case Dali::Actor::VISIBLE:
2532 SetVisible( property.Get<bool>() );
2536 case Dali::Actor::COLOR:
2538 SetColor( property.Get<Vector4>() );
2542 case Dali::Actor::COLOR_RED:
2544 SetColorRed( property.Get<float>() );
2548 case Dali::Actor::COLOR_GREEN:
2550 SetColorGreen( property.Get<float>() );
2554 case Dali::Actor::COLOR_BLUE:
2556 SetColorBlue( property.Get<float>() );
2560 case Dali::Actor::COLOR_ALPHA:
2562 SetOpacity( property.Get<float>() );
2566 case Dali::Actor::NAME:
2568 SetName( property.Get<std::string>() );
2572 case Dali::Actor::SENSITIVE:
2574 SetSensitive( property.Get<bool>() );
2578 case Dali::Actor::LEAVE_REQUIRED:
2580 SetLeaveRequired( property.Get<bool>() );
2584 case Dali::Actor::INHERIT_ROTATION:
2586 SetInheritRotation( property.Get<bool>() );
2590 case Dali::Actor::INHERIT_SCALE:
2592 SetInheritScale( property.Get<bool>() );
2596 case Dali::Actor::COLOR_MODE:
2598 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2602 case Dali::Actor::POSITION_INHERITANCE:
2604 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2608 case Dali::Actor::DRAW_MODE:
2610 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2616 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2622 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2624 // TODO: This should be deprecated
2625 OnPropertySet(index, value);
2627 if(entry.IsAnimatable())
2629 // TODO: ADD MATRIX & MATRIX3 types
2631 switch ( entry.type )
2633 case Property::BOOLEAN:
2635 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2636 DALI_ASSERT_DEBUG( NULL != property );
2638 // property is being used in a separate thread; queue a message to set the property
2639 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2644 case Property::FLOAT:
2646 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2647 DALI_ASSERT_DEBUG( NULL != property );
2649 // property is being used in a separate thread; queue a message to set the property
2650 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2655 case Property::INTEGER:
2657 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( 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<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2666 case Property::VECTOR2:
2668 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( 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<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2677 case Property::VECTOR3:
2679 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( 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<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2688 case Property::VECTOR4:
2690 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( 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<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2699 case Property::ROTATION:
2701 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( 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<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2712 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2719 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2721 Property::Value value;
2725 case Dali::Actor::PARENT_ORIGIN:
2727 value = GetCurrentParentOrigin();
2731 case Dali::Actor::PARENT_ORIGIN_X:
2733 value = GetCurrentParentOrigin().x;
2737 case Dali::Actor::PARENT_ORIGIN_Y:
2739 value = GetCurrentParentOrigin().y;
2743 case Dali::Actor::PARENT_ORIGIN_Z:
2745 value = GetCurrentParentOrigin().z;
2749 case Dali::Actor::ANCHOR_POINT:
2751 value = GetCurrentAnchorPoint();
2755 case Dali::Actor::ANCHOR_POINT_X:
2757 value = GetCurrentAnchorPoint().x;
2761 case Dali::Actor::ANCHOR_POINT_Y:
2763 value = GetCurrentAnchorPoint().y;
2767 case Dali::Actor::ANCHOR_POINT_Z:
2769 value = GetCurrentAnchorPoint().z;
2773 case Dali::Actor::SIZE:
2775 value = GetCurrentSize();
2779 case Dali::Actor::SIZE_WIDTH:
2781 value = GetCurrentSize().width;
2785 case Dali::Actor::SIZE_HEIGHT:
2787 value = GetCurrentSize().height;
2791 case Dali::Actor::SIZE_DEPTH:
2793 value = GetCurrentSize().depth;
2797 case Dali::Actor::POSITION:
2799 value = GetCurrentPosition();
2803 case Dali::Actor::POSITION_X:
2805 value = GetCurrentPosition().x;
2809 case Dali::Actor::POSITION_Y:
2811 value = GetCurrentPosition().y;
2815 case Dali::Actor::POSITION_Z:
2817 value = GetCurrentPosition().z;
2821 case Dali::Actor::WORLD_POSITION:
2823 value = GetCurrentWorldPosition();
2827 case Dali::Actor::WORLD_POSITION_X:
2829 value = GetCurrentWorldPosition().x;
2833 case Dali::Actor::WORLD_POSITION_Y:
2835 value = GetCurrentWorldPosition().y;
2839 case Dali::Actor::WORLD_POSITION_Z:
2841 value = GetCurrentWorldPosition().z;
2845 case Dali::Actor::ROTATION:
2847 value = GetCurrentRotation();
2851 case Dali::Actor::WORLD_ROTATION:
2853 value = GetCurrentWorldRotation();
2857 case Dali::Actor::SCALE:
2859 value = GetCurrentScale();
2863 case Dali::Actor::SCALE_X:
2865 value = GetCurrentScale().x;
2869 case Dali::Actor::SCALE_Y:
2871 value = GetCurrentScale().y;
2875 case Dali::Actor::SCALE_Z:
2877 value = GetCurrentScale().z;
2881 case Dali::Actor::WORLD_SCALE:
2883 value = GetCurrentWorldScale();
2887 case Dali::Actor::VISIBLE:
2889 value = IsVisible();
2893 case Dali::Actor::COLOR:
2895 value = GetCurrentColor();
2899 case Dali::Actor::COLOR_RED:
2901 value = GetCurrentColor().r;
2905 case Dali::Actor::COLOR_GREEN:
2907 value = GetCurrentColor().g;
2911 case Dali::Actor::COLOR_BLUE:
2913 value = GetCurrentColor().b;
2917 case Dali::Actor::COLOR_ALPHA:
2919 value = GetCurrentColor().a;
2923 case Dali::Actor::WORLD_COLOR:
2925 value = GetCurrentWorldColor();
2929 case Dali::Actor::WORLD_MATRIX:
2931 value = GetCurrentWorldMatrix();
2935 case Dali::Actor::NAME:
2941 case Dali::Actor::SENSITIVE:
2943 value = IsSensitive();
2947 case Dali::Actor::LEAVE_REQUIRED:
2949 value = GetLeaveRequired();
2953 case Dali::Actor::INHERIT_ROTATION:
2955 value = IsRotationInherited();
2959 case Dali::Actor::INHERIT_SCALE:
2961 value = IsScaleInherited();
2965 case Dali::Actor::COLOR_MODE:
2967 value = Scripting::GetColorMode( GetColorMode() );
2971 case Dali::Actor::POSITION_INHERITANCE:
2973 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2977 case Dali::Actor::DRAW_MODE:
2979 value = Scripting::GetDrawMode( GetDrawMode() );
2985 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2993 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2997 // mNode is being used in a separate thread; queue a message to add the property
2998 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3002 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3004 // This method should only return an object connected to the scene-graph
3005 return OnStage() ? mNode : NULL;
3008 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3010 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3012 const PropertyBase* property( NULL );
3014 // This method should only return a property of an object connected to the scene-graph
3020 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3022 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3024 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3026 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3028 else if( NULL != mNode )
3032 case Dali::Actor::SIZE:
3033 property = &mNode->mSize;
3036 case Dali::Actor::SIZE_WIDTH:
3037 property = &mNode->mSize;
3040 case Dali::Actor::SIZE_HEIGHT:
3041 property = &mNode->mSize;
3044 case Dali::Actor::SIZE_DEPTH:
3045 property = &mNode->mSize;
3048 case Dali::Actor::POSITION:
3049 property = &mNode->mPosition;
3052 case Dali::Actor::POSITION_X:
3053 property = &mNode->mPosition;
3056 case Dali::Actor::POSITION_Y:
3057 property = &mNode->mPosition;
3060 case Dali::Actor::POSITION_Z:
3061 property = &mNode->mPosition;
3064 case Dali::Actor::ROTATION:
3065 property = &mNode->mRotation;
3068 case Dali::Actor::SCALE:
3069 property = &mNode->mScale;
3072 case Dali::Actor::SCALE_X:
3073 property = &mNode->mScale;
3076 case Dali::Actor::SCALE_Y:
3077 property = &mNode->mScale;
3080 case Dali::Actor::SCALE_Z:
3081 property = &mNode->mScale;
3084 case Dali::Actor::VISIBLE:
3085 property = &mNode->mVisible;
3088 case Dali::Actor::COLOR:
3089 property = &mNode->mColor;
3092 case Dali::Actor::COLOR_RED:
3093 property = &mNode->mColor;
3096 case Dali::Actor::COLOR_GREEN:
3097 property = &mNode->mColor;
3100 case Dali::Actor::COLOR_BLUE:
3101 property = &mNode->mColor;
3104 case Dali::Actor::COLOR_ALPHA:
3105 property = &mNode->mColor;
3116 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3118 const PropertyInputImpl* property( NULL );
3120 // This method should only return a property of an object connected to the scene-graph
3126 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3128 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3130 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3132 property = entry->second.GetSceneGraphProperty();
3134 else if( NULL != mNode )
3138 case Dali::Actor::PARENT_ORIGIN:
3139 property = &mNode->mParentOrigin;
3142 case Dali::Actor::PARENT_ORIGIN_X:
3143 property = &mNode->mParentOrigin;
3146 case Dali::Actor::PARENT_ORIGIN_Y:
3147 property = &mNode->mParentOrigin;
3150 case Dali::Actor::PARENT_ORIGIN_Z:
3151 property = &mNode->mParentOrigin;
3154 case Dali::Actor::ANCHOR_POINT:
3155 property = &mNode->mAnchorPoint;
3158 case Dali::Actor::ANCHOR_POINT_X:
3159 property = &mNode->mAnchorPoint;
3162 case Dali::Actor::ANCHOR_POINT_Y:
3163 property = &mNode->mAnchorPoint;
3166 case Dali::Actor::ANCHOR_POINT_Z:
3167 property = &mNode->mAnchorPoint;
3170 case Dali::Actor::SIZE:
3171 property = &mNode->mSize;
3174 case Dali::Actor::SIZE_WIDTH:
3175 property = &mNode->mSize;
3178 case Dali::Actor::SIZE_HEIGHT:
3179 property = &mNode->mSize;
3182 case Dali::Actor::SIZE_DEPTH:
3183 property = &mNode->mSize;
3186 case Dali::Actor::POSITION:
3187 property = &mNode->mPosition;
3190 case Dali::Actor::POSITION_X:
3191 property = &mNode->mPosition;
3194 case Dali::Actor::POSITION_Y:
3195 property = &mNode->mPosition;
3198 case Dali::Actor::POSITION_Z:
3199 property = &mNode->mPosition;
3202 case Dali::Actor::WORLD_POSITION:
3203 property = &mNode->mWorldPosition;
3206 case Dali::Actor::WORLD_POSITION_X:
3207 property = &mNode->mWorldPosition;
3210 case Dali::Actor::WORLD_POSITION_Y:
3211 property = &mNode->mWorldPosition;
3214 case Dali::Actor::WORLD_POSITION_Z:
3215 property = &mNode->mWorldPosition;
3218 case Dali::Actor::ROTATION:
3219 property = &mNode->mRotation;
3222 case Dali::Actor::WORLD_ROTATION:
3223 property = &mNode->mWorldRotation;
3226 case Dali::Actor::SCALE:
3227 property = &mNode->mScale;
3230 case Dali::Actor::SCALE_X:
3231 property = &mNode->mScale;
3234 case Dali::Actor::SCALE_Y:
3235 property = &mNode->mScale;
3238 case Dali::Actor::SCALE_Z:
3239 property = &mNode->mScale;
3242 case Dali::Actor::WORLD_SCALE:
3243 property = &mNode->mWorldScale;
3246 case Dali::Actor::VISIBLE:
3247 property = &mNode->mVisible;
3250 case Dali::Actor::COLOR:
3251 property = &mNode->mColor;
3254 case Dali::Actor::COLOR_RED:
3255 property = &mNode->mColor;
3258 case Dali::Actor::COLOR_GREEN:
3259 property = &mNode->mColor;
3262 case Dali::Actor::COLOR_BLUE:
3263 property = &mNode->mColor;
3266 case Dali::Actor::COLOR_ALPHA:
3267 property = &mNode->mColor;
3270 case Dali::Actor::WORLD_COLOR:
3271 property = &mNode->mWorldColor;
3274 case Dali::Actor::WORLD_MATRIX:
3275 property = &mNode->mWorldMatrix;
3286 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3288 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3292 case Dali::Actor::PARENT_ORIGIN_X:
3293 case Dali::Actor::ANCHOR_POINT_X:
3294 case Dali::Actor::SIZE_WIDTH:
3295 case Dali::Actor::POSITION_X:
3296 case Dali::Actor::SCALE_X:
3297 case Dali::Actor::COLOR_RED:
3298 case Dali::Actor::WORLD_POSITION_X:
3304 case Dali::Actor::PARENT_ORIGIN_Y:
3305 case Dali::Actor::ANCHOR_POINT_Y:
3306 case Dali::Actor::SIZE_HEIGHT:
3307 case Dali::Actor::POSITION_Y:
3308 case Dali::Actor::SCALE_Y:
3309 case Dali::Actor::COLOR_GREEN:
3310 case Dali::Actor::WORLD_POSITION_Y:
3316 case Dali::Actor::PARENT_ORIGIN_Z:
3317 case Dali::Actor::ANCHOR_POINT_Z:
3318 case Dali::Actor::SIZE_DEPTH:
3319 case Dali::Actor::POSITION_Z:
3320 case Dali::Actor::SCALE_Z:
3321 case Dali::Actor::COLOR_BLUE:
3322 case Dali::Actor::WORLD_POSITION_Z:
3328 case Dali::Actor::COLOR_ALPHA:
3341 return componentIndex;
3344 void Actor::SetParent(Actor* parent, int index)
3348 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3352 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3355 StagePtr stage = parent->mStage;
3357 // Instruct each actor to create a corresponding node in the scene graph
3358 ConnectToStage(*stage, index);
3361 else // parent being set to NULL
3363 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3367 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3370 DALI_ASSERT_ALWAYS(mNode != NULL);
3374 // Disconnect the Node & its children from the scene-graph.
3375 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3378 // Instruct each actor to discard pointers to the scene-graph
3379 DisconnectFromStage();
3384 SceneGraph::Node* Actor::CreateNode() const
3389 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3392 Actor* actor = dynamic_cast<Actor*>(object);
3396 if(Dali::Actor::ACTION_SHOW == actionName)
3398 actor->SetVisible(true);
3401 else if(Dali::Actor::ACTION_HIDE == actionName)
3403 actor->SetVisible(false);
3411 } // namespace Internal