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/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
59 using Dali::Internal::SceneGraph::Node;
60 using Dali::Internal::SceneGraph::AnimatableProperty;
61 using Dali::Internal::SceneGraph::PropertyBase;
66 const Property::Index Actor::PARENT_ORIGIN = 0;
67 const Property::Index Actor::PARENT_ORIGIN_X = 1;
68 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
69 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
70 const Property::Index Actor::ANCHOR_POINT = 4;
71 const Property::Index Actor::ANCHOR_POINT_X = 5;
72 const Property::Index Actor::ANCHOR_POINT_Y = 6;
73 const Property::Index Actor::ANCHOR_POINT_Z = 7;
74 const Property::Index Actor::SIZE = 8;
75 const Property::Index Actor::SIZE_WIDTH = 9;
76 const Property::Index Actor::SIZE_HEIGHT = 10;
77 const Property::Index Actor::SIZE_DEPTH = 11;
78 const Property::Index Actor::POSITION = 12;
79 const Property::Index Actor::POSITION_X = 13;
80 const Property::Index Actor::POSITION_Y = 14;
81 const Property::Index Actor::POSITION_Z = 15;
82 const Property::Index Actor::WORLD_POSITION = 16;
83 const Property::Index Actor::WORLD_POSITION_X = 17;
84 const Property::Index Actor::WORLD_POSITION_Y = 18;
85 const Property::Index Actor::WORLD_POSITION_Z = 19;
86 const Property::Index Actor::ROTATION = 20;
87 const Property::Index Actor::WORLD_ROTATION = 21;
88 const Property::Index Actor::SCALE = 22;
89 const Property::Index Actor::SCALE_X = 23;
90 const Property::Index Actor::SCALE_Y = 24;
91 const Property::Index Actor::SCALE_Z = 25;
92 const Property::Index Actor::WORLD_SCALE = 26;
93 const Property::Index Actor::VISIBLE = 27;
94 const Property::Index Actor::COLOR = 28;
95 const Property::Index Actor::COLOR_RED = 29;
96 const Property::Index Actor::COLOR_GREEN = 30;
97 const Property::Index Actor::COLOR_BLUE = 31;
98 const Property::Index Actor::COLOR_ALPHA = 32;
99 const Property::Index Actor::WORLD_COLOR = 33;
100 const Property::Index Actor::WORLD_MATRIX = 34;
101 const Property::Index Actor::NAME = 35;
102 const Property::Index Actor::SENSITIVE = 36;
103 const Property::Index Actor::LEAVE_REQUIRED = 37;
104 const Property::Index Actor::INHERIT_ROTATION = 38;
105 const Property::Index Actor::INHERIT_SCALE = 39;
106 const Property::Index Actor::COLOR_MODE = 40;
107 const Property::Index Actor::POSITION_INHERITANCE = 41;
108 const Property::Index Actor::DRAW_MODE = 42;
110 namespace // unnamed namespace
114 * We want to discourage the use of property strings (minimize string comparisons),
115 * particularly for the default properties.
117 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
119 // Name Type writable animatable constraint-input
120 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
121 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
122 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
123 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
124 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
125 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
126 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
127 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
128 { "size", Property::VECTOR3, true, true, true }, // SIZE
129 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
130 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
131 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
132 { "position", Property::VECTOR3, true, true, true }, // POSITION
133 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
134 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
135 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
136 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
137 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
138 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
139 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
140 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
141 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
142 { "scale", Property::VECTOR3, true, true, true }, // SCALE
143 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
144 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
145 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
146 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
147 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
148 { "color", Property::VECTOR4, true, true, true }, // COLOR
149 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
150 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
151 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
152 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
153 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
154 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
155 { "name", Property::STRING, true, false, false }, // NAME
156 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
157 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
158 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
159 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
160 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
161 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
162 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
164 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
166 } // unnamed namespace
171 unsigned int Actor::mActorCounter = 0;
172 ActorContainer Actor::mNullChildren;
174 #ifdef DYNAMICS_SUPPORT
176 // Encapsulate actor related dynamics data
179 DynamicsData( Actor* slotOwner )
180 : slotDelegate( slotOwner )
184 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
185 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
187 DynamicsBodyPtr body;
188 JointContainer joints;
189 ReferencedJointContainer referencedJoints;
191 SlotDelegate< Actor > slotDelegate;
194 #endif // DYNAMICS_SUPPORT
199 using namespace Dali;
201 BaseHandle CreateActor()
203 return Dali::Actor::New();
206 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
208 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
209 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_HOVERED, &Actor::DoConnectSignal);
210 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
211 SignalConnectorType signalConnector5(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
213 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
214 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
218 ActorPtr Actor::New()
220 ActorPtr actor( new Actor( BASIC ) );
222 // Second-phase construction
228 const std::string& Actor::GetName() const
233 void Actor::SetName(const std::string& name)
239 // ATTENTION: string for debug purposes is not thread safe.
240 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
244 unsigned int Actor::GetId() const
249 void Actor::Attach( ActorAttachment& attachment )
251 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
255 attachment.Connect();
258 mAttachment = ActorAttachmentPtr(&attachment);
261 ActorAttachmentPtr Actor::GetAttachment()
266 bool Actor::OnStage() const
271 Dali::Layer Actor::GetLayer()
275 // Short-circuit for Layer derived actors
278 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
281 // Find the immediate Layer parent
282 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
284 if( parent->IsLayer() )
286 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
293 void Actor::Add(Actor& child)
295 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
296 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
300 mChildren = new ActorContainer;
303 Actor* const oldParent( child.mParent );
305 // child might already be ours
306 if( this != oldParent )
308 // if we already have parent, unparent us first
311 oldParent->Remove( child ); // This causes OnChildRemove callback
314 // Guard against Add() during previous OnChildRemove callback
315 if ( !child.mParent )
317 // Do this first, since user callbacks from within SetParent() may need to remove child
318 mChildren->push_back(Dali::Actor(&child));
320 // SetParent asserts that child can be added
321 child.SetParent(this);
323 // Notification for derived classes
329 void Actor::Insert(unsigned int index, Actor& child)
331 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
332 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
336 mChildren = new ActorContainer;
339 Actor* const oldParent( child.mParent );
341 // since an explicit position has been given, always insert, even if already a child
344 oldParent->Remove( child ); // This causes OnChildRemove callback
347 // Guard against Add() during previous OnChildRemove callback
348 if ( !child.mParent )
350 // Do this first, since user callbacks from within SetParent() may need to remove child
351 if (index < GetChildCount())
353 ActorIter it = mChildren->begin();
354 std::advance(it, index);
355 mChildren->insert(it, Dali::Actor(&child));
359 mChildren->push_back(Dali::Actor(&child));
361 // SetParent asserts that child can be added
362 child.SetParent(this, index);
364 // Notification for derived classes
369 void Actor::Remove(Actor& child)
371 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
381 // Find the child in mChildren, and unparent it
382 ActorIter end = mChildren->end();
383 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
385 Actor& actor = GetImplementation(*iter);
387 if( &actor == &child )
389 // Keep handle for OnChildRemove notification
390 removed = Dali::Actor( &actor );
392 // Do this first, since user callbacks from within SetParent() may need to add the child
393 mChildren->erase(iter);
395 DALI_ASSERT_DEBUG( actor.GetParent() == this );
396 actor.SetParent( NULL );
404 // Notification for derived classes
405 OnChildRemove( GetImplementation(removed) );
409 void Actor::Unparent()
413 mParent->Remove( *this );
417 unsigned int Actor::GetChildCount() const
419 return ( NULL != mChildren ) ? mChildren->size() : 0;
422 Dali::Actor Actor::GetChildAt(unsigned int index) const
424 DALI_ASSERT_ALWAYS( index < GetChildCount() );
426 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
429 ActorContainer Actor::GetChildren()
431 if( NULL != mChildren )
436 // return copy of mNullChildren
437 return mNullChildren;
440 const ActorContainer& Actor::GetChildren() const
442 if( NULL != mChildren )
447 // return const reference to mNullChildren
448 return mNullChildren;
451 ActorPtr Actor::FindChildByName(const std::string& actorName)
454 if (actorName == mName)
460 ActorIter end = mChildren->end();
461 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
463 child = GetImplementation(*iter).FindChildByName(actorName);
474 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
476 Dali::Actor child = DoGetChildByAlias(actorAlias);
478 // If not found then search by name.
481 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
484 child = Dali::Actor(child_ptr.Get());
491 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
493 Dali::Actor child = GetChildByAlias(actorAlias);
495 if (!child && mChildren )
497 ActorIter end = mChildren->end();
498 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
500 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
512 ActorPtr Actor::FindChildById(const unsigned int id)
521 ActorIter end = mChildren->end();
522 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
524 child = GetImplementation(*iter).FindChildById(id);
535 void Actor::SetParentOrigin( const Vector3& origin )
539 // mNode is being used in a separate thread; queue a message to set the value & base value
540 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
543 // Cache for event-thread access
546 // not allocated, check if different from default
547 if( ParentOrigin::DEFAULT != origin )
549 mParentOrigin = new Vector3( origin );
554 // check if different from current costs more than just set
555 *mParentOrigin = origin;
559 void Actor::SetParentOriginX( float x )
561 const Vector3& current = GetCurrentParentOrigin();
563 SetParentOrigin( Vector3( x, current.y, current.z ) );
566 void Actor::SetParentOriginY( float y )
568 const Vector3& current = GetCurrentParentOrigin();
570 SetParentOrigin( Vector3( current.x, y, current.z ) );
573 void Actor::SetParentOriginZ( float z )
575 const Vector3& current = GetCurrentParentOrigin();
577 SetParentOrigin( Vector3( current.x, current.y, z ) );
580 const Vector3& Actor::GetCurrentParentOrigin() const
582 // Cached for event-thread access
583 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
586 void Actor::SetAnchorPoint(const Vector3& anchor)
590 // mNode is being used in a separate thread; queue a message to set the value & base value
591 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
594 // Cache for event-thread access
597 // not allocated, check if different from default
598 if( AnchorPoint::DEFAULT != anchor )
600 mAnchorPoint = new Vector3( anchor );
605 // check if different from current costs more than just set
606 *mAnchorPoint = anchor;
610 void Actor::SetAnchorPointX( float x )
612 const Vector3& current = GetCurrentAnchorPoint();
614 SetAnchorPoint( Vector3( x, current.y, current.z ) );
617 void Actor::SetAnchorPointY( float y )
619 const Vector3& current = GetCurrentAnchorPoint();
621 SetAnchorPoint( Vector3( current.x, y, current.z ) );
624 void Actor::SetAnchorPointZ( float z )
626 const Vector3& current = GetCurrentAnchorPoint();
628 SetAnchorPoint( Vector3( current.x, current.y, z ) );
631 const Vector3& Actor::GetCurrentAnchorPoint() const
633 // Cached for event-thread access
634 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
637 void Actor::SetPosition(float x, float y)
639 SetPosition(Vector3(x, y, 0.0f));
642 void Actor::SetPosition(float x, float y, float z)
644 SetPosition(Vector3(x, y, z));
647 void Actor::SetPosition(const Vector3& position)
651 // mNode is being used in a separate thread; queue a message to set the value & base value
652 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
656 void Actor::SetX(float x)
660 // mNode is being used in a separate thread; queue a message to set the value & base value
661 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
665 void Actor::SetY(float y)
669 // mNode is being used in a separate thread; queue a message to set the value & base value
670 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
674 void Actor::SetZ(float z)
678 // mNode is being used in a separate thread; queue a message to set the value & base value
679 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
683 void Actor::MoveBy(const Vector3& distance)
687 // mNode is being used in a separate thread; queue a message to set the value & base value
688 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
692 const Vector3& Actor::GetCurrentPosition() const
696 // mNode is being used in a separate thread; copy the value from the previous update
697 return mNode->GetPosition(mStage->GetEventBufferIndex());
700 return Vector3::ZERO;
703 const Vector3& Actor::GetCurrentWorldPosition() const
707 // mNode is being used in a separate thread; copy the value from the previous update
708 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
711 return Vector3::ZERO;
714 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
716 // this flag is not animatable so keep the value
717 mPositionInheritanceMode = mode;
720 // mNode is being used in a separate thread; queue a message to set the value
721 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
725 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
727 // Cached for event-thread access
728 return mPositionInheritanceMode;
731 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
733 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
734 normalizedAxis.Normalize();
736 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
738 SetRotation(rotation);
741 void Actor::SetRotation(const Quaternion& rotation)
745 // mNode is being used in a separate thread; queue a message to set the value & base value
746 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
750 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
754 // mNode is being used in a separate thread; queue a message to set the value & base value
755 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
759 void Actor::RotateBy(const Quaternion& relativeRotation)
763 // mNode is being used in a separate thread; queue a message to set the value & base value
764 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
768 const Quaternion& Actor::GetCurrentRotation() const
772 // mNode is being used in a separate thread; copy the value from the previous update
773 return mNode->GetRotation(mStage->GetEventBufferIndex());
776 return Quaternion::IDENTITY;
779 const Quaternion& Actor::GetCurrentWorldRotation() const
783 // mNode is being used in a separate thread; copy the value from the previous update
784 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
787 return Quaternion::IDENTITY;
790 void Actor::SetScale(float scale)
792 SetScale(Vector3(scale, scale, scale));
795 void Actor::SetScale(float x, float y, float z)
797 SetScale(Vector3(x, y, z));
800 void Actor::SetScale(const Vector3& scale)
804 // mNode is being used in a separate thread; queue a message to set the value & base value
805 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
809 void Actor::SetScaleX( float x )
813 // mNode is being used in a separate thread; queue a message to set the value & base value
814 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
818 void Actor::SetScaleY( float y )
822 // mNode is being used in a separate thread; queue a message to set the value & base value
823 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
827 void Actor::SetScaleZ( float z )
831 // mNode is being used in a separate thread; queue a message to set the value & base value
832 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
836 void Actor::SetInitialVolume(const Vector3& volume)
840 // mNode is being used in a separate thread; queue a message to set the value
841 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
845 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
849 // mNode is being used in a separate thread; queue a message to set the value
850 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
854 bool Actor::GetTransmitGeometryScaling() const
858 // mNode is being used in a separate thread; copy the value from the previous update
859 return mNode->GetTransmitGeometryScaling();
865 void Actor::ScaleBy(const Vector3& relativeScale)
869 // mNode is being used in a separate thread; queue a message to set the value & base value
870 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
874 const Vector3& Actor::GetCurrentScale() const
878 // mNode is being used in a separate thread; copy the value from the previous update
879 return mNode->GetScale(mStage->GetEventBufferIndex());
885 const Vector3& Actor::GetCurrentWorldScale() const
889 // mNode is being used in a separate thread; copy the value from the previous update
890 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
896 void Actor::SetInheritScale( bool inherit )
898 // non animateable so keep local copy
899 mInheritScale = inherit;
902 // mNode is being used in a separate thread; queue a message to set the value
903 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
907 bool Actor::IsScaleInherited() const
909 return mInheritScale;
912 Matrix Actor::GetCurrentWorldMatrix() const
916 // World matrix is no longer updated unless there is something observing the node.
917 // Need to calculate it from node's world position, rotation and scale:
918 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
919 Matrix worldMatrix(false);
920 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
921 mNode->GetWorldRotation( updateBufferIndex ),
922 mNode->GetWorldPosition( updateBufferIndex ) );
926 return Matrix::IDENTITY;
929 void Actor::SetVisible(bool visible)
933 // mNode is being used in a separate thread; queue a message to set the value & base value
934 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
938 bool Actor::IsVisible() const
942 // mNode is being used in a separate thread; copy the value from the previous update
943 return mNode->IsVisible( mStage->GetEventBufferIndex() );
949 void Actor::SetOpacity(float opacity)
953 // mNode is being used in a separate thread; queue a message to set the value & base value
954 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
958 void Actor::OpacityBy(float relativeOpacity)
962 // mNode is being used in a separate thread; queue a message to set the value & base value
963 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
967 float Actor::GetCurrentOpacity() const
971 // mNode is being used in a separate thread; copy the value from the previous update
972 return mNode->GetOpacity(mStage->GetEventBufferIndex());
978 const Vector4& Actor::GetCurrentWorldColor() const
982 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
988 void Actor::SetColor(const Vector4& color)
992 // mNode is being used in a separate thread; queue a message to set the value & base value
993 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
997 void Actor::SetColorRed( float red )
1001 // mNode is being used in a separate thread; queue a message to set the value & base value
1002 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1006 void Actor::SetColorGreen( float green )
1010 // mNode is being used in a separate thread; queue a message to set the value & base value
1011 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1015 void Actor::SetColorBlue( float blue )
1019 // mNode is being used in a separate thread; queue a message to set the value & base value
1020 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1024 void Actor::ColorBy(const Vector4& relativeColor)
1028 // mNode is being used in a separate thread; queue a message to set the value & base value
1029 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1033 const Vector4& Actor::GetCurrentColor() const
1037 // mNode is being used in a separate thread; copy the value from the previous update
1038 return mNode->GetColor(mStage->GetEventBufferIndex());
1041 return Color::WHITE;
1044 void Actor::SetInheritRotation(bool inherit)
1046 // non animateable so keep local copy
1047 mInheritRotation = inherit;
1050 // mNode is being used in a separate thread; queue a message to set the value
1051 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1055 bool Actor::IsRotationInherited() const
1057 return mInheritRotation;
1060 void Actor::SetColorMode(ColorMode colorMode)
1062 // non animateable so keep local copy
1063 mColorMode = colorMode;
1066 // mNode is being used in a separate thread; queue a message to set the value
1067 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1071 ColorMode Actor::GetColorMode() const
1073 // we have cached copy
1077 void Actor::SetSize(float width, float height)
1079 SetSize( Vector2( width, height ) );
1082 void Actor::SetSize(float width, float height, float depth)
1084 SetSize( Vector3( width, height, depth ) );
1087 void Actor::SetSize(const Vector2& size)
1089 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1092 float Actor::CalculateSizeZ( const Vector2& size ) const
1094 return std::min( size.width, size.height );
1097 void Actor::SetSize(const Vector3& size)
1103 // mNode is being used in a separate thread; queue a message to set the value & base value
1104 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1106 // Notification for derived classes
1111 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1115 // Notify deriving classes
1116 OnSizeAnimation( animation, targetSize );
1119 void Actor::SetWidth( float width )
1123 // mNode is being used in a separate thread; queue a message to set the value & base value
1124 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1128 void Actor::SetHeight( float height )
1132 // mNode is being used in a separate thread; queue a message to set the value & base value
1133 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1137 void Actor::SetDepth( float depth )
1141 // mNode is being used in a separate thread; queue a message to set the value & base value
1142 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1146 const Vector3& Actor::GetSize() const
1151 const Vector3& Actor::GetCurrentSize() const
1155 // mNode is being used in a separate thread; copy the value from the previous update
1156 return mNode->GetSize( mStage->GetEventBufferIndex() );
1159 return Vector3::ZERO;
1162 Vector3 Actor::GetNaturalSize() const
1164 // It is up to deriving classes to return the appropriate natural size
1165 return Vector3( 0.0f, 0.0f, 0.0f );
1169 #ifdef DYNAMICS_SUPPORT
1171 //--------------- Dynamics ---------------
1173 void Actor::DisableDynamics()
1175 if( NULL != mDynamicsData )
1177 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1179 // ensure dynamics object are disconnected from scene
1180 DisconnectDynamics();
1182 // delete joint owned by this actor
1183 while( !mDynamicsData->joints.empty() )
1185 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1188 // delete other joints referencing this actor
1189 while( !mDynamicsData->referencedJoints.empty() )
1191 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1192 ActorPtr jointOwner( joint->GetActor( true ) );
1195 jointOwner->RemoveDynamicsJoint( joint );
1199 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1202 // delete the DynamicsBody object
1203 mDynamicsData->body.Reset();
1205 // Discard Dynamics data structure
1206 delete mDynamicsData;
1207 mDynamicsData = NULL;
1211 DynamicsBodyPtr Actor::GetDynamicsBody() const
1213 DynamicsBodyPtr body;
1215 if( NULL != mDynamicsData )
1217 body = mDynamicsData->body;
1223 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1225 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1227 if( NULL == mDynamicsData )
1229 mDynamicsData = new DynamicsData( this );
1232 if( !mDynamicsData->body )
1234 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1238 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1241 if( mParent == world->GetRootActor().Get() )
1243 mDynamicsData->body->Connect(*mStage);
1249 return mDynamicsData->body;
1252 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1254 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1255 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1258 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1260 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1261 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1263 DynamicsJointPtr joint;
1265 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1269 if( NULL != mDynamicsData )
1271 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1273 if( mDynamicsData->joints.end() != it )
1275 // use existing joint
1281 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1282 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1286 bodyA = EnableDynamics( new DynamicsBodyConfig );
1291 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1294 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1295 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1297 if( OnStage() && attachedActor->OnStage() )
1299 joint->Connect(*mStage);
1302 attachedActor->ReferenceJoint( joint );
1304 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1305 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1312 const int Actor::GetNumberOfJoints() const
1314 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1317 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1319 DynamicsJointPtr joint;
1321 if( NULL != mDynamicsData )
1323 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1325 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1327 for( int i = 0; i < index; ++i )
1339 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1341 DynamicsJointPtr joint;
1343 if( NULL != mDynamicsData )
1345 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1347 if( mDynamicsData->joints.end() != it )
1349 // use existing joint
1357 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1359 if( NULL != mDynamicsData )
1361 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1362 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1364 for( ; it != endIt; ++it )
1366 if( it->second == joint.Get() )
1368 ActorPtr attachedActor( it->first );
1370 if( OnStage() && attachedActor && attachedActor->OnStage() )
1372 joint->Disconnect(*mStage);
1377 attachedActor->ReleaseJoint( joint );
1378 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1379 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1382 mDynamicsData->joints.erase(it);
1389 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1391 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1393 if( NULL != mDynamicsData )
1395 mDynamicsData->referencedJoints.push_back(joint);
1399 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1401 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1403 if( NULL != mDynamicsData )
1405 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1407 if( it != mDynamicsData->referencedJoints.end() )
1409 mDynamicsData->referencedJoints.erase( it );
1414 void Actor::SetDynamicsRoot(bool flag)
1416 if( mIsDynamicsRoot != flag )
1418 mIsDynamicsRoot = flag;
1420 if( OnStage() && mChildren )
1422 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1423 ActorIter end = mChildren->end();
1424 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1426 Actor& child = GetImplementation(*iter);
1428 if( child.GetDynamicsBody() )
1430 if( mIsDynamicsRoot )
1432 child.ConnectDynamics();
1436 child.DisconnectDynamics();
1444 bool Actor::IsDynamicsRoot() const
1446 return mIsDynamicsRoot;
1449 void Actor::AttachedActorOnStage( Dali::Actor actor )
1451 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1455 ActorPtr attachedActor( &GetImplementation(actor) );
1457 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1458 if( NULL != mDynamicsData )
1460 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1461 if( mDynamicsData->joints.end() != it )
1463 DynamicsJointPtr joint( it->second );
1464 joint->Connect(*mStage);
1470 void Actor::AttachedActorOffStage( Dali::Actor actor )
1472 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1476 ActorPtr attachedActor( &GetImplementation(actor) );
1478 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1479 if( NULL != mDynamicsData )
1481 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1482 if( mDynamicsData->joints.end() != it )
1484 DynamicsJointPtr joint( it->second );
1485 joint->Disconnect(*mStage);
1491 void Actor::ConnectDynamics()
1493 if( NULL != mDynamicsData && mDynamicsData->body )
1495 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1497 mDynamicsData->body->Connect(*mStage);
1499 // Connect all joints where attachedActor is also on stage
1500 if( !mDynamicsData->joints.empty() )
1502 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1503 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1505 for( ; it != endIt; ++it )
1507 Actor* attachedActor( it->first );
1508 if( NULL != attachedActor && attachedActor->OnStage() )
1510 DynamicsJointPtr joint( it->second );
1512 joint->Connect(*mStage);
1520 void Actor::DisconnectDynamics()
1522 if( NULL != mDynamicsData && mDynamicsData->body )
1526 mDynamicsData->body->Disconnect(*mStage);
1528 // Disconnect all joints
1529 if( !mDynamicsData->joints.empty() )
1531 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1532 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1534 for( ; it != endIt; ++it )
1536 DynamicsJointPtr joint( it->second );
1538 joint->Disconnect(*mStage);
1545 #endif // DYNAMICS_SUPPORT
1547 void Actor::SetOverlay(bool enable)
1549 // Setting STENCIL will override OVERLAY
1550 if( DrawMode::STENCIL != mDrawMode )
1552 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1556 bool Actor::IsOverlay() const
1558 return ( DrawMode::OVERLAY == mDrawMode );
1561 void Actor::SetDrawMode( DrawMode::Type drawMode )
1563 // this flag is not animatable so keep the value
1564 mDrawMode = drawMode;
1567 // mNode is being used in a separate thread; queue a message to set the value
1568 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1572 DrawMode::Type Actor::GetDrawMode() const
1577 bool Actor::ScreenToLocal( float& localX,
1580 float screenY ) const
1582 // only valid when on-stage
1585 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1587 Vector2 converted( screenX, screenY );
1589 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1590 const int taskCount = taskList.GetTaskCount();
1591 for( int i = taskCount - 1; i >= 0; --i )
1593 Dali::RenderTask task = taskList.GetTask( i );
1594 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1596 // found a task where this conversion was ok so return
1604 bool Actor::ScreenToLocal( RenderTask& renderTask,
1608 float screenY ) const
1610 bool retval = false;
1611 // only valid when on-stage
1614 CameraActor* camera = renderTask.GetCameraActor();
1618 renderTask.GetViewport( viewport );
1620 // need to translate coordinates to render tasks coordinate space
1621 Vector2 converted( screenX, screenY );
1622 if( renderTask.TranslateCoordinates( converted ) )
1624 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1631 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1632 const Matrix& projectionMatrix,
1633 const Viewport& viewport,
1637 float screenY ) const
1639 // Early-out if mNode is NULL
1645 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1647 // Calculate the ModelView matrix
1648 Matrix modelView(false/*don't init*/);
1649 // need to use the components as world matrix is only updated for actors that need it
1650 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1651 Matrix::Multiply(modelView, modelView, viewMatrix);
1653 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1654 Matrix invertedMvp(false/*don't init*/);
1655 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1656 bool success = invertedMvp.Invert();
1658 // Convert to GL coordinates
1659 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1664 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1671 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1677 if (XyPlaneIntersect(nearPos, farPos, local))
1679 Vector3 size = GetCurrentSize();
1680 localX = local.x + size.x * 0.5f;
1681 localY = local.y + size.y * 0.5f;
1692 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1695 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1697 Mathematical Formulation
1699 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1701 ( p - c ) dot ( p - c ) = r^2
1703 Given a ray with a point of origin 'o', and a direction vector 'd':
1705 ray(t) = o + td, t >= 0
1707 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1709 (o + td - c ) dot ( o + td - c ) = r^2
1711 To solve for t we first expand the above into a more recognisable quadratic equation form
1713 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1722 B = 2( o - c ) dot d
1723 C = ( o - c ) dot ( o - c ) - r^2
1725 which can be solved using a standard quadratic formula.
1727 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1729 Practical Simplification
1731 In a renderer, we often differentiate between world space and object space. In the object space
1732 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1733 into object space, the mathematical solution presented above can be simplified significantly.
1735 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1739 and we can find the t at which the (transformed) ray intersects the sphere by
1741 ( o + td ) dot ( o + td ) = r^2
1743 According to the reasoning above, we expand the above quadratic equation into the general form
1747 which now has coefficients:
1754 // Early out if mNode is NULL
1760 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1762 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1763 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1764 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1765 rayOrigin.y - translation.y,
1766 rayOrigin.z - translation.z);
1768 // Compute the radius is not needed, square radius it's enough.
1769 const Vector3& size( mNode->GetSize( bufferIndex ) );
1771 // Scale the sphere.
1772 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1774 const float width = size.width * scale.width;
1775 const float height = size.height * scale.height;
1777 float squareSphereRadius = 0.5f * ( width * width + height * height );
1779 float a = rayDir.Dot( rayDir ); // a
1780 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1781 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1783 return ( b2*b2 - a*c ) >= 0.f;
1786 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1793 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1795 // Transforms the ray to the local reference system.
1797 // Calculate the inverse of Model matrix
1798 Matrix invModelMatrix(false/*don't init*/);
1799 // need to use the components as world matrix is only updated for actors that need it
1800 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1802 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1803 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1805 // Test with the actor's XY plane (Normal = 0 0 1 1).
1807 float a = -rayOriginLocal.z;
1808 float b = rayDirLocal.z;
1810 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1812 // Ray travels distance * rayDirLocal to intersect with plane.
1815 const Vector3& size = mNode->GetSize( bufferIndex );
1817 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1818 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1820 // Test with the actor's geometry.
1821 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1828 void Actor::SetLeaveRequired(bool required)
1830 mLeaveRequired = required;
1833 bool Actor::GetLeaveRequired() const
1835 return mLeaveRequired;
1838 void Actor::SetKeyboardFocusable( bool focusable )
1840 mKeyboardFocusable = focusable;
1843 bool Actor::IsKeyboardFocusable() const
1845 return mKeyboardFocusable;
1848 bool Actor::GetTouchRequired() const
1850 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1853 bool Actor::GetHoverRequired() const
1855 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1858 bool Actor::GetMouseWheelEventRequired() const
1860 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1863 bool Actor::IsHittable() const
1865 return IsSensitive() &&
1867 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1871 ActorGestureData& Actor::GetGestureData()
1873 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1874 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1875 if ( NULL == mGestureData )
1877 mGestureData = new ActorGestureData;
1879 return *mGestureData;
1882 bool Actor::IsGestureRequred( Gesture::Type type ) const
1884 return mGestureData && mGestureData->IsGestureRequred( type );
1887 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1889 bool consumed = false;
1891 if ( !mTouchedSignal.Empty() )
1893 Dali::Actor handle( this );
1894 consumed = mTouchedSignal.Emit( handle, event );
1899 // Notification for derived classes
1900 consumed = OnTouchEvent( event );
1906 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1908 bool consumed = false;
1910 if ( !mHoveredSignal.Empty() )
1912 Dali::Actor handle( this );
1913 consumed = mHoveredSignal.Emit( handle, event );
1918 // Notification for derived classes
1919 consumed = OnHoverEvent( event );
1925 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1927 bool consumed = false;
1929 if ( !mMouseWheelEventSignal.Empty() )
1931 Dali::Actor handle( this );
1932 consumed = mMouseWheelEventSignal.Emit( handle, event );
1937 // Notification for derived classes
1938 consumed = OnMouseWheelEvent(event);
1944 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1946 return mTouchedSignal;
1949 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1951 return mHoveredSignal;
1954 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1956 return mMouseWheelEventSignal;
1959 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1961 return mOnStageSignal;
1964 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1966 return mOffStageSignal;
1969 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1971 bool connected( true );
1972 Actor* actor = dynamic_cast<Actor*>(object);
1974 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1976 actor->TouchedSignal().Connect( tracker, functor );
1978 else if(Dali::Actor::SIGNAL_HOVERED == signalName)
1980 actor->HoveredSignal().Connect( tracker, functor );
1982 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1984 actor->MouseWheelEventSignal().Connect( tracker, functor );
1986 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1988 actor->OnStageSignal().Connect( tracker, functor );
1990 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1992 actor->OffStageSignal().Connect( tracker, functor );
1996 // signalName does not match any signal
2003 Actor::Actor( DerivedType derivedType )
2008 mParentOrigin( NULL ),
2009 mAnchorPoint( NULL ),
2010 #ifdef DYNAMICS_SUPPORT
2011 mDynamicsData( NULL ),
2013 mGestureData( NULL ),
2015 mSize( 0.0f, 0.0f, 0.0f ),
2017 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2018 mIsRoot( ROOT_LAYER == derivedType ),
2019 mIsRenderable( RENDERABLE == derivedType ),
2020 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2021 mIsOnStage( false ),
2022 mIsDynamicsRoot(false),
2024 mLeaveRequired( false ),
2025 mKeyboardFocusable( false ),
2026 mDerivedRequiresTouch( false ),
2027 mDerivedRequiresHover( false ),
2028 mDerivedRequiresMouseWheelEvent( false ),
2029 mOnStageSignalled( false ),
2030 mInheritRotation( true ),
2031 mInheritScale( true ),
2032 mDrawMode( DrawMode::NORMAL ),
2033 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2034 mColorMode( Node::DEFAULT_COLOR_MODE )
2038 void Actor::Initialize()
2040 mStage = Stage::GetCurrent();
2043 SceneGraph::Node* node = CreateNode();
2045 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2046 mNode = node; // Keep raw-pointer to Node
2055 // Remove mParent pointers from children even if we're destroying core,
2056 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2059 ActorConstIter endIter = mChildren->end();
2060 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2062 Actor& actor = GetImplementation( *iter );
2063 actor.SetParent( NULL );
2068 // Guard to allow handle destruction after Core has been destroyed
2069 if( Stage::IsInstalled() )
2073 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2074 mNode = NULL; // Node is about to be destroyed
2080 #ifdef DYNAMICS_SUPPORT
2082 delete mDynamicsData;
2085 // Cleanup optional gesture data
2086 delete mGestureData;
2088 // Cleanup optional parent origin and anchor
2089 delete mParentOrigin;
2090 delete mAnchorPoint;
2093 void Actor::ConnectToStage( int index )
2095 // This container is used instead of walking the Actor hierachy.
2096 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2097 ActorContainer connectionList;
2099 // This stage is atomic i.e. not interrupted by user callbacks
2100 RecursiveConnectToStage( connectionList, index );
2102 // Notify applications about the newly connected actors.
2103 const ActorIter endIter = connectionList.end();
2104 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2106 Actor& actor = GetImplementation(*iter);
2107 actor.NotifyStageConnection();
2111 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2113 DALI_ASSERT_ALWAYS( !OnStage() );
2117 ConnectToSceneGraph(index);
2119 // Notification for internal derived classes
2120 OnStageConnectionInternal();
2122 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2123 connectionList.push_back( Dali::Actor(this) );
2125 // Recursively connect children
2128 ActorConstIter endIter = mChildren->end();
2129 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2131 Actor& actor = GetImplementation( *iter );
2132 actor.RecursiveConnectToStage( connectionList );
2138 * This method is called when the Actor is connected to the Stage.
2139 * The parent must have added its Node to the scene-graph.
2140 * The child must connect its Node to the parent's Node.
2141 * This is resursive; the child calls ConnectToStage() for its children.
2143 void Actor::ConnectToSceneGraph(int index)
2145 DALI_ASSERT_DEBUG( mNode != NULL);
2146 DALI_ASSERT_DEBUG( mParent != NULL);
2147 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2151 // Reparent Node in next Update
2152 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2155 // Notify attachment
2158 mAttachment->Connect();
2161 #ifdef DYNAMICS_SUPPORT
2163 if( NULL != mDynamicsData )
2169 // Notification for ProxyObject::Observers
2173 void Actor::NotifyStageConnection()
2175 // Actors can be removed (in a callback), before the on-stage stage is reported.
2176 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2177 if ( OnStage() && !mOnStageSignalled )
2179 // Notification for external (CustomActor) derived classes
2180 OnStageConnectionExternal();
2182 if ( !mOnStageSignal.Empty() )
2184 Dali::Actor handle( this );
2185 mOnStageSignal.Emit( handle );
2188 // Guard against Remove during callbacks
2191 mOnStageSignalled = true; // signal required next time Actor is removed
2196 void Actor::DisconnectFromStage()
2198 // This container is used instead of walking the Actor hierachy.
2199 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2200 ActorContainer disconnectionList;
2202 // This stage is atomic i.e. not interrupted by user callbacks
2203 RecursiveDisconnectFromStage( disconnectionList );
2205 // Notify applications about the newly disconnected actors.
2206 const ActorIter endIter = disconnectionList.end();
2207 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2209 Actor& actor = GetImplementation(*iter);
2210 actor.NotifyStageDisconnection();
2214 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2216 DALI_ASSERT_ALWAYS( OnStage() );
2218 // Recursively disconnect children
2221 ActorConstIter endIter = mChildren->end();
2222 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2224 Actor& actor = GetImplementation( *iter );
2225 actor.RecursiveDisconnectFromStage( disconnectionList );
2229 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2230 disconnectionList.push_back( Dali::Actor(this) );
2232 // Notification for internal derived classes
2233 OnStageDisconnectionInternal();
2235 DisconnectFromSceneGraph();
2241 * This method is called by an actor or its parent, before a node removal message is sent.
2242 * This is recursive; the child calls DisconnectFromStage() for its children.
2244 void Actor::DisconnectFromSceneGraph()
2246 // Notification for ProxyObject::Observers
2247 OnSceneObjectRemove();
2249 // Notify attachment
2252 mAttachment->Disconnect();
2255 #ifdef DYNAMICS_SUPPORT
2257 if( NULL != mDynamicsData )
2259 DisconnectDynamics();
2264 void Actor::NotifyStageDisconnection()
2266 // Actors can be added (in a callback), before the off-stage state is reported.
2267 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2268 // only do this step if there is a stage, i.e. Core is not being shut down
2269 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2271 // Notification for external (CustomeActor) derived classes
2272 OnStageDisconnectionExternal();
2274 if( !mOffStageSignal.Empty() )
2276 Dali::Actor handle( this );
2277 mOffStageSignal.Emit( handle );
2280 // Guard against Add during callbacks
2283 mOnStageSignalled = false; // signal required next time Actor is added
2288 bool Actor::IsNodeConnected() const
2290 bool connected( false );
2295 if( mNode->IsRoot() || mNode->GetParent() )
2304 unsigned int Actor::GetDefaultPropertyCount() const
2306 return DEFAULT_PROPERTY_COUNT;
2309 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2311 indices.reserve( DEFAULT_PROPERTY_COUNT );
2313 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2315 indices.push_back( i );
2319 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2321 if( index < DEFAULT_PROPERTY_COUNT )
2323 return DEFAULT_PROPERTY_DETAILS[index].name;
2331 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2333 Property::Index index = Property::INVALID_INDEX;
2335 // Look for name in default properties
2336 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2338 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2339 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2349 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2351 if( index < DEFAULT_PROPERTY_COUNT )
2353 return DEFAULT_PROPERTY_DETAILS[index].writable;
2361 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2363 if( index < DEFAULT_PROPERTY_COUNT )
2365 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2373 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2375 if( index < DEFAULT_PROPERTY_COUNT )
2377 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2385 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2387 if( index < DEFAULT_PROPERTY_COUNT )
2389 return DEFAULT_PROPERTY_DETAILS[index].type;
2393 // index out of range...return Property::NONE
2394 return Property::NONE;
2398 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2402 case Dali::Actor::PARENT_ORIGIN:
2404 SetParentOrigin( property.Get<Vector3>() );
2408 case Dali::Actor::PARENT_ORIGIN_X:
2410 SetParentOriginX( property.Get<float>() );
2414 case Dali::Actor::PARENT_ORIGIN_Y:
2416 SetParentOriginY( property.Get<float>() );
2420 case Dali::Actor::PARENT_ORIGIN_Z:
2422 SetParentOriginZ( property.Get<float>() );
2426 case Dali::Actor::ANCHOR_POINT:
2428 SetAnchorPoint( property.Get<Vector3>() );
2432 case Dali::Actor::ANCHOR_POINT_X:
2434 SetAnchorPointX( property.Get<float>() );
2438 case Dali::Actor::ANCHOR_POINT_Y:
2440 SetAnchorPointY( property.Get<float>() );
2444 case Dali::Actor::ANCHOR_POINT_Z:
2446 SetAnchorPointZ( property.Get<float>() );
2450 case Dali::Actor::SIZE:
2452 SetSize( property.Get<Vector3>() );
2456 case Dali::Actor::SIZE_WIDTH:
2458 SetWidth( property.Get<float>() );
2462 case Dali::Actor::SIZE_HEIGHT:
2464 SetHeight( property.Get<float>() );
2468 case Dali::Actor::SIZE_DEPTH:
2470 SetDepth( property.Get<float>() );
2474 case Dali::Actor::POSITION:
2476 SetPosition( property.Get<Vector3>() );
2480 case Dali::Actor::POSITION_X:
2482 SetX( property.Get<float>() );
2486 case Dali::Actor::POSITION_Y:
2488 SetY( property.Get<float>() );
2492 case Dali::Actor::POSITION_Z:
2494 SetZ( property.Get<float>() );
2498 case Dali::Actor::ROTATION:
2500 SetRotation( property.Get<Quaternion>() );
2504 case Dali::Actor::SCALE:
2506 SetScale( property.Get<Vector3>() );
2510 case Dali::Actor::SCALE_X:
2512 SetScaleX( property.Get<float>() );
2516 case Dali::Actor::SCALE_Y:
2518 SetScaleY( property.Get<float>() );
2522 case Dali::Actor::SCALE_Z:
2524 SetScaleZ( property.Get<float>() );
2528 case Dali::Actor::VISIBLE:
2530 SetVisible( property.Get<bool>() );
2534 case Dali::Actor::COLOR:
2536 SetColor( property.Get<Vector4>() );
2540 case Dali::Actor::COLOR_RED:
2542 SetColorRed( property.Get<float>() );
2546 case Dali::Actor::COLOR_GREEN:
2548 SetColorGreen( property.Get<float>() );
2552 case Dali::Actor::COLOR_BLUE:
2554 SetColorBlue( property.Get<float>() );
2558 case Dali::Actor::COLOR_ALPHA:
2560 SetOpacity( property.Get<float>() );
2564 case Dali::Actor::NAME:
2566 SetName( property.Get<std::string>() );
2570 case Dali::Actor::SENSITIVE:
2572 SetSensitive( property.Get<bool>() );
2576 case Dali::Actor::LEAVE_REQUIRED:
2578 SetLeaveRequired( property.Get<bool>() );
2582 case Dali::Actor::INHERIT_ROTATION:
2584 SetInheritRotation( property.Get<bool>() );
2588 case Dali::Actor::INHERIT_SCALE:
2590 SetInheritScale( property.Get<bool>() );
2594 case Dali::Actor::COLOR_MODE:
2596 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2600 case Dali::Actor::POSITION_INHERITANCE:
2602 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2606 case Dali::Actor::DRAW_MODE:
2608 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2614 // this can happen in the case of a non-animatable default property so just do nothing
2620 // TODO: This method needs to be removed
2621 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2623 OnPropertySet(index, value);
2625 switch ( entry.type )
2627 case Property::BOOLEAN:
2629 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2630 DALI_ASSERT_DEBUG( NULL != property );
2632 // property is being used in a separate thread; queue a message to set the property
2633 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2638 case Property::FLOAT:
2640 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2641 DALI_ASSERT_DEBUG( NULL != property );
2643 // property is being used in a separate thread; queue a message to set the property
2644 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2649 case Property::INTEGER:
2651 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2652 DALI_ASSERT_DEBUG( NULL != property );
2654 // property is being used in a separate thread; queue a message to set the property
2655 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2660 case Property::VECTOR2:
2662 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2663 DALI_ASSERT_DEBUG( NULL != property );
2665 // property is being used in a separate thread; queue a message to set the property
2666 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2671 case Property::VECTOR3:
2673 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2674 DALI_ASSERT_DEBUG( NULL != property );
2676 // property is being used in a separate thread; queue a message to set the property
2677 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2682 case Property::VECTOR4:
2684 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2685 DALI_ASSERT_DEBUG( NULL != property );
2687 // property is being used in a separate thread; queue a message to set the property
2688 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2693 case Property::ROTATION:
2695 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2696 DALI_ASSERT_DEBUG( NULL != property );
2698 // property is being used in a separate thread; queue a message to set the property
2699 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2704 case Property::MATRIX:
2706 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2707 DALI_ASSERT_DEBUG( NULL != property );
2709 // property is being used in a separate thread; queue a message to set the property
2710 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2715 case Property::MATRIX3:
2717 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2718 DALI_ASSERT_DEBUG( NULL != property );
2720 // property is being used in a separate thread; queue a message to set the property
2721 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2728 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2734 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2736 Property::Value value;
2740 case Dali::Actor::PARENT_ORIGIN:
2742 value = GetCurrentParentOrigin();
2746 case Dali::Actor::PARENT_ORIGIN_X:
2748 value = GetCurrentParentOrigin().x;
2752 case Dali::Actor::PARENT_ORIGIN_Y:
2754 value = GetCurrentParentOrigin().y;
2758 case Dali::Actor::PARENT_ORIGIN_Z:
2760 value = GetCurrentParentOrigin().z;
2764 case Dali::Actor::ANCHOR_POINT:
2766 value = GetCurrentAnchorPoint();
2770 case Dali::Actor::ANCHOR_POINT_X:
2772 value = GetCurrentAnchorPoint().x;
2776 case Dali::Actor::ANCHOR_POINT_Y:
2778 value = GetCurrentAnchorPoint().y;
2782 case Dali::Actor::ANCHOR_POINT_Z:
2784 value = GetCurrentAnchorPoint().z;
2788 case Dali::Actor::SIZE:
2790 value = GetCurrentSize();
2794 case Dali::Actor::SIZE_WIDTH:
2796 value = GetCurrentSize().width;
2800 case Dali::Actor::SIZE_HEIGHT:
2802 value = GetCurrentSize().height;
2806 case Dali::Actor::SIZE_DEPTH:
2808 value = GetCurrentSize().depth;
2812 case Dali::Actor::POSITION:
2814 value = GetCurrentPosition();
2818 case Dali::Actor::POSITION_X:
2820 value = GetCurrentPosition().x;
2824 case Dali::Actor::POSITION_Y:
2826 value = GetCurrentPosition().y;
2830 case Dali::Actor::POSITION_Z:
2832 value = GetCurrentPosition().z;
2836 case Dali::Actor::WORLD_POSITION:
2838 value = GetCurrentWorldPosition();
2842 case Dali::Actor::WORLD_POSITION_X:
2844 value = GetCurrentWorldPosition().x;
2848 case Dali::Actor::WORLD_POSITION_Y:
2850 value = GetCurrentWorldPosition().y;
2854 case Dali::Actor::WORLD_POSITION_Z:
2856 value = GetCurrentWorldPosition().z;
2860 case Dali::Actor::ROTATION:
2862 value = GetCurrentRotation();
2866 case Dali::Actor::WORLD_ROTATION:
2868 value = GetCurrentWorldRotation();
2872 case Dali::Actor::SCALE:
2874 value = GetCurrentScale();
2878 case Dali::Actor::SCALE_X:
2880 value = GetCurrentScale().x;
2884 case Dali::Actor::SCALE_Y:
2886 value = GetCurrentScale().y;
2890 case Dali::Actor::SCALE_Z:
2892 value = GetCurrentScale().z;
2896 case Dali::Actor::WORLD_SCALE:
2898 value = GetCurrentWorldScale();
2902 case Dali::Actor::VISIBLE:
2904 value = IsVisible();
2908 case Dali::Actor::COLOR:
2910 value = GetCurrentColor();
2914 case Dali::Actor::COLOR_RED:
2916 value = GetCurrentColor().r;
2920 case Dali::Actor::COLOR_GREEN:
2922 value = GetCurrentColor().g;
2926 case Dali::Actor::COLOR_BLUE:
2928 value = GetCurrentColor().b;
2932 case Dali::Actor::COLOR_ALPHA:
2934 value = GetCurrentColor().a;
2938 case Dali::Actor::WORLD_COLOR:
2940 value = GetCurrentWorldColor();
2944 case Dali::Actor::WORLD_MATRIX:
2946 value = GetCurrentWorldMatrix();
2950 case Dali::Actor::NAME:
2956 case Dali::Actor::SENSITIVE:
2958 value = IsSensitive();
2962 case Dali::Actor::LEAVE_REQUIRED:
2964 value = GetLeaveRequired();
2968 case Dali::Actor::INHERIT_ROTATION:
2970 value = IsRotationInherited();
2974 case Dali::Actor::INHERIT_SCALE:
2976 value = IsScaleInherited();
2980 case Dali::Actor::COLOR_MODE:
2982 value = Scripting::GetColorMode( GetColorMode() );
2986 case Dali::Actor::POSITION_INHERITANCE:
2988 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2992 case Dali::Actor::DRAW_MODE:
2994 value = Scripting::GetDrawMode( GetDrawMode() );
3000 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3008 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3013 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3015 // This method should only return an object connected to the scene-graph
3016 return OnStage() ? mNode : NULL;
3019 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3021 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3023 const PropertyBase* property( NULL );
3025 // This method should only return a property of an object connected to the scene-graph
3031 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3033 CustomProperty* custom = FindCustomProperty( index );
3034 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3036 property = custom->GetSceneGraphProperty();
3038 else if( NULL != mNode )
3042 case Dali::Actor::SIZE:
3043 property = &mNode->mSize;
3046 case Dali::Actor::SIZE_WIDTH:
3047 property = &mNode->mSize;
3050 case Dali::Actor::SIZE_HEIGHT:
3051 property = &mNode->mSize;
3054 case Dali::Actor::SIZE_DEPTH:
3055 property = &mNode->mSize;
3058 case Dali::Actor::POSITION:
3059 property = &mNode->mPosition;
3062 case Dali::Actor::POSITION_X:
3063 property = &mNode->mPosition;
3066 case Dali::Actor::POSITION_Y:
3067 property = &mNode->mPosition;
3070 case Dali::Actor::POSITION_Z:
3071 property = &mNode->mPosition;
3074 case Dali::Actor::ROTATION:
3075 property = &mNode->mRotation;
3078 case Dali::Actor::SCALE:
3079 property = &mNode->mScale;
3082 case Dali::Actor::SCALE_X:
3083 property = &mNode->mScale;
3086 case Dali::Actor::SCALE_Y:
3087 property = &mNode->mScale;
3090 case Dali::Actor::SCALE_Z:
3091 property = &mNode->mScale;
3094 case Dali::Actor::VISIBLE:
3095 property = &mNode->mVisible;
3098 case Dali::Actor::COLOR:
3099 property = &mNode->mColor;
3102 case Dali::Actor::COLOR_RED:
3103 property = &mNode->mColor;
3106 case Dali::Actor::COLOR_GREEN:
3107 property = &mNode->mColor;
3110 case Dali::Actor::COLOR_BLUE:
3111 property = &mNode->mColor;
3114 case Dali::Actor::COLOR_ALPHA:
3115 property = &mNode->mColor;
3126 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3128 const PropertyInputImpl* property( NULL );
3130 // This method should only return a property of an object connected to the scene-graph
3136 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3138 CustomProperty* custom = FindCustomProperty( index );
3139 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3140 property = custom->GetSceneGraphProperty();
3142 else if( NULL != mNode )
3146 case Dali::Actor::PARENT_ORIGIN:
3147 property = &mNode->mParentOrigin;
3150 case Dali::Actor::PARENT_ORIGIN_X:
3151 property = &mNode->mParentOrigin;
3154 case Dali::Actor::PARENT_ORIGIN_Y:
3155 property = &mNode->mParentOrigin;
3158 case Dali::Actor::PARENT_ORIGIN_Z:
3159 property = &mNode->mParentOrigin;
3162 case Dali::Actor::ANCHOR_POINT:
3163 property = &mNode->mAnchorPoint;
3166 case Dali::Actor::ANCHOR_POINT_X:
3167 property = &mNode->mAnchorPoint;
3170 case Dali::Actor::ANCHOR_POINT_Y:
3171 property = &mNode->mAnchorPoint;
3174 case Dali::Actor::ANCHOR_POINT_Z:
3175 property = &mNode->mAnchorPoint;
3178 case Dali::Actor::SIZE:
3179 property = &mNode->mSize;
3182 case Dali::Actor::SIZE_WIDTH:
3183 property = &mNode->mSize;
3186 case Dali::Actor::SIZE_HEIGHT:
3187 property = &mNode->mSize;
3190 case Dali::Actor::SIZE_DEPTH:
3191 property = &mNode->mSize;
3194 case Dali::Actor::POSITION:
3195 property = &mNode->mPosition;
3198 case Dali::Actor::POSITION_X:
3199 property = &mNode->mPosition;
3202 case Dali::Actor::POSITION_Y:
3203 property = &mNode->mPosition;
3206 case Dali::Actor::POSITION_Z:
3207 property = &mNode->mPosition;
3210 case Dali::Actor::WORLD_POSITION:
3211 property = &mNode->mWorldPosition;
3214 case Dali::Actor::WORLD_POSITION_X:
3215 property = &mNode->mWorldPosition;
3218 case Dali::Actor::WORLD_POSITION_Y:
3219 property = &mNode->mWorldPosition;
3222 case Dali::Actor::WORLD_POSITION_Z:
3223 property = &mNode->mWorldPosition;
3226 case Dali::Actor::ROTATION:
3227 property = &mNode->mRotation;
3230 case Dali::Actor::WORLD_ROTATION:
3231 property = &mNode->mWorldRotation;
3234 case Dali::Actor::SCALE:
3235 property = &mNode->mScale;
3238 case Dali::Actor::SCALE_X:
3239 property = &mNode->mScale;
3242 case Dali::Actor::SCALE_Y:
3243 property = &mNode->mScale;
3246 case Dali::Actor::SCALE_Z:
3247 property = &mNode->mScale;
3250 case Dali::Actor::WORLD_SCALE:
3251 property = &mNode->mWorldScale;
3254 case Dali::Actor::VISIBLE:
3255 property = &mNode->mVisible;
3258 case Dali::Actor::COLOR:
3259 property = &mNode->mColor;
3262 case Dali::Actor::COLOR_RED:
3263 property = &mNode->mColor;
3266 case Dali::Actor::COLOR_GREEN:
3267 property = &mNode->mColor;
3270 case Dali::Actor::COLOR_BLUE:
3271 property = &mNode->mColor;
3274 case Dali::Actor::COLOR_ALPHA:
3275 property = &mNode->mColor;
3278 case Dali::Actor::WORLD_COLOR:
3279 property = &mNode->mWorldColor;
3282 case Dali::Actor::WORLD_MATRIX:
3283 property = &mNode->mWorldMatrix;
3294 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3296 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3300 case Dali::Actor::PARENT_ORIGIN_X:
3301 case Dali::Actor::ANCHOR_POINT_X:
3302 case Dali::Actor::SIZE_WIDTH:
3303 case Dali::Actor::POSITION_X:
3304 case Dali::Actor::SCALE_X:
3305 case Dali::Actor::COLOR_RED:
3306 case Dali::Actor::WORLD_POSITION_X:
3312 case Dali::Actor::PARENT_ORIGIN_Y:
3313 case Dali::Actor::ANCHOR_POINT_Y:
3314 case Dali::Actor::SIZE_HEIGHT:
3315 case Dali::Actor::POSITION_Y:
3316 case Dali::Actor::SCALE_Y:
3317 case Dali::Actor::COLOR_GREEN:
3318 case Dali::Actor::WORLD_POSITION_Y:
3324 case Dali::Actor::PARENT_ORIGIN_Z:
3325 case Dali::Actor::ANCHOR_POINT_Z:
3326 case Dali::Actor::SIZE_DEPTH:
3327 case Dali::Actor::POSITION_Z:
3328 case Dali::Actor::SCALE_Z:
3329 case Dali::Actor::COLOR_BLUE:
3330 case Dali::Actor::WORLD_POSITION_Z:
3336 case Dali::Actor::COLOR_ALPHA:
3349 return componentIndex;
3352 void Actor::SetParent(Actor* parent, int index)
3356 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3360 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3363 // Instruct each actor to create a corresponding node in the scene graph
3364 ConnectToStage( index );
3367 else // parent being set to NULL
3369 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3373 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3376 DALI_ASSERT_ALWAYS(mNode != NULL);
3380 // Disconnect the Node & its children from the scene-graph.
3381 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3384 // Instruct each actor to discard pointers to the scene-graph
3385 DisconnectFromStage();
3390 SceneGraph::Node* Actor::CreateNode() const
3395 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3398 Actor* actor = dynamic_cast<Actor*>(object);
3402 if(Dali::Actor::ACTION_SHOW == actionName)
3404 actor->SetVisible(true);
3407 else if(Dali::Actor::ACTION_HIDE == actionName)
3409 actor->SetVisible(false);
3417 } // namespace Internal