2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/internal/event/actors/actor-impl.h>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector3.h>
30 #include <dali/public-api/math/radian.h>
31 #include <dali/public-api/object/type-registry.h>
32 #include <dali/public-api/scripting/scripting.h>
34 #include <dali/internal/common/internal-constants.h>
35 #include <dali/internal/event/render-tasks/render-task-impl.h>
36 #include <dali/internal/event/actors/camera-actor-impl.h>
37 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
38 #include <dali/internal/event/common/property-index-ranges.h>
39 #include <dali/internal/event/common/stage-impl.h>
40 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
41 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
42 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
43 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
44 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
45 #include <dali/internal/event/animation/constraint-impl.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/update/common/animatable-property.h>
48 #include <dali/internal/update/common/property-owner-messages.h>
49 #include <dali/internal/update/nodes/node-messages.h>
50 #include <dali/internal/update/animation/scene-graph-constraint.h>
51 #include <dali/internal/event/effects/shader-effect-impl.h>
52 #include <dali/internal/common/message.h>
53 #include <dali/integration-api/debug.h>
56 #include <dali/internal/update/nodes/node-declarations.h>
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::PropertyBase;
61 using Dali::Internal::SceneGraph::Shader;
68 const Property::Index Actor::PARENT_ORIGIN = 0;
69 const Property::Index Actor::PARENT_ORIGIN_X = 1;
70 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
71 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
72 const Property::Index Actor::ANCHOR_POINT = 4;
73 const Property::Index Actor::ANCHOR_POINT_X = 5;
74 const Property::Index Actor::ANCHOR_POINT_Y = 6;
75 const Property::Index Actor::ANCHOR_POINT_Z = 7;
76 const Property::Index Actor::SIZE = 8;
77 const Property::Index Actor::SIZE_WIDTH = 9;
78 const Property::Index Actor::SIZE_HEIGHT = 10;
79 const Property::Index Actor::SIZE_DEPTH = 11;
80 const Property::Index Actor::POSITION = 12;
81 const Property::Index Actor::POSITION_X = 13;
82 const Property::Index Actor::POSITION_Y = 14;
83 const Property::Index Actor::POSITION_Z = 15;
84 const Property::Index Actor::WORLD_POSITION = 16;
85 const Property::Index Actor::WORLD_POSITION_X = 17;
86 const Property::Index Actor::WORLD_POSITION_Y = 18;
87 const Property::Index Actor::WORLD_POSITION_Z = 19;
88 const Property::Index Actor::ROTATION = 20;
89 const Property::Index Actor::WORLD_ROTATION = 21;
90 const Property::Index Actor::SCALE = 22;
91 const Property::Index Actor::SCALE_X = 23;
92 const Property::Index Actor::SCALE_Y = 24;
93 const Property::Index Actor::SCALE_Z = 25;
94 const Property::Index Actor::WORLD_SCALE = 26;
95 const Property::Index Actor::VISIBLE = 27;
96 const Property::Index Actor::COLOR = 28;
97 const Property::Index Actor::COLOR_RED = 29;
98 const Property::Index Actor::COLOR_GREEN = 30;
99 const Property::Index Actor::COLOR_BLUE = 31;
100 const Property::Index Actor::COLOR_ALPHA = 32;
101 const Property::Index Actor::WORLD_COLOR = 33;
102 const Property::Index Actor::WORLD_MATRIX = 34;
103 const Property::Index Actor::NAME = 35;
104 const Property::Index Actor::SENSITIVE = 36;
105 const Property::Index Actor::LEAVE_REQUIRED = 37;
106 const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
107 const Property::Index Actor::INHERIT_ROTATION = 39;
108 const Property::Index Actor::INHERIT_SCALE = 40;
109 const Property::Index Actor::COLOR_MODE = 41;
110 const Property::Index Actor::POSITION_INHERITANCE = 42;
111 const Property::Index Actor::DRAW_MODE = 43;
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-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
162 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
163 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
164 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
165 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
166 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
168 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
170 } // unnamed namespace
175 unsigned int Actor::mActorCounter = 0;
176 ActorContainer Actor::mNullChildren;
178 // Encapsulate actor related dynamics data
181 DynamicsData( Actor* slotOwner )
182 : slotDelegate( slotOwner )
186 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
187 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
189 DynamicsBodyPtr body;
190 JointContainer joints;
191 ReferencedJointContainer referencedJoints;
193 SlotDelegate< Actor > slotDelegate;
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_SET_SIZE, &Actor::DoConnectSignal);
210 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
211 SignalConnectorType signalConnector4(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 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
220 ActorPtr Actor::New()
222 ActorPtr actor( new Actor( BASIC ) );
224 // Second-phase construction
230 const std::string& Actor::GetName() const
235 void Actor::SetName(const std::string& name)
241 // ATTENTION: string for debug purposes is not thread safe.
242 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
246 unsigned int Actor::GetId() const
251 void Actor::Attach( ActorAttachment& attachment )
253 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
257 attachment.Connect();
260 mAttachment = ActorAttachmentPtr(&attachment);
263 ActorAttachmentPtr Actor::GetAttachment()
268 bool Actor::OnStage() const
273 Dali::Layer Actor::GetLayer()
277 // Short-circuit for Layer derived actors
280 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
283 // Find the immediate Layer parent
284 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
286 if( parent->IsLayer() )
288 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
295 void Actor::Add(Actor& child)
297 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
298 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
302 mChildren = new ActorContainer;
305 Actor* const oldParent( child.mParent );
307 // child might already be ours
308 if( this != oldParent )
310 // if we already have parent, unparent us first
313 oldParent->Remove( child ); // This causes OnChildRemove callback
316 // Guard against Add() during previous OnChildRemove callback
317 if ( !child.mParent )
319 // Do this first, since user callbacks from within SetParent() may need to remove child
320 mChildren->push_back(Dali::Actor(&child));
322 // SetParent asserts that child can be added
323 child.SetParent(this);
325 // Notification for derived classes
331 void Actor::Remove(Actor& child)
333 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
343 // Find the child in mChildren, and unparent it
344 ActorIter end = mChildren->end();
345 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
347 Actor& actor = GetImplementation(*iter);
349 if( &actor == &child )
351 // Keep handle for OnChildRemove notification
352 removed = Dali::Actor( &actor );
354 // Do this first, since user callbacks from within SetParent() may need to add the child
355 mChildren->erase(iter);
357 DALI_ASSERT_DEBUG( actor.GetParent() == this );
358 actor.SetParent( NULL );
366 // Notification for derived classes
367 OnChildRemove( GetImplementation(removed) );
371 void Actor::Unparent()
375 mParent->Remove( *this );
379 unsigned int Actor::GetChildCount() const
381 return ( NULL != mChildren ) ? mChildren->size() : 0;
384 Dali::Actor Actor::GetChildAt(unsigned int index) const
386 DALI_ASSERT_ALWAYS( index < GetChildCount() );
388 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
391 ActorContainer Actor::GetChildren()
393 if( NULL != mChildren )
398 // return copy of mNullChildren
399 return mNullChildren;
402 const ActorContainer& Actor::GetChildren() const
404 if( NULL != mChildren )
409 // return const reference to mNullChildren
410 return mNullChildren;
413 ActorPtr Actor::FindChildByName(const std::string& actorName)
416 if (actorName == mName)
422 ActorIter end = mChildren->end();
423 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
425 child = GetImplementation(*iter).FindChildByName(actorName);
436 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
438 Dali::Actor child = DoGetChildByAlias(actorAlias);
440 // If not found then search by name.
443 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
446 child = Dali::Actor(child_ptr.Get());
453 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
455 Dali::Actor child = GetChildByAlias(actorAlias);
457 if (!child && mChildren )
459 ActorIter end = mChildren->end();
460 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
462 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
474 ActorPtr Actor::FindChildById(const unsigned int id)
483 ActorIter end = mChildren->end();
484 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
486 child = GetImplementation(*iter).FindChildById(id);
497 void Actor::SetParentOrigin( const Vector3& origin )
501 // mNode is being used in a separate thread; queue a message to set the value & base value
502 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
505 // Cache for event-thread access
508 // not allocated, check if different from default
509 if( ParentOrigin::DEFAULT != origin )
511 mParentOrigin = new Vector3( origin );
516 // check if different from current costs more than just set
517 *mParentOrigin = origin;
521 void Actor::SetParentOriginX( float x )
523 const Vector3& current = GetCurrentParentOrigin();
525 SetParentOrigin( Vector3( x, current.y, current.z ) );
528 void Actor::SetParentOriginY( float y )
530 const Vector3& current = GetCurrentParentOrigin();
532 SetParentOrigin( Vector3( current.x, y, current.z ) );
535 void Actor::SetParentOriginZ( float z )
537 const Vector3& current = GetCurrentParentOrigin();
539 SetParentOrigin( Vector3( current.x, current.y, z ) );
542 const Vector3& Actor::GetCurrentParentOrigin() const
544 // Cached for event-thread access
545 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
548 void Actor::SetAnchorPoint(const Vector3& anchor)
552 // mNode is being used in a separate thread; queue a message to set the value & base value
553 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
556 // Cache for event-thread access
559 // not allocated, check if different from default
560 if( AnchorPoint::DEFAULT != anchor )
562 mAnchorPoint = new Vector3( anchor );
567 // check if different from current costs more than just set
568 *mAnchorPoint = anchor;
572 void Actor::SetAnchorPointX( float x )
574 const Vector3& current = GetCurrentAnchorPoint();
576 SetAnchorPoint( Vector3( x, current.y, current.z ) );
579 void Actor::SetAnchorPointY( float y )
581 const Vector3& current = GetCurrentAnchorPoint();
583 SetAnchorPoint( Vector3( current.x, y, current.z ) );
586 void Actor::SetAnchorPointZ( float z )
588 const Vector3& current = GetCurrentAnchorPoint();
590 SetAnchorPoint( Vector3( current.x, current.y, z ) );
593 const Vector3& Actor::GetCurrentAnchorPoint() const
595 // Cached for event-thread access
596 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
599 void Actor::SetPosition(float x, float y)
601 SetPosition(Vector3(x, y, 0.0f));
604 void Actor::SetPosition(float x, float y, float z)
606 SetPosition(Vector3(x, y, z));
609 void Actor::SetPosition(const Vector3& position)
613 // mNode is being used in a separate thread; queue a message to set the value & base value
614 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
618 void Actor::SetX(float x)
622 // mNode is being used in a separate thread; queue a message to set the value & base value
623 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
627 void Actor::SetY(float y)
631 // mNode is being used in a separate thread; queue a message to set the value & base value
632 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
636 void Actor::SetZ(float z)
640 // mNode is being used in a separate thread; queue a message to set the value & base value
641 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
645 void Actor::MoveBy(const Vector3& distance)
649 // mNode is being used in a separate thread; queue a message to set the value & base value
650 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
654 const Vector3& Actor::GetCurrentPosition() const
658 // mNode is being used in a separate thread; copy the value from the previous update
659 return mNode->GetPosition(mStage->GetEventBufferIndex());
662 return Vector3::ZERO;
665 const Vector3& Actor::GetCurrentWorldPosition() const
669 // mNode is being used in a separate thread; copy the value from the previous update
670 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
673 return Vector3::ZERO;
676 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
678 // this flag is not animatable so keep the value
679 mPositionInheritanceMode = mode;
682 // mNode is being used in a separate thread; queue a message to set the value
683 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
687 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
689 // Cached for event-thread access
690 return mPositionInheritanceMode;
693 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
695 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
696 normalizedAxis.Normalize();
698 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
700 SetRotation(rotation);
703 void Actor::SetRotation(const Quaternion& rotation)
707 // mNode is being used in a separate thread; queue a message to set the value & base value
708 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
712 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
716 // mNode is being used in a separate thread; queue a message to set the value & base value
717 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
721 void Actor::RotateBy(const Quaternion& relativeRotation)
725 // mNode is being used in a separate thread; queue a message to set the value & base value
726 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
730 const Quaternion& Actor::GetCurrentRotation() const
734 // mNode is being used in a separate thread; copy the value from the previous update
735 return mNode->GetRotation(mStage->GetEventBufferIndex());
738 return Quaternion::IDENTITY;
741 const Quaternion& Actor::GetCurrentWorldRotation() const
745 // mNode is being used in a separate thread; copy the value from the previous update
746 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
749 return Quaternion::IDENTITY;
752 void Actor::SetScale(float scale)
754 SetScale(Vector3(scale, scale, scale));
757 void Actor::SetScale(float x, float y, float z)
759 SetScale(Vector3(x, y, z));
762 void Actor::SetScale(const Vector3& scale)
766 // mNode is being used in a separate thread; queue a message to set the value & base value
767 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
771 void Actor::SetScaleX( float x )
775 // mNode is being used in a separate thread; queue a message to set the value & base value
776 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
780 void Actor::SetScaleY( float y )
784 // mNode is being used in a separate thread; queue a message to set the value & base value
785 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
789 void Actor::SetScaleZ( float z )
793 // mNode is being used in a separate thread; queue a message to set the value & base value
794 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
798 void Actor::SetInitialVolume(const Vector3& volume)
802 // mNode is being used in a separate thread; queue a message to set the value
803 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
807 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
811 // mNode is being used in a separate thread; queue a message to set the value
812 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
816 bool Actor::GetTransmitGeometryScaling() const
820 // mNode is being used in a separate thread; copy the value from the previous update
821 return mNode->GetTransmitGeometryScaling();
827 void Actor::ScaleBy(const Vector3& relativeScale)
831 // mNode is being used in a separate thread; queue a message to set the value & base value
832 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
836 const Vector3& Actor::GetCurrentScale() const
840 // mNode is being used in a separate thread; copy the value from the previous update
841 return mNode->GetScale(mStage->GetEventBufferIndex());
847 const Vector3& Actor::GetCurrentWorldScale() const
851 // mNode is being used in a separate thread; copy the value from the previous update
852 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
858 void Actor::SetInheritScale( bool inherit )
860 // non animateable so keep local copy
861 mInheritScale = inherit;
864 // mNode is being used in a separate thread; queue a message to set the value
865 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
869 bool Actor::IsScaleInherited() const
871 return mInheritScale;
874 Matrix Actor::GetCurrentWorldMatrix() const
878 // World matrix is no longer updated unless there is something observing the node.
879 // Need to calculate it from node's world position, rotation and scale:
880 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
881 Matrix worldMatrix(false);
882 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
883 mNode->GetWorldRotation( updateBufferIndex ),
884 mNode->GetWorldPosition( updateBufferIndex ) );
888 return Matrix::IDENTITY;
891 void Actor::SetVisible(bool visible)
895 // mNode is being used in a separate thread; queue a message to set the value & base value
896 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
900 bool Actor::IsVisible() const
904 // mNode is being used in a separate thread; copy the value from the previous update
905 return mNode->IsVisible( mStage->GetEventBufferIndex() );
911 void Actor::SetOpacity(float opacity)
915 // mNode is being used in a separate thread; queue a message to set the value & base value
916 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
920 void Actor::OpacityBy(float relativeOpacity)
924 // mNode is being used in a separate thread; queue a message to set the value & base value
925 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
929 float Actor::GetCurrentOpacity() const
933 // mNode is being used in a separate thread; copy the value from the previous update
934 return mNode->GetOpacity(mStage->GetEventBufferIndex());
940 const Vector4& Actor::GetCurrentWorldColor() const
944 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
950 void Actor::SetColor(const Vector4& color)
954 // mNode is being used in a separate thread; queue a message to set the value & base value
955 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
959 void Actor::SetColorRed( float red )
963 // mNode is being used in a separate thread; queue a message to set the value & base value
964 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
968 void Actor::SetColorGreen( float green )
972 // mNode is being used in a separate thread; queue a message to set the value & base value
973 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
977 void Actor::SetColorBlue( float blue )
981 // mNode is being used in a separate thread; queue a message to set the value & base value
982 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
986 void Actor::ColorBy(const Vector4& relativeColor)
990 // mNode is being used in a separate thread; queue a message to set the value & base value
991 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
995 const Vector4& Actor::GetCurrentColor() const
999 // mNode is being used in a separate thread; copy the value from the previous update
1000 return mNode->GetColor(mStage->GetEventBufferIndex());
1003 return Color::WHITE;
1006 void Actor::SetInheritRotation(bool inherit)
1008 // non animateable so keep local copy
1009 mInheritRotation = inherit;
1012 // mNode is being used in a separate thread; queue a message to set the value
1013 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1017 bool Actor::IsRotationInherited() const
1019 return mInheritRotation;
1022 void Actor::SetColorMode(ColorMode colorMode)
1024 // non animateable so keep local copy
1025 mColorMode = colorMode;
1028 // mNode is being used in a separate thread; queue a message to set the value
1029 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1033 ColorMode Actor::GetColorMode() const
1035 // we have cached copy
1039 void Actor::SetSize(float width, float height)
1041 SetSize( Vector2( width, height ) );
1044 void Actor::SetSize(float width, float height, float depth)
1046 SetSize( Vector3( width, height, depth ) );
1049 void Actor::SetSize(const Vector2& size)
1051 Vector3 volume( size );
1052 volume.z = std::min( size.width, size.height );
1056 void Actor::SetSize(const Vector3& size)
1060 // mNode is being used in a separate thread; queue a message to set the value & base value
1061 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1063 // Notification for derived classes
1066 // Emit signal for application developer
1068 if( !mSetSizeSignalV2.Empty() )
1070 Dali::Actor handle( this );
1071 mSetSizeSignalV2.Emit( handle, size );
1076 void Actor::SetWidth( float width )
1080 // mNode is being used in a separate thread; queue a message to set the value & base value
1081 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1085 void Actor::SetHeight( float height )
1089 // mNode is being used in a separate thread; queue a message to set the value & base value
1090 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1094 void Actor::SetDepth( float depth )
1098 // mNode is being used in a separate thread; queue a message to set the value & base value
1099 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1103 const Vector3& Actor::GetCurrentSize() const
1107 // mNode is being used in a separate thread; copy the value from the previous update
1108 return mNode->GetSize( mStage->GetEventBufferIndex() );
1111 return Vector3::ZERO;
1114 void Actor::SetInheritShaderEffect(bool inherit)
1118 // mNode is being used in a separate thread; queue a message to set the value
1119 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1123 bool Actor::GetInheritShaderEffect() const
1127 // mNode is being used in a separate thread; copy the value from the previous update
1128 return mNode->GetInheritShader();
1134 void Actor::SetShaderEffect(ShaderEffect& effect)
1140 mShaderEffect->Disconnect();
1143 mShaderEffect = ShaderEffectPtr(&effect);
1145 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1149 // mNode is being used in a separate thread; queue a message to apply shader
1150 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1153 mShaderEffect->Connect();
1157 mShaderEffect = ShaderEffectPtr(&effect);
1159 // Effects can only be applied when the Node is connected to scene-graph
1162 ShaderEffectPtr Actor::GetShaderEffect() const
1164 return mShaderEffect;
1167 void Actor::RemoveShaderEffect()
1173 // mNode is being used in a separate thread; queue a message to remove shader
1174 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1177 // Notify shader effect
1180 mShaderEffect->Disconnect();
1184 mShaderEffect.Reset();
1187 //--------------- Dynamics ---------------
1189 void Actor::DisableDynamics()
1191 if( NULL != mDynamicsData )
1193 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1195 // ensure dynamics object are disconnected from scene
1196 DisconnectDynamics();
1198 // delete joint owned by this actor
1199 while( !mDynamicsData->joints.empty() )
1201 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1204 // delete other joints referencing this actor
1205 while( !mDynamicsData->referencedJoints.empty() )
1207 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1208 ActorPtr jointOwner( joint->GetActor( true ) );
1211 jointOwner->RemoveDynamicsJoint( joint );
1215 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1218 // delete the DynamicsBody object
1219 mDynamicsData->body.Reset();
1221 // Discard Dynamics data structure
1222 delete mDynamicsData;
1223 mDynamicsData = NULL;
1227 DynamicsBodyPtr Actor::GetDynamicsBody() const
1229 DynamicsBodyPtr body;
1231 if( NULL != mDynamicsData )
1233 body = mDynamicsData->body;
1239 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1241 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1243 if( NULL == mDynamicsData )
1245 mDynamicsData = new DynamicsData( this );
1248 if( !mDynamicsData->body )
1250 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1254 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1257 if( mParent == world->GetRootActor().Get() )
1259 mDynamicsData->body->Connect(*mStage);
1265 return mDynamicsData->body;
1268 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1270 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1271 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1274 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1276 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1277 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1279 DynamicsJointPtr joint;
1281 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1285 if( NULL != mDynamicsData )
1287 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1289 if( mDynamicsData->joints.end() != it )
1291 // use existing joint
1297 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1298 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1302 bodyA = EnableDynamics( new DynamicsBodyConfig );
1307 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1310 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1311 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1313 if( OnStage() && attachedActor->OnStage() )
1315 joint->Connect(*mStage);
1318 attachedActor->ReferenceJoint( joint );
1320 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1321 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1328 const int Actor::GetNumberOfJoints() const
1330 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1333 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1335 DynamicsJointPtr joint;
1337 if( NULL != mDynamicsData )
1339 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1341 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1343 for( int i = 0; i < index; ++i )
1355 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1357 DynamicsJointPtr joint;
1359 if( NULL != mDynamicsData )
1361 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1363 if( mDynamicsData->joints.end() != it )
1365 // use existing joint
1373 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1375 if( NULL != mDynamicsData )
1377 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1378 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1380 for( ; it != endIt; ++it )
1382 if( it->second == joint.Get() )
1384 ActorPtr attachedActor( it->first );
1386 if( OnStage() && attachedActor && attachedActor->OnStage() )
1388 joint->Disconnect(*mStage);
1393 attachedActor->ReleaseJoint( joint );
1394 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1395 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1398 mDynamicsData->joints.erase(it);
1405 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1407 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1409 if( NULL != mDynamicsData )
1411 mDynamicsData->referencedJoints.push_back(joint);
1415 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1417 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1419 if( NULL != mDynamicsData )
1421 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1423 if( it != mDynamicsData->referencedJoints.end() )
1425 mDynamicsData->referencedJoints.erase( it );
1430 void Actor::SetDynamicsRoot(bool flag)
1432 if( mIsDynamicsRoot != flag )
1434 mIsDynamicsRoot = flag;
1436 if( OnStage() && mChildren )
1438 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1439 ActorIter end = mChildren->end();
1440 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1442 Actor& child = GetImplementation(*iter);
1444 if( child.GetDynamicsBody() )
1446 if( mIsDynamicsRoot )
1448 child.ConnectDynamics();
1452 child.DisconnectDynamics();
1460 bool Actor::IsDynamicsRoot() const
1462 return mIsDynamicsRoot;
1465 void Actor::AttachedActorOnStage( Dali::Actor actor )
1467 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1471 ActorPtr attachedActor( &GetImplementation(actor) );
1473 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1474 if( NULL != mDynamicsData )
1476 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1477 if( mDynamicsData->joints.end() != it )
1479 DynamicsJointPtr joint( it->second );
1480 joint->Connect(*mStage);
1486 void Actor::AttachedActorOffStage( Dali::Actor actor )
1488 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1492 ActorPtr attachedActor( &GetImplementation(actor) );
1494 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1495 if( NULL != mDynamicsData )
1497 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1498 if( mDynamicsData->joints.end() != it )
1500 DynamicsJointPtr joint( it->second );
1501 joint->Disconnect(*mStage);
1507 void Actor::ConnectDynamics()
1509 if( NULL != mDynamicsData && mDynamicsData->body )
1511 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1513 mDynamicsData->body->Connect(*mStage);
1515 // Connect all joints where attachedActor is also on stage
1516 if( !mDynamicsData->joints.empty() )
1518 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1519 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1521 for( ; it != endIt; ++it )
1523 Actor* attachedActor( it->first );
1524 if( NULL != attachedActor && attachedActor->OnStage() )
1526 DynamicsJointPtr joint( it->second );
1528 joint->Connect(*mStage);
1536 void Actor::DisconnectDynamics()
1538 if( NULL != mDynamicsData && mDynamicsData->body )
1542 mDynamicsData->body->Disconnect(*mStage);
1544 // Disconnect all joints
1545 if( !mDynamicsData->joints.empty() )
1547 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1548 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1550 for( ; it != endIt; ++it )
1552 DynamicsJointPtr joint( it->second );
1554 joint->Disconnect(*mStage);
1561 void Actor::SetOverlay(bool enable)
1563 // Setting STENCIL will override OVERLAY
1564 if( DrawMode::STENCIL != mDrawMode )
1566 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1570 bool Actor::IsOverlay() const
1572 return ( DrawMode::OVERLAY == mDrawMode );
1575 void Actor::SetDrawMode( DrawMode::Type drawMode )
1577 // this flag is not animatable so keep the value
1578 mDrawMode = drawMode;
1581 // mNode is being used in a separate thread; queue a message to set the value
1582 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1586 DrawMode::Type Actor::GetDrawMode() const
1591 bool Actor::ScreenToLocal( float& localX,
1594 float screenY ) const
1596 // only valid when on-stage
1599 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1601 Vector2 converted( screenX, screenY );
1603 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1604 const int taskCount = taskList.GetTaskCount();
1605 for( int i = taskCount - 1; i >= 0; --i )
1607 Dali::RenderTask task = taskList.GetTask( i );
1608 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1610 // found a task where this conversion was ok so return
1618 bool Actor::ScreenToLocal( RenderTask& renderTask,
1622 float screenY ) const
1624 bool retval = false;
1625 // only valid when on-stage
1628 CameraActor* camera = renderTask.GetCameraActor();
1632 renderTask.GetViewport( viewport );
1634 // need to translate coordinates to render tasks coordinate space
1635 Vector2 converted( screenX, screenY );
1636 if( renderTask.TranslateCoordinates( converted ) )
1638 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1645 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1646 const Matrix& projectionMatrix,
1647 const Viewport& viewport,
1651 float screenY ) const
1653 // Early-out if mNode is NULL
1659 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1661 // Calculate the ModelView matrix
1662 Matrix modelView(false/*don't init*/);
1663 // need to use the components as world matrix is only updated for actors that need it
1664 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1665 Matrix::Multiply(modelView, modelView, viewMatrix);
1667 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1668 Matrix invertedMvp(false/*don't init*/);
1669 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1670 bool success = invertedMvp.Invert();
1672 // Convert to GL coordinates
1673 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1678 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1685 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1691 if (XyPlaneIntersect(nearPos, farPos, local))
1693 Vector3 size = GetCurrentSize();
1694 localX = local.x + size.x * 0.5f;
1695 localY = local.y + size.y * 0.5f;
1706 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1709 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1711 Mathematical Formulation
1713 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1715 ( p - c ) dot ( p - c ) = r^2
1717 Given a ray with a point of origin 'o', and a direction vector 'd':
1719 ray(t) = o + td, t >= 0
1721 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1723 (o + td - c ) dot ( o + td - c ) = r^2
1725 To solve for t we first expand the above into a more recognisable quadratic equation form
1727 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1736 B = 2( o - c ) dot d
1737 C = ( o - c ) dot ( o - c ) - r^2
1739 which can be solved using a standard quadratic formula.
1741 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1743 Practical Simplification
1745 In a renderer, we often differentiate between world space and object space. In the object space
1746 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1747 into object space, the mathematical solution presented above can be simplified significantly.
1749 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1753 and we can find the t at which the (transformed) ray intersects the sphere by
1755 ( o + td ) dot ( o + td ) = r^2
1757 According to the reasoning above, we expand the above quadratic equation into the general form
1761 which now has coefficients:
1768 // Early out if mNode is NULL
1774 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1776 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1777 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1778 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1779 rayOrigin.y - translation.y,
1780 rayOrigin.z - translation.z);
1782 // Compute the radius is not needed, square radius it's enough.
1783 const Vector3& size( mNode->GetSize( bufferIndex ) );
1785 // Scale the sphere.
1786 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1788 const float width = size.width * scale.width;
1789 const float height = size.height * scale.height;
1791 float squareSphereRadius = 0.5f * ( width * width + height * height );
1793 float a = rayDir.Dot( rayDir ); // a
1794 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1795 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1797 return ( b2*b2 - a*c ) >= 0.f;
1800 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1807 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1809 // Transforms the ray to the local reference system.
1811 // Calculate the inverse of Model matrix
1812 Matrix invModelMatrix(false/*don't init*/);
1813 // need to use the components as world matrix is only updated for actors that need it
1814 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1816 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1817 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1819 // Test with the actor's XY plane (Normal = 0 0 1 1).
1821 float a = -rayOriginLocal.z;
1822 float b = rayDirLocal.z;
1824 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1826 // Ray travels distance * rayDirLocal to intersect with plane.
1829 const Vector3& size = mNode->GetSize( bufferIndex );
1831 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1832 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1834 // Test with the actor's geometry.
1835 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1842 void Actor::SetLeaveRequired(bool required)
1844 mLeaveRequired = required;
1847 bool Actor::GetLeaveRequired() const
1849 return mLeaveRequired;
1852 void Actor::SetKeyboardFocusable( bool focusable )
1854 mKeyboardFocusable = focusable;
1857 bool Actor::IsKeyboardFocusable() const
1859 return mKeyboardFocusable;
1862 bool Actor::GetTouchRequired() const
1864 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1867 bool Actor::GetMouseWheelEventRequired() const
1869 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1872 bool Actor::IsHittable() const
1874 return IsSensitive() &&
1876 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1880 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1882 bool consumed = false;
1884 if ( !mTouchedSignalV2.Empty() )
1886 Dali::Actor handle( this );
1887 consumed = mTouchedSignalV2.Emit( handle, event );
1892 // Notification for derived classes
1893 consumed = OnTouchEvent( event );
1899 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1901 bool consumed = false;
1903 if ( !mMouseWheelEventSignalV2.Empty() )
1905 Dali::Actor handle( this );
1906 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1911 // Notification for derived classes
1912 consumed = OnMouseWheelEvent(event);
1918 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1920 return mTouchedSignalV2;
1923 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1925 return mMouseWheelEventSignalV2;
1928 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1930 return mSetSizeSignalV2;
1933 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1935 return mOnStageSignalV2;
1938 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1940 return mOffStageSignalV2;
1943 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1945 bool connected( true );
1946 Actor* actor = dynamic_cast<Actor*>(object);
1948 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1950 actor->TouchedSignal().Connect( tracker, functor );
1952 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1954 actor->MouseWheelEventSignal().Connect( tracker, functor );
1956 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1958 actor->SetSizeSignal().Connect( tracker, functor );
1960 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1962 actor->OnStageSignal().Connect( tracker, functor );
1964 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1966 actor->OffStageSignal().Connect( tracker, functor );
1970 // signalName does not match any signal
1977 Actor::Actor( DerivedType derivedType )
1982 mParentOrigin( NULL ),
1983 mAnchorPoint( NULL ),
1984 mDynamicsData( NULL ),
1988 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1989 mIsRoot( ROOT_LAYER == derivedType ),
1990 mIsRenderable( RENDERABLE == derivedType ),
1991 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1992 mIsOnStage( false ),
1993 mIsDynamicsRoot(false),
1995 mLeaveRequired( false ),
1996 mKeyboardFocusable( false ),
1997 mDerivedRequiresTouch( false ),
1998 mDerivedRequiresMouseWheelEvent( false ),
1999 mOnStageSignalled( false ),
2000 mInheritRotation( true ),
2001 mInheritScale( true ),
2002 mDrawMode( DrawMode::NORMAL ),
2003 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2004 mColorMode( Node::DEFAULT_COLOR_MODE )
2008 void Actor::Initialize()
2010 mStage = Stage::GetCurrent();
2013 SceneGraph::Node* node = CreateNode();
2015 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2016 mNode = node; // Keep raw-pointer to Node
2018 if(!mDefaultPropertyLookup)
2020 mDefaultPropertyLookup = new DefaultPropertyLookup();
2022 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2024 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2035 // Remove mParent pointers from children even if we're destroying core,
2036 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2039 ActorConstIter endIter = mChildren->end();
2040 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2042 Actor& actor = GetImplementation( *iter );
2043 actor.SetParent( NULL );
2048 // Guard to allow handle destruction after Core has been destroyed
2049 if( Stage::IsInstalled() )
2053 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2054 mNode = NULL; // Node is about to be destroyed
2061 delete mDynamicsData;
2062 // Cleanup optional parent origin and anchor
2063 delete mParentOrigin;
2064 delete mAnchorPoint;
2067 void Actor::ConnectToStage( Stage& stage )
2069 // This container is used instead of walking the Actor hierachy.
2070 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2071 ActorContainer connectionList;
2073 // This stage is atomic i.e. not interrupted by user callbacks
2074 RecursiveConnectToStage( stage, connectionList );
2076 // Notify applications about the newly connected actors.
2077 const ActorIter endIter = connectionList.end();
2078 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2080 Actor& actor = GetImplementation(*iter);
2081 actor.NotifyStageConnection();
2085 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2087 DALI_ASSERT_ALWAYS( !OnStage() );
2091 ConnectToSceneGraph();
2093 // Notification for internal derived classes
2094 OnStageConnectionInternal();
2096 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2097 connectionList.push_back( Dali::Actor(this) );
2099 // Recursively connect children
2102 ActorConstIter endIter = mChildren->end();
2103 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2105 Actor& actor = GetImplementation( *iter );
2106 actor.RecursiveConnectToStage( stage, connectionList );
2112 * This method is called when the Actor is connected to the Stage.
2113 * The parent must have added its Node to the scene-graph.
2114 * The child must connect its Node to the parent's Node.
2115 * This is resursive; the child calls ConnectToStage() for its children.
2117 void Actor::ConnectToSceneGraph()
2119 DALI_ASSERT_DEBUG( mNode != NULL);
2120 DALI_ASSERT_DEBUG( mParent != NULL);
2121 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2125 // Reparent Node in next Update
2126 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2131 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2135 // Effects can only be applied when the node is on-stage
2136 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2139 // Notify shader effect
2140 mShaderEffect->Connect();
2143 // Notify attachment
2146 mAttachment->Connect();
2150 if( NULL != mDynamicsData )
2155 // Notification for ProxyObject::Observers
2159 void Actor::NotifyStageConnection()
2161 // Actors can be removed (in a callback), before the on-stage stage is reported.
2162 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2163 if ( OnStage() && !mOnStageSignalled )
2165 // Notification for external (CustomActor) derived classes
2166 OnStageConnectionExternal();
2168 if ( !mOnStageSignalV2.Empty() )
2170 Dali::Actor handle( this );
2171 mOnStageSignalV2.Emit( handle );
2174 // Guard against Remove during callbacks
2177 mOnStageSignalled = true; // signal required next time Actor is removed
2182 void Actor::DisconnectFromStage()
2184 // This container is used instead of walking the Actor hierachy.
2185 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2186 ActorContainer disconnectionList;
2188 // This stage is atomic i.e. not interrupted by user callbacks
2189 RecursiveDisconnectFromStage( disconnectionList );
2191 // Notify applications about the newly disconnected actors.
2192 const ActorIter endIter = disconnectionList.end();
2193 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2195 Actor& actor = GetImplementation(*iter);
2196 actor.NotifyStageDisconnection();
2200 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2202 DALI_ASSERT_ALWAYS( OnStage() );
2204 // Recursively disconnect children
2207 ActorConstIter endIter = mChildren->end();
2208 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2210 Actor& actor = GetImplementation( *iter );
2211 actor.RecursiveDisconnectFromStage( disconnectionList );
2215 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2216 disconnectionList.push_back( Dali::Actor(this) );
2218 // Notification for internal derived classes
2219 OnStageDisconnectionInternal();
2221 DisconnectFromSceneGraph();
2227 * This method is called by an actor or its parent, before a node removal message is sent.
2228 * This is recursive; the child calls DisconnectFromStage() for its children.
2230 void Actor::DisconnectFromSceneGraph()
2232 // Notification for ProxyObject::Observers
2233 OnSceneObjectRemove();
2235 // Notify shader effect
2238 mShaderEffect->Disconnect();
2241 // Notify attachment
2244 mAttachment->Disconnect();
2248 if( NULL != mDynamicsData )
2250 DisconnectDynamics();
2254 void Actor::NotifyStageDisconnection()
2256 // Actors can be added (in a callback), before the off-stage state is reported.
2257 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2258 // only do this step if there is a stage, i.e. Core is not being shut down
2259 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2261 // Notification for external (CustomeActor) derived classes
2262 OnStageDisconnectionExternal();
2264 if( !mOffStageSignalV2.Empty() )
2266 Dali::Actor handle( this );
2267 mOffStageSignalV2.Emit( handle );
2270 // Guard against Add during callbacks
2273 mOnStageSignalled = false; // signal required next time Actor is added
2278 bool Actor::IsNodeConnected() const
2280 bool connected( false );
2285 if( mNode->IsRoot() || mNode->GetParent() )
2294 bool Actor::IsSceneObjectRemovable() const
2299 unsigned int Actor::GetDefaultPropertyCount() const
2301 return DEFAULT_PROPERTY_COUNT;
2304 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2306 indices.reserve( DEFAULT_PROPERTY_COUNT );
2308 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2310 indices.push_back( i );
2314 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2316 if( index < DEFAULT_PROPERTY_COUNT )
2318 return DEFAULT_PROPERTY_DETAILS[index].name;
2322 // index out of range..return empty string
2323 return String::EMPTY;
2327 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2329 Property::Index index = Property::INVALID_INDEX;
2331 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2333 // Look for name in default properties
2334 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2335 if ( mDefaultPropertyLookup->end() != result )
2337 index = result->second;
2343 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2345 if( index < DEFAULT_PROPERTY_COUNT )
2347 return DEFAULT_PROPERTY_DETAILS[index].writable;
2355 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2357 if( index < DEFAULT_PROPERTY_COUNT )
2359 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2367 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2369 if( index < DEFAULT_PROPERTY_COUNT )
2371 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2379 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2381 if( index < DEFAULT_PROPERTY_COUNT )
2383 return DEFAULT_PROPERTY_DETAILS[index].type;
2387 // index out of range...return Property::NONE
2388 return Property::NONE;
2392 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2396 case Dali::Actor::PARENT_ORIGIN:
2398 SetParentOrigin( property.Get<Vector3>() );
2402 case Dali::Actor::PARENT_ORIGIN_X:
2404 SetParentOriginX( property.Get<float>() );
2408 case Dali::Actor::PARENT_ORIGIN_Y:
2410 SetParentOriginY( property.Get<float>() );
2414 case Dali::Actor::PARENT_ORIGIN_Z:
2416 SetParentOriginZ( property.Get<float>() );
2420 case Dali::Actor::ANCHOR_POINT:
2422 SetAnchorPoint( property.Get<Vector3>() );
2426 case Dali::Actor::ANCHOR_POINT_X:
2428 SetAnchorPointX( property.Get<float>() );
2432 case Dali::Actor::ANCHOR_POINT_Y:
2434 SetAnchorPointY( property.Get<float>() );
2438 case Dali::Actor::ANCHOR_POINT_Z:
2440 SetAnchorPointZ( property.Get<float>() );
2444 case Dali::Actor::SIZE:
2446 SetSize( property.Get<Vector3>() );
2450 case Dali::Actor::SIZE_WIDTH:
2452 SetWidth( property.Get<float>() );
2456 case Dali::Actor::SIZE_HEIGHT:
2458 SetHeight( property.Get<float>() );
2462 case Dali::Actor::SIZE_DEPTH:
2464 SetDepth( property.Get<float>() );
2468 case Dali::Actor::POSITION:
2470 SetPosition( property.Get<Vector3>() );
2474 case Dali::Actor::POSITION_X:
2476 SetX( property.Get<float>() );
2480 case Dali::Actor::POSITION_Y:
2482 SetY( property.Get<float>() );
2486 case Dali::Actor::POSITION_Z:
2488 SetZ( property.Get<float>() );
2492 case Dali::Actor::ROTATION:
2494 SetRotation( property.Get<Quaternion>() );
2498 case Dali::Actor::SCALE:
2500 SetScale( property.Get<Vector3>() );
2504 case Dali::Actor::SCALE_X:
2506 SetScaleX( property.Get<float>() );
2510 case Dali::Actor::SCALE_Y:
2512 SetScaleY( property.Get<float>() );
2516 case Dali::Actor::SCALE_Z:
2518 SetScaleZ( property.Get<float>() );
2522 case Dali::Actor::VISIBLE:
2524 SetVisible( property.Get<bool>() );
2528 case Dali::Actor::COLOR:
2530 SetColor( property.Get<Vector4>() );
2534 case Dali::Actor::COLOR_RED:
2536 SetColorRed( property.Get<float>() );
2540 case Dali::Actor::COLOR_GREEN:
2542 SetColorGreen( property.Get<float>() );
2546 case Dali::Actor::COLOR_BLUE:
2548 SetColorBlue( property.Get<float>() );
2552 case Dali::Actor::COLOR_ALPHA:
2554 SetOpacity( property.Get<float>() );
2558 case Dali::Actor::NAME:
2560 SetName( property.Get<std::string>() );
2564 case Dali::Actor::SENSITIVE:
2566 SetSensitive( property.Get<bool>() );
2570 case Dali::Actor::LEAVE_REQUIRED:
2572 SetLeaveRequired( property.Get<bool>() );
2576 case Dali::Actor::INHERIT_SHADER_EFFECT:
2578 SetInheritShaderEffect( 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 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2620 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2622 // TODO: This should be deprecated
2623 OnPropertySet(index, value);
2625 if(entry.IsAnimatable())
2627 // TODO: ADD MATRIX & MATRIX3 types
2629 switch ( entry.type )
2631 case Property::BOOLEAN:
2633 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2634 DALI_ASSERT_DEBUG( NULL != property );
2636 // property is being used in a separate thread; queue a message to set the property
2637 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2642 case Property::FLOAT:
2644 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2645 DALI_ASSERT_DEBUG( NULL != property );
2647 // property is being used in a separate thread; queue a message to set the property
2648 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2653 case Property::VECTOR2:
2655 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2656 DALI_ASSERT_DEBUG( NULL != property );
2658 // property is being used in a separate thread; queue a message to set the property
2659 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2664 case Property::VECTOR3:
2666 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2667 DALI_ASSERT_DEBUG( NULL != property );
2669 // property is being used in a separate thread; queue a message to set the property
2670 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2675 case Property::VECTOR4:
2677 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2678 DALI_ASSERT_DEBUG( NULL != property );
2680 // property is being used in a separate thread; queue a message to set the property
2681 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2686 case Property::ROTATION:
2688 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2689 DALI_ASSERT_DEBUG( NULL != property );
2691 // property is being used in a separate thread; queue a message to set the property
2692 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2699 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2706 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2708 Property::Value value;
2712 case Dali::Actor::PARENT_ORIGIN:
2714 value = GetCurrentParentOrigin();
2718 case Dali::Actor::PARENT_ORIGIN_X:
2720 value = GetCurrentParentOrigin().x;
2724 case Dali::Actor::PARENT_ORIGIN_Y:
2726 value = GetCurrentParentOrigin().y;
2730 case Dali::Actor::PARENT_ORIGIN_Z:
2732 value = GetCurrentParentOrigin().z;
2736 case Dali::Actor::ANCHOR_POINT:
2738 value = GetCurrentAnchorPoint();
2742 case Dali::Actor::ANCHOR_POINT_X:
2744 value = GetCurrentAnchorPoint().x;
2748 case Dali::Actor::ANCHOR_POINT_Y:
2750 value = GetCurrentAnchorPoint().y;
2754 case Dali::Actor::ANCHOR_POINT_Z:
2756 value = GetCurrentAnchorPoint().z;
2760 case Dali::Actor::SIZE:
2762 value = GetCurrentSize();
2766 case Dali::Actor::SIZE_WIDTH:
2768 value = GetCurrentSize().width;
2772 case Dali::Actor::SIZE_HEIGHT:
2774 value = GetCurrentSize().height;
2778 case Dali::Actor::SIZE_DEPTH:
2780 value = GetCurrentSize().depth;
2784 case Dali::Actor::POSITION:
2786 value = GetCurrentPosition();
2790 case Dali::Actor::POSITION_X:
2792 value = GetCurrentPosition().x;
2796 case Dali::Actor::POSITION_Y:
2798 value = GetCurrentPosition().y;
2802 case Dali::Actor::POSITION_Z:
2804 value = GetCurrentPosition().z;
2808 case Dali::Actor::WORLD_POSITION:
2810 value = GetCurrentWorldPosition();
2814 case Dali::Actor::WORLD_POSITION_X:
2816 value = GetCurrentWorldPosition().x;
2820 case Dali::Actor::WORLD_POSITION_Y:
2822 value = GetCurrentWorldPosition().y;
2826 case Dali::Actor::WORLD_POSITION_Z:
2828 value = GetCurrentWorldPosition().z;
2832 case Dali::Actor::ROTATION:
2834 value = GetCurrentRotation();
2838 case Dali::Actor::WORLD_ROTATION:
2840 value = GetCurrentWorldRotation();
2844 case Dali::Actor::SCALE:
2846 value = GetCurrentScale();
2850 case Dali::Actor::SCALE_X:
2852 value = GetCurrentScale().x;
2856 case Dali::Actor::SCALE_Y:
2858 value = GetCurrentScale().y;
2862 case Dali::Actor::SCALE_Z:
2864 value = GetCurrentScale().z;
2868 case Dali::Actor::WORLD_SCALE:
2870 value = GetCurrentWorldScale();
2874 case Dali::Actor::VISIBLE:
2876 value = IsVisible();
2880 case Dali::Actor::COLOR:
2882 value = GetCurrentColor();
2886 case Dali::Actor::COLOR_RED:
2888 value = GetCurrentColor().r;
2892 case Dali::Actor::COLOR_GREEN:
2894 value = GetCurrentColor().g;
2898 case Dali::Actor::COLOR_BLUE:
2900 value = GetCurrentColor().b;
2904 case Dali::Actor::COLOR_ALPHA:
2906 value = GetCurrentColor().a;
2910 case Dali::Actor::WORLD_COLOR:
2912 value = GetCurrentWorldColor();
2916 case Dali::Actor::WORLD_MATRIX:
2918 value = GetCurrentWorldMatrix();
2922 case Dali::Actor::NAME:
2928 case Dali::Actor::SENSITIVE:
2930 value = IsSensitive();
2934 case Dali::Actor::LEAVE_REQUIRED:
2936 value = GetLeaveRequired();
2940 case Dali::Actor::INHERIT_SHADER_EFFECT:
2942 value = GetInheritShaderEffect();
2946 case Dali::Actor::INHERIT_ROTATION:
2948 value = IsRotationInherited();
2952 case Dali::Actor::INHERIT_SCALE:
2954 value = IsScaleInherited();
2958 case Dali::Actor::COLOR_MODE:
2960 value = Scripting::GetColorMode( GetColorMode() );
2964 case Dali::Actor::POSITION_INHERITANCE:
2966 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2970 case Dali::Actor::DRAW_MODE:
2972 value = Scripting::GetDrawMode( GetDrawMode() );
2978 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2986 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2990 // mNode is being used in a separate thread; queue a message to add the property
2991 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2995 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2997 // This method should only return an object connected to the scene-graph
2998 return OnStage() ? mNode : NULL;
3001 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3003 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3005 const PropertyBase* property( NULL );
3007 // This method should only return a property of an object connected to the scene-graph
3013 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3015 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3017 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3019 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3021 else if( NULL != mNode )
3025 case Dali::Actor::SIZE:
3026 property = &mNode->mSize;
3029 case Dali::Actor::SIZE_WIDTH:
3030 property = &mNode->mSize;
3033 case Dali::Actor::SIZE_HEIGHT:
3034 property = &mNode->mSize;
3037 case Dali::Actor::SIZE_DEPTH:
3038 property = &mNode->mSize;
3041 case Dali::Actor::POSITION:
3042 property = &mNode->mPosition;
3045 case Dali::Actor::POSITION_X:
3046 property = &mNode->mPosition;
3049 case Dali::Actor::POSITION_Y:
3050 property = &mNode->mPosition;
3053 case Dali::Actor::POSITION_Z:
3054 property = &mNode->mPosition;
3057 case Dali::Actor::ROTATION:
3058 property = &mNode->mRotation;
3061 case Dali::Actor::SCALE:
3062 property = &mNode->mScale;
3065 case Dali::Actor::SCALE_X:
3066 property = &mNode->mScale;
3069 case Dali::Actor::SCALE_Y:
3070 property = &mNode->mScale;
3073 case Dali::Actor::SCALE_Z:
3074 property = &mNode->mScale;
3077 case Dali::Actor::VISIBLE:
3078 property = &mNode->mVisible;
3081 case Dali::Actor::COLOR:
3082 property = &mNode->mColor;
3085 case Dali::Actor::COLOR_RED:
3086 property = &mNode->mColor;
3089 case Dali::Actor::COLOR_GREEN:
3090 property = &mNode->mColor;
3093 case Dali::Actor::COLOR_BLUE:
3094 property = &mNode->mColor;
3097 case Dali::Actor::COLOR_ALPHA:
3098 property = &mNode->mColor;
3109 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3111 const PropertyInputImpl* property( NULL );
3113 // This method should only return a property of an object connected to the scene-graph
3119 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3121 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3123 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3125 property = entry->second.GetSceneGraphProperty();
3127 else if( NULL != mNode )
3131 case Dali::Actor::PARENT_ORIGIN:
3132 property = &mNode->mParentOrigin;
3135 case Dali::Actor::PARENT_ORIGIN_X:
3136 property = &mNode->mParentOrigin;
3139 case Dali::Actor::PARENT_ORIGIN_Y:
3140 property = &mNode->mParentOrigin;
3143 case Dali::Actor::PARENT_ORIGIN_Z:
3144 property = &mNode->mParentOrigin;
3147 case Dali::Actor::ANCHOR_POINT:
3148 property = &mNode->mAnchorPoint;
3151 case Dali::Actor::ANCHOR_POINT_X:
3152 property = &mNode->mAnchorPoint;
3155 case Dali::Actor::ANCHOR_POINT_Y:
3156 property = &mNode->mAnchorPoint;
3159 case Dali::Actor::ANCHOR_POINT_Z:
3160 property = &mNode->mAnchorPoint;
3163 case Dali::Actor::SIZE:
3164 property = &mNode->mSize;
3167 case Dali::Actor::SIZE_WIDTH:
3168 property = &mNode->mSize;
3171 case Dali::Actor::SIZE_HEIGHT:
3172 property = &mNode->mSize;
3175 case Dali::Actor::SIZE_DEPTH:
3176 property = &mNode->mSize;
3179 case Dali::Actor::POSITION:
3180 property = &mNode->mPosition;
3183 case Dali::Actor::POSITION_X:
3184 property = &mNode->mPosition;
3187 case Dali::Actor::POSITION_Y:
3188 property = &mNode->mPosition;
3191 case Dali::Actor::POSITION_Z:
3192 property = &mNode->mPosition;
3195 case Dali::Actor::WORLD_POSITION:
3196 property = &mNode->mWorldPosition;
3199 case Dali::Actor::WORLD_POSITION_X:
3200 property = &mNode->mWorldPosition;
3203 case Dali::Actor::WORLD_POSITION_Y:
3204 property = &mNode->mWorldPosition;
3207 case Dali::Actor::WORLD_POSITION_Z:
3208 property = &mNode->mWorldPosition;
3211 case Dali::Actor::ROTATION:
3212 property = &mNode->mRotation;
3215 case Dali::Actor::WORLD_ROTATION:
3216 property = &mNode->mWorldRotation;
3219 case Dali::Actor::SCALE:
3220 property = &mNode->mScale;
3223 case Dali::Actor::SCALE_X:
3224 property = &mNode->mScale;
3227 case Dali::Actor::SCALE_Y:
3228 property = &mNode->mScale;
3231 case Dali::Actor::SCALE_Z:
3232 property = &mNode->mScale;
3235 case Dali::Actor::WORLD_SCALE:
3236 property = &mNode->mWorldScale;
3239 case Dali::Actor::VISIBLE:
3240 property = &mNode->mVisible;
3243 case Dali::Actor::COLOR:
3244 property = &mNode->mColor;
3247 case Dali::Actor::COLOR_RED:
3248 property = &mNode->mColor;
3251 case Dali::Actor::COLOR_GREEN:
3252 property = &mNode->mColor;
3255 case Dali::Actor::COLOR_BLUE:
3256 property = &mNode->mColor;
3259 case Dali::Actor::COLOR_ALPHA:
3260 property = &mNode->mColor;
3263 case Dali::Actor::WORLD_COLOR:
3264 property = &mNode->mWorldColor;
3267 case Dali::Actor::WORLD_MATRIX:
3268 property = &mNode->mWorldMatrix;
3279 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3281 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3285 case Dali::Actor::PARENT_ORIGIN_X:
3286 case Dali::Actor::ANCHOR_POINT_X:
3287 case Dali::Actor::SIZE_WIDTH:
3288 case Dali::Actor::POSITION_X:
3289 case Dali::Actor::SCALE_X:
3290 case Dali::Actor::COLOR_RED:
3291 case Dali::Actor::WORLD_POSITION_X:
3297 case Dali::Actor::PARENT_ORIGIN_Y:
3298 case Dali::Actor::ANCHOR_POINT_Y:
3299 case Dali::Actor::SIZE_HEIGHT:
3300 case Dali::Actor::POSITION_Y:
3301 case Dali::Actor::SCALE_Y:
3302 case Dali::Actor::COLOR_GREEN:
3303 case Dali::Actor::WORLD_POSITION_Y:
3309 case Dali::Actor::PARENT_ORIGIN_Z:
3310 case Dali::Actor::ANCHOR_POINT_Z:
3311 case Dali::Actor::SIZE_DEPTH:
3312 case Dali::Actor::POSITION_Z:
3313 case Dali::Actor::SCALE_Z:
3314 case Dali::Actor::COLOR_BLUE:
3315 case Dali::Actor::WORLD_POSITION_Z:
3321 case Dali::Actor::COLOR_ALPHA:
3334 return componentIndex;
3337 void Actor::SetParent(Actor* parent)
3341 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3345 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3348 StagePtr stage = parent->mStage;
3350 // Instruct each actor to create a corresponding node in the scene graph
3351 ConnectToStage(*stage);
3354 else // parent being set to NULL
3356 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3360 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3363 DALI_ASSERT_ALWAYS(mNode != NULL);
3367 // Disconnect the Node & its children from the scene-graph.
3368 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3371 // Instruct each actor to discard pointers to the scene-graph
3372 DisconnectFromStage();
3377 SceneGraph::Node* Actor::CreateNode() const
3382 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3385 Actor* actor = dynamic_cast<Actor*>(object);
3389 if(Dali::Actor::ACTION_SHOW == actionName)
3391 actor->SetVisible(true);
3394 else if(Dali::Actor::ACTION_HIDE == actionName)
3396 actor->SetVisible(false);
3404 } // namespace Internal