2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/common/constants.h>
29 #include <dali/public-api/math/vector2.h>
30 #include <dali/public-api/math/vector3.h>
31 #include <dali/public-api/math/radian.h>
32 #include <dali/public-api/object/type-registry.h>
33 #include <dali/public-api/scripting/scripting.h>
35 #include <dali/internal/common/internal-constants.h>
36 #include <dali/internal/event/render-tasks/render-task-impl.h>
37 #include <dali/internal/event/actors/camera-actor-impl.h>
38 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
39 #include <dali/internal/event/common/property-index-ranges.h>
40 #include <dali/internal/event/common/stage-impl.h>
41 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
42 #include <dali/internal/event/animation/constraint-impl.h>
43 #include <dali/internal/event/common/projection.h>
44 #include <dali/internal/update/common/animatable-property.h>
45 #include <dali/internal/update/common/property-owner-messages.h>
46 #include <dali/internal/update/nodes/node-messages.h>
47 #include <dali/internal/update/nodes/node-declarations.h>
48 #include <dali/internal/update/animation/scene-graph-constraint.h>
49 #include <dali/internal/event/events/actor-gesture-data.h>
50 #include <dali/internal/common/message.h>
51 #include <dali/integration-api/debug.h>
53 #ifdef DYNAMICS_SUPPORT
54 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
60 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::AnimatableProperty;
62 using Dali::Internal::SceneGraph::PropertyBase;
67 const Property::Index Actor::PARENT_ORIGIN = 0;
68 const Property::Index Actor::PARENT_ORIGIN_X = 1;
69 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
70 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
71 const Property::Index Actor::ANCHOR_POINT = 4;
72 const Property::Index Actor::ANCHOR_POINT_X = 5;
73 const Property::Index Actor::ANCHOR_POINT_Y = 6;
74 const Property::Index Actor::ANCHOR_POINT_Z = 7;
75 const Property::Index Actor::SIZE = 8;
76 const Property::Index Actor::SIZE_WIDTH = 9;
77 const Property::Index Actor::SIZE_HEIGHT = 10;
78 const Property::Index Actor::SIZE_DEPTH = 11;
79 const Property::Index Actor::POSITION = 12;
80 const Property::Index Actor::POSITION_X = 13;
81 const Property::Index Actor::POSITION_Y = 14;
82 const Property::Index Actor::POSITION_Z = 15;
83 const Property::Index Actor::WORLD_POSITION = 16;
84 const Property::Index Actor::WORLD_POSITION_X = 17;
85 const Property::Index Actor::WORLD_POSITION_Y = 18;
86 const Property::Index Actor::WORLD_POSITION_Z = 19;
87 const Property::Index Actor::ROTATION = 20;
88 const Property::Index Actor::WORLD_ROTATION = 21;
89 const Property::Index Actor::SCALE = 22;
90 const Property::Index Actor::SCALE_X = 23;
91 const Property::Index Actor::SCALE_Y = 24;
92 const Property::Index Actor::SCALE_Z = 25;
93 const Property::Index Actor::WORLD_SCALE = 26;
94 const Property::Index Actor::VISIBLE = 27;
95 const Property::Index Actor::COLOR = 28;
96 const Property::Index Actor::COLOR_RED = 29;
97 const Property::Index Actor::COLOR_GREEN = 30;
98 const Property::Index Actor::COLOR_BLUE = 31;
99 const Property::Index Actor::COLOR_ALPHA = 32;
100 const Property::Index Actor::WORLD_COLOR = 33;
101 const Property::Index Actor::WORLD_MATRIX = 34;
102 const Property::Index Actor::NAME = 35;
103 const Property::Index Actor::SENSITIVE = 36;
104 const Property::Index Actor::LEAVE_REQUIRED = 37;
105 const Property::Index Actor::INHERIT_ROTATION = 38;
106 const Property::Index Actor::INHERIT_SCALE = 39;
107 const Property::Index Actor::COLOR_MODE = 40;
108 const Property::Index Actor::POSITION_INHERITANCE = 41;
109 const Property::Index Actor::DRAW_MODE = 42;
111 namespace // unnamed namespace
115 * We want to discourage the use of property strings (minimize string comparisons),
116 * particularly for the default properties.
118 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
120 // Name Type writable animatable constraint-input
121 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
122 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
123 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
124 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
125 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
126 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
127 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
128 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
129 { "size", Property::VECTOR3, true, true, true }, // SIZE
130 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
131 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
132 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
133 { "position", Property::VECTOR3, true, true, true }, // POSITION
134 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
135 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
136 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
137 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
138 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
139 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
140 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
141 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
142 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
143 { "scale", Property::VECTOR3, true, true, true }, // SCALE
144 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
145 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
146 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
147 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
148 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
149 { "color", Property::VECTOR4, true, true, true }, // COLOR
150 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
151 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
152 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
153 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
154 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
155 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
156 { "name", Property::STRING, true, false, false }, // NAME
157 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
158 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
159 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
160 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
161 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
162 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
163 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
165 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
167 } // unnamed namespace
172 unsigned int Actor::mActorCounter = 0;
173 ActorContainer Actor::mNullChildren;
175 #ifdef DYNAMICS_SUPPORT
177 // Encapsulate actor related dynamics data
180 DynamicsData( Actor* slotOwner )
181 : slotDelegate( slotOwner )
185 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
186 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
188 DynamicsBodyPtr body;
189 JointContainer joints;
190 ReferencedJointContainer referencedJoints;
192 SlotDelegate< Actor > slotDelegate;
195 #endif // DYNAMICS_SUPPORT
200 using namespace Dali;
202 BaseHandle CreateActor()
204 return Dali::Actor::New();
207 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
209 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
210 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_HOVERED, &Actor::DoConnectSignal);
211 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
212 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
213 SignalConnectorType signalConnector5(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
215 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
216 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
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::Insert(unsigned int index, Actor& child)
333 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
334 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
338 mChildren = new ActorContainer;
341 Actor* const oldParent( child.mParent );
343 // since an explicit position has been given, always insert, even if already a child
346 oldParent->Remove( child ); // This causes OnChildRemove callback
349 // Guard against Add() during previous OnChildRemove callback
350 if ( !child.mParent )
352 // Do this first, since user callbacks from within SetParent() may need to remove child
353 if (index < GetChildCount())
355 ActorIter it = mChildren->begin();
356 std::advance(it, index);
357 mChildren->insert(it, Dali::Actor(&child));
361 mChildren->push_back(Dali::Actor(&child));
363 // SetParent asserts that child can be added
364 child.SetParent(this, index);
366 // Notification for derived classes
371 void Actor::Remove(Actor& child)
373 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
383 // Find the child in mChildren, and unparent it
384 ActorIter end = mChildren->end();
385 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
387 Actor& actor = GetImplementation(*iter);
389 if( &actor == &child )
391 // Keep handle for OnChildRemove notification
392 removed = Dali::Actor( &actor );
394 // Do this first, since user callbacks from within SetParent() may need to add the child
395 mChildren->erase(iter);
397 DALI_ASSERT_DEBUG( actor.GetParent() == this );
398 actor.SetParent( NULL );
406 // Notification for derived classes
407 OnChildRemove( GetImplementation(removed) );
411 void Actor::Unparent()
415 mParent->Remove( *this );
419 unsigned int Actor::GetChildCount() const
421 return ( NULL != mChildren ) ? mChildren->size() : 0;
424 Dali::Actor Actor::GetChildAt(unsigned int index) const
426 DALI_ASSERT_ALWAYS( index < GetChildCount() );
428 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
431 ActorContainer Actor::GetChildren()
433 if( NULL != mChildren )
438 // return copy of mNullChildren
439 return mNullChildren;
442 const ActorContainer& Actor::GetChildren() const
444 if( NULL != mChildren )
449 // return const reference to mNullChildren
450 return mNullChildren;
453 ActorPtr Actor::FindChildByName(const std::string& actorName)
456 if (actorName == mName)
462 ActorIter end = mChildren->end();
463 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
465 child = GetImplementation(*iter).FindChildByName(actorName);
476 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
478 Dali::Actor child = DoGetChildByAlias(actorAlias);
480 // If not found then search by name.
483 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
486 child = Dali::Actor(child_ptr.Get());
493 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
495 Dali::Actor child = GetChildByAlias(actorAlias);
497 if (!child && mChildren )
499 ActorIter end = mChildren->end();
500 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
502 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
514 ActorPtr Actor::FindChildById(const unsigned int id)
523 ActorIter end = mChildren->end();
524 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
526 child = GetImplementation(*iter).FindChildById(id);
537 void Actor::SetParentOrigin( const Vector3& origin )
541 // mNode is being used in a separate thread; queue a message to set the value & base value
542 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
545 // Cache for event-thread access
548 // not allocated, check if different from default
549 if( ParentOrigin::DEFAULT != origin )
551 mParentOrigin = new Vector3( origin );
556 // check if different from current costs more than just set
557 *mParentOrigin = origin;
561 void Actor::SetParentOriginX( float x )
563 const Vector3& current = GetCurrentParentOrigin();
565 SetParentOrigin( Vector3( x, current.y, current.z ) );
568 void Actor::SetParentOriginY( float y )
570 const Vector3& current = GetCurrentParentOrigin();
572 SetParentOrigin( Vector3( current.x, y, current.z ) );
575 void Actor::SetParentOriginZ( float z )
577 const Vector3& current = GetCurrentParentOrigin();
579 SetParentOrigin( Vector3( current.x, current.y, z ) );
582 const Vector3& Actor::GetCurrentParentOrigin() const
584 // Cached for event-thread access
585 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
588 void Actor::SetAnchorPoint(const Vector3& anchor)
592 // mNode is being used in a separate thread; queue a message to set the value & base value
593 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
596 // Cache for event-thread access
599 // not allocated, check if different from default
600 if( AnchorPoint::DEFAULT != anchor )
602 mAnchorPoint = new Vector3( anchor );
607 // check if different from current costs more than just set
608 *mAnchorPoint = anchor;
612 void Actor::SetAnchorPointX( float x )
614 const Vector3& current = GetCurrentAnchorPoint();
616 SetAnchorPoint( Vector3( x, current.y, current.z ) );
619 void Actor::SetAnchorPointY( float y )
621 const Vector3& current = GetCurrentAnchorPoint();
623 SetAnchorPoint( Vector3( current.x, y, current.z ) );
626 void Actor::SetAnchorPointZ( float z )
628 const Vector3& current = GetCurrentAnchorPoint();
630 SetAnchorPoint( Vector3( current.x, current.y, z ) );
633 const Vector3& Actor::GetCurrentAnchorPoint() const
635 // Cached for event-thread access
636 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
639 void Actor::SetPosition(float x, float y)
641 SetPosition(Vector3(x, y, 0.0f));
644 void Actor::SetPosition(float x, float y, float z)
646 SetPosition(Vector3(x, y, z));
649 void Actor::SetPosition(const Vector3& position)
653 // mNode is being used in a separate thread; queue a message to set the value & base value
654 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
658 void Actor::SetX(float x)
662 // mNode is being used in a separate thread; queue a message to set the value & base value
663 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
667 void Actor::SetY(float y)
671 // mNode is being used in a separate thread; queue a message to set the value & base value
672 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
676 void Actor::SetZ(float z)
680 // mNode is being used in a separate thread; queue a message to set the value & base value
681 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
685 void Actor::MoveBy(const Vector3& distance)
689 // mNode is being used in a separate thread; queue a message to set the value & base value
690 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
694 const Vector3& Actor::GetCurrentPosition() const
698 // mNode is being used in a separate thread; copy the value from the previous update
699 return mNode->GetPosition(mStage->GetEventBufferIndex());
702 return Vector3::ZERO;
705 const Vector3& Actor::GetCurrentWorldPosition() const
709 // mNode is being used in a separate thread; copy the value from the previous update
710 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
713 return Vector3::ZERO;
716 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
718 // this flag is not animatable so keep the value
719 mPositionInheritanceMode = mode;
722 // mNode is being used in a separate thread; queue a message to set the value
723 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
727 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
729 // Cached for event-thread access
730 return mPositionInheritanceMode;
733 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
735 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
736 normalizedAxis.Normalize();
738 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
740 SetRotation(rotation);
743 void Actor::SetRotation(const Quaternion& rotation)
747 // mNode is being used in a separate thread; queue a message to set the value & base value
748 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
752 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
756 // mNode is being used in a separate thread; queue a message to set the value & base value
757 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
761 void Actor::RotateBy(const Quaternion& relativeRotation)
765 // mNode is being used in a separate thread; queue a message to set the value & base value
766 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
770 const Quaternion& Actor::GetCurrentRotation() const
774 // mNode is being used in a separate thread; copy the value from the previous update
775 return mNode->GetRotation(mStage->GetEventBufferIndex());
778 return Quaternion::IDENTITY;
781 const Quaternion& Actor::GetCurrentWorldRotation() const
785 // mNode is being used in a separate thread; copy the value from the previous update
786 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
789 return Quaternion::IDENTITY;
792 void Actor::SetScale(float scale)
794 SetScale(Vector3(scale, scale, scale));
797 void Actor::SetScale(float x, float y, float z)
799 SetScale(Vector3(x, y, z));
802 void Actor::SetScale(const Vector3& scale)
806 // mNode is being used in a separate thread; queue a message to set the value & base value
807 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
811 void Actor::SetScaleX( float x )
815 // mNode is being used in a separate thread; queue a message to set the value & base value
816 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
820 void Actor::SetScaleY( float y )
824 // mNode is being used in a separate thread; queue a message to set the value & base value
825 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
829 void Actor::SetScaleZ( float z )
833 // mNode is being used in a separate thread; queue a message to set the value & base value
834 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
838 void Actor::SetInitialVolume(const Vector3& volume)
842 // mNode is being used in a separate thread; queue a message to set the value
843 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
847 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
851 // mNode is being used in a separate thread; queue a message to set the value
852 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
856 bool Actor::GetTransmitGeometryScaling() const
860 // mNode is being used in a separate thread; copy the value from the previous update
861 return mNode->GetTransmitGeometryScaling();
867 void Actor::ScaleBy(const Vector3& relativeScale)
871 // mNode is being used in a separate thread; queue a message to set the value & base value
872 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
876 const Vector3& Actor::GetCurrentScale() const
880 // mNode is being used in a separate thread; copy the value from the previous update
881 return mNode->GetScale(mStage->GetEventBufferIndex());
887 const Vector3& Actor::GetCurrentWorldScale() const
891 // mNode is being used in a separate thread; copy the value from the previous update
892 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
898 void Actor::SetInheritScale( bool inherit )
900 // non animateable so keep local copy
901 mInheritScale = inherit;
904 // mNode is being used in a separate thread; queue a message to set the value
905 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
909 bool Actor::IsScaleInherited() const
911 return mInheritScale;
914 Matrix Actor::GetCurrentWorldMatrix() const
918 // World matrix is no longer updated unless there is something observing the node.
919 // Need to calculate it from node's world position, rotation and scale:
920 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
921 Matrix worldMatrix(false);
922 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
923 mNode->GetWorldRotation( updateBufferIndex ),
924 mNode->GetWorldPosition( updateBufferIndex ) );
928 return Matrix::IDENTITY;
931 void Actor::SetVisible(bool visible)
935 // mNode is being used in a separate thread; queue a message to set the value & base value
936 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
940 bool Actor::IsVisible() const
944 // mNode is being used in a separate thread; copy the value from the previous update
945 return mNode->IsVisible( mStage->GetEventBufferIndex() );
951 void Actor::SetOpacity(float opacity)
955 // mNode is being used in a separate thread; queue a message to set the value & base value
956 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
960 void Actor::OpacityBy(float relativeOpacity)
964 // mNode is being used in a separate thread; queue a message to set the value & base value
965 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
969 float Actor::GetCurrentOpacity() const
973 // mNode is being used in a separate thread; copy the value from the previous update
974 return mNode->GetOpacity(mStage->GetEventBufferIndex());
980 const Vector4& Actor::GetCurrentWorldColor() const
984 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
990 void Actor::SetColor(const Vector4& color)
994 // mNode is being used in a separate thread; queue a message to set the value & base value
995 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
999 void Actor::SetColorRed( float red )
1003 // mNode is being used in a separate thread; queue a message to set the value & base value
1004 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1008 void Actor::SetColorGreen( float green )
1012 // mNode is being used in a separate thread; queue a message to set the value & base value
1013 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1017 void Actor::SetColorBlue( float blue )
1021 // mNode is being used in a separate thread; queue a message to set the value & base value
1022 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1026 void Actor::ColorBy(const Vector4& relativeColor)
1030 // mNode is being used in a separate thread; queue a message to set the value & base value
1031 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1035 const Vector4& Actor::GetCurrentColor() const
1039 // mNode is being used in a separate thread; copy the value from the previous update
1040 return mNode->GetColor(mStage->GetEventBufferIndex());
1043 return Color::WHITE;
1046 void Actor::SetInheritRotation(bool inherit)
1048 // non animateable so keep local copy
1049 mInheritRotation = inherit;
1052 // mNode is being used in a separate thread; queue a message to set the value
1053 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1057 bool Actor::IsRotationInherited() const
1059 return mInheritRotation;
1062 void Actor::SetColorMode(ColorMode colorMode)
1064 // non animateable so keep local copy
1065 mColorMode = colorMode;
1068 // mNode is being used in a separate thread; queue a message to set the value
1069 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1073 ColorMode Actor::GetColorMode() const
1075 // we have cached copy
1079 void Actor::SetSize(float width, float height)
1081 SetSize( Vector2( width, height ) );
1084 void Actor::SetSize(float width, float height, float depth)
1086 SetSize( Vector3( width, height, depth ) );
1089 void Actor::SetSize(const Vector2& size)
1091 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1094 float Actor::CalculateSizeZ( const Vector2& size ) const
1096 return std::min( size.width, size.height );
1099 void Actor::SetSize(const Vector3& size)
1105 // mNode is being used in a separate thread; queue a message to set the value & base value
1106 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1108 // Notification for derived classes
1111 // Emit signal for application developer
1113 if( !mSetSizeSignalV2.Empty() )
1115 Dali::Actor handle( this );
1116 mSetSizeSignalV2.Emit( handle, mSize );
1121 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1125 // Notify deriving classes
1126 OnSizeAnimation( animation, targetSize );
1129 void Actor::SetWidth( float width )
1133 // mNode is being used in a separate thread; queue a message to set the value & base value
1134 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1138 void Actor::SetHeight( float height )
1142 // mNode is being used in a separate thread; queue a message to set the value & base value
1143 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1147 void Actor::SetDepth( float depth )
1151 // mNode is being used in a separate thread; queue a message to set the value & base value
1152 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1156 const Vector3& Actor::GetSize() const
1161 const Vector3& Actor::GetCurrentSize() const
1165 // mNode is being used in a separate thread; copy the value from the previous update
1166 return mNode->GetSize( mStage->GetEventBufferIndex() );
1169 return Vector3::ZERO;
1172 Vector3 Actor::GetNaturalSize() const
1174 // It is up to deriving classes to return the appropriate natural size
1175 return Vector3( 0.0f, 0.0f, 0.0f );
1179 #ifdef DYNAMICS_SUPPORT
1181 //--------------- Dynamics ---------------
1183 void Actor::DisableDynamics()
1185 if( NULL != mDynamicsData )
1187 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1189 // ensure dynamics object are disconnected from scene
1190 DisconnectDynamics();
1192 // delete joint owned by this actor
1193 while( !mDynamicsData->joints.empty() )
1195 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1198 // delete other joints referencing this actor
1199 while( !mDynamicsData->referencedJoints.empty() )
1201 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1202 ActorPtr jointOwner( joint->GetActor( true ) );
1205 jointOwner->RemoveDynamicsJoint( joint );
1209 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1212 // delete the DynamicsBody object
1213 mDynamicsData->body.Reset();
1215 // Discard Dynamics data structure
1216 delete mDynamicsData;
1217 mDynamicsData = NULL;
1221 DynamicsBodyPtr Actor::GetDynamicsBody() const
1223 DynamicsBodyPtr body;
1225 if( NULL != mDynamicsData )
1227 body = mDynamicsData->body;
1233 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1235 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1237 if( NULL == mDynamicsData )
1239 mDynamicsData = new DynamicsData( this );
1242 if( !mDynamicsData->body )
1244 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1248 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1251 if( mParent == world->GetRootActor().Get() )
1253 mDynamicsData->body->Connect(*mStage);
1259 return mDynamicsData->body;
1262 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1264 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1265 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1268 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1270 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1271 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1273 DynamicsJointPtr joint;
1275 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1279 if( NULL != mDynamicsData )
1281 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1283 if( mDynamicsData->joints.end() != it )
1285 // use existing joint
1291 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1292 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1296 bodyA = EnableDynamics( new DynamicsBodyConfig );
1301 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1304 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1305 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1307 if( OnStage() && attachedActor->OnStage() )
1309 joint->Connect(*mStage);
1312 attachedActor->ReferenceJoint( joint );
1314 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1315 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1322 const int Actor::GetNumberOfJoints() const
1324 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1327 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1329 DynamicsJointPtr joint;
1331 if( NULL != mDynamicsData )
1333 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1335 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1337 for( int i = 0; i < index; ++i )
1349 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1351 DynamicsJointPtr joint;
1353 if( NULL != mDynamicsData )
1355 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1357 if( mDynamicsData->joints.end() != it )
1359 // use existing joint
1367 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1369 if( NULL != mDynamicsData )
1371 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1372 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1374 for( ; it != endIt; ++it )
1376 if( it->second == joint.Get() )
1378 ActorPtr attachedActor( it->first );
1380 if( OnStage() && attachedActor && attachedActor->OnStage() )
1382 joint->Disconnect(*mStage);
1387 attachedActor->ReleaseJoint( joint );
1388 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1389 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1392 mDynamicsData->joints.erase(it);
1399 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1401 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1403 if( NULL != mDynamicsData )
1405 mDynamicsData->referencedJoints.push_back(joint);
1409 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1411 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1413 if( NULL != mDynamicsData )
1415 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1417 if( it != mDynamicsData->referencedJoints.end() )
1419 mDynamicsData->referencedJoints.erase( it );
1424 void Actor::SetDynamicsRoot(bool flag)
1426 if( mIsDynamicsRoot != flag )
1428 mIsDynamicsRoot = flag;
1430 if( OnStage() && mChildren )
1432 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1433 ActorIter end = mChildren->end();
1434 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1436 Actor& child = GetImplementation(*iter);
1438 if( child.GetDynamicsBody() )
1440 if( mIsDynamicsRoot )
1442 child.ConnectDynamics();
1446 child.DisconnectDynamics();
1454 bool Actor::IsDynamicsRoot() const
1456 return mIsDynamicsRoot;
1459 void Actor::AttachedActorOnStage( Dali::Actor actor )
1461 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1465 ActorPtr attachedActor( &GetImplementation(actor) );
1467 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1468 if( NULL != mDynamicsData )
1470 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1471 if( mDynamicsData->joints.end() != it )
1473 DynamicsJointPtr joint( it->second );
1474 joint->Connect(*mStage);
1480 void Actor::AttachedActorOffStage( Dali::Actor actor )
1482 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1486 ActorPtr attachedActor( &GetImplementation(actor) );
1488 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1489 if( NULL != mDynamicsData )
1491 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1492 if( mDynamicsData->joints.end() != it )
1494 DynamicsJointPtr joint( it->second );
1495 joint->Disconnect(*mStage);
1501 void Actor::ConnectDynamics()
1503 if( NULL != mDynamicsData && mDynamicsData->body )
1505 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1507 mDynamicsData->body->Connect(*mStage);
1509 // Connect all joints where attachedActor is also on stage
1510 if( !mDynamicsData->joints.empty() )
1512 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1513 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1515 for( ; it != endIt; ++it )
1517 Actor* attachedActor( it->first );
1518 if( NULL != attachedActor && attachedActor->OnStage() )
1520 DynamicsJointPtr joint( it->second );
1522 joint->Connect(*mStage);
1530 void Actor::DisconnectDynamics()
1532 if( NULL != mDynamicsData && mDynamicsData->body )
1536 mDynamicsData->body->Disconnect(*mStage);
1538 // Disconnect all joints
1539 if( !mDynamicsData->joints.empty() )
1541 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1542 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1544 for( ; it != endIt; ++it )
1546 DynamicsJointPtr joint( it->second );
1548 joint->Disconnect(*mStage);
1555 #endif // DYNAMICS_SUPPORT
1557 void Actor::SetOverlay(bool enable)
1559 // Setting STENCIL will override OVERLAY
1560 if( DrawMode::STENCIL != mDrawMode )
1562 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1566 bool Actor::IsOverlay() const
1568 return ( DrawMode::OVERLAY == mDrawMode );
1571 void Actor::SetDrawMode( DrawMode::Type drawMode )
1573 // this flag is not animatable so keep the value
1574 mDrawMode = drawMode;
1577 // mNode is being used in a separate thread; queue a message to set the value
1578 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1582 DrawMode::Type Actor::GetDrawMode() const
1587 bool Actor::ScreenToLocal( float& localX,
1590 float screenY ) const
1592 // only valid when on-stage
1595 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1597 Vector2 converted( screenX, screenY );
1599 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1600 const int taskCount = taskList.GetTaskCount();
1601 for( int i = taskCount - 1; i >= 0; --i )
1603 Dali::RenderTask task = taskList.GetTask( i );
1604 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1606 // found a task where this conversion was ok so return
1614 bool Actor::ScreenToLocal( RenderTask& renderTask,
1618 float screenY ) const
1620 bool retval = false;
1621 // only valid when on-stage
1624 CameraActor* camera = renderTask.GetCameraActor();
1628 renderTask.GetViewport( viewport );
1630 // need to translate coordinates to render tasks coordinate space
1631 Vector2 converted( screenX, screenY );
1632 if( renderTask.TranslateCoordinates( converted ) )
1634 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1641 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1642 const Matrix& projectionMatrix,
1643 const Viewport& viewport,
1647 float screenY ) const
1649 // Early-out if mNode is NULL
1655 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1657 // Calculate the ModelView matrix
1658 Matrix modelView(false/*don't init*/);
1659 // need to use the components as world matrix is only updated for actors that need it
1660 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1661 Matrix::Multiply(modelView, modelView, viewMatrix);
1663 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1664 Matrix invertedMvp(false/*don't init*/);
1665 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1666 bool success = invertedMvp.Invert();
1668 // Convert to GL coordinates
1669 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1674 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1681 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1687 if (XyPlaneIntersect(nearPos, farPos, local))
1689 Vector3 size = GetCurrentSize();
1690 localX = local.x + size.x * 0.5f;
1691 localY = local.y + size.y * 0.5f;
1702 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1705 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1707 Mathematical Formulation
1709 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1711 ( p - c ) dot ( p - c ) = r^2
1713 Given a ray with a point of origin 'o', and a direction vector 'd':
1715 ray(t) = o + td, t >= 0
1717 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1719 (o + td - c ) dot ( o + td - c ) = r^2
1721 To solve for t we first expand the above into a more recognisable quadratic equation form
1723 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1732 B = 2( o - c ) dot d
1733 C = ( o - c ) dot ( o - c ) - r^2
1735 which can be solved using a standard quadratic formula.
1737 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1739 Practical Simplification
1741 In a renderer, we often differentiate between world space and object space. In the object space
1742 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1743 into object space, the mathematical solution presented above can be simplified significantly.
1745 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1749 and we can find the t at which the (transformed) ray intersects the sphere by
1751 ( o + td ) dot ( o + td ) = r^2
1753 According to the reasoning above, we expand the above quadratic equation into the general form
1757 which now has coefficients:
1764 // Early out if mNode is NULL
1770 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1772 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1773 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1774 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1775 rayOrigin.y - translation.y,
1776 rayOrigin.z - translation.z);
1778 // Compute the radius is not needed, square radius it's enough.
1779 const Vector3& size( mNode->GetSize( bufferIndex ) );
1781 // Scale the sphere.
1782 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1784 const float width = size.width * scale.width;
1785 const float height = size.height * scale.height;
1787 float squareSphereRadius = 0.5f * ( width * width + height * height );
1789 float a = rayDir.Dot( rayDir ); // a
1790 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1791 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1793 return ( b2*b2 - a*c ) >= 0.f;
1796 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1803 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1805 // Transforms the ray to the local reference system.
1807 // Calculate the inverse of Model matrix
1808 Matrix invModelMatrix(false/*don't init*/);
1809 // need to use the components as world matrix is only updated for actors that need it
1810 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1812 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1813 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1815 // Test with the actor's XY plane (Normal = 0 0 1 1).
1817 float a = -rayOriginLocal.z;
1818 float b = rayDirLocal.z;
1820 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1822 // Ray travels distance * rayDirLocal to intersect with plane.
1825 const Vector3& size = mNode->GetSize( bufferIndex );
1827 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1828 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1830 // Test with the actor's geometry.
1831 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1838 void Actor::SetLeaveRequired(bool required)
1840 mLeaveRequired = required;
1843 bool Actor::GetLeaveRequired() const
1845 return mLeaveRequired;
1848 void Actor::SetKeyboardFocusable( bool focusable )
1850 mKeyboardFocusable = focusable;
1853 bool Actor::IsKeyboardFocusable() const
1855 return mKeyboardFocusable;
1858 bool Actor::GetTouchRequired() const
1860 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1863 bool Actor::GetHoverRequired() const
1865 return !mHoveredSignalV2.Empty() || mDerivedRequiresHover;
1868 bool Actor::GetMouseWheelEventRequired() const
1870 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1873 bool Actor::IsHittable() const
1875 return IsSensitive() &&
1877 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1881 ActorGestureData& Actor::GetGestureData()
1883 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1884 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1885 if ( NULL == mGestureData )
1887 mGestureData = new ActorGestureData;
1889 return *mGestureData;
1892 bool Actor::IsGestureRequred( Gesture::Type type ) const
1894 return mGestureData && mGestureData->IsGestureRequred( type );
1897 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1899 bool consumed = false;
1901 if ( !mTouchedSignalV2.Empty() )
1903 Dali::Actor handle( this );
1904 consumed = mTouchedSignalV2.Emit( handle, event );
1909 // Notification for derived classes
1910 consumed = OnTouchEvent( event );
1916 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1918 bool consumed = false;
1920 if ( !mHoveredSignalV2.Empty() )
1922 Dali::Actor handle( this );
1923 consumed = mHoveredSignalV2.Emit( handle, event );
1928 // Notification for derived classes
1929 consumed = OnHoverEvent( event );
1935 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1937 bool consumed = false;
1939 if ( !mMouseWheelEventSignalV2.Empty() )
1941 Dali::Actor handle( this );
1942 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1947 // Notification for derived classes
1948 consumed = OnMouseWheelEvent(event);
1954 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1956 return mTouchedSignalV2;
1959 Dali::Actor::HoverSignalV2& Actor::HoveredSignal()
1961 return mHoveredSignalV2;
1964 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1966 return mMouseWheelEventSignalV2;
1969 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1971 return mSetSizeSignalV2;
1974 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1976 return mOnStageSignalV2;
1979 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1981 return mOffStageSignalV2;
1984 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1986 bool connected( true );
1987 Actor* actor = dynamic_cast<Actor*>(object);
1989 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1991 actor->TouchedSignal().Connect( tracker, functor );
1993 else if(Dali::Actor::SIGNAL_HOVERED == signalName)
1995 actor->HoveredSignal().Connect( tracker, functor );
1997 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1999 actor->MouseWheelEventSignal().Connect( tracker, functor );
2001 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
2003 actor->SetSizeSignal().Connect( tracker, functor );
2005 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
2007 actor->OnStageSignal().Connect( tracker, functor );
2009 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
2011 actor->OffStageSignal().Connect( tracker, functor );
2015 // signalName does not match any signal
2022 Actor::Actor( DerivedType derivedType )
2027 mParentOrigin( NULL ),
2028 mAnchorPoint( NULL ),
2029 #ifdef DYNAMICS_SUPPORT
2030 mDynamicsData( NULL ),
2032 mGestureData( NULL ),
2034 mSize( 0.0f, 0.0f, 0.0f ),
2036 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2037 mIsRoot( ROOT_LAYER == derivedType ),
2038 mIsRenderable( RENDERABLE == derivedType ),
2039 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2040 mIsOnStage( false ),
2041 mIsDynamicsRoot(false),
2043 mLeaveRequired( false ),
2044 mKeyboardFocusable( false ),
2045 mDerivedRequiresTouch( false ),
2046 mDerivedRequiresHover( false ),
2047 mDerivedRequiresMouseWheelEvent( false ),
2048 mOnStageSignalled( false ),
2049 mInheritRotation( true ),
2050 mInheritScale( true ),
2051 mDrawMode( DrawMode::NORMAL ),
2052 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2053 mColorMode( Node::DEFAULT_COLOR_MODE )
2057 void Actor::Initialize()
2059 mStage = Stage::GetCurrent();
2062 SceneGraph::Node* node = CreateNode();
2064 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2065 mNode = node; // Keep raw-pointer to Node
2074 // Remove mParent pointers from children even if we're destroying core,
2075 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2078 ActorConstIter endIter = mChildren->end();
2079 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2081 Actor& actor = GetImplementation( *iter );
2082 actor.SetParent( NULL );
2087 // Guard to allow handle destruction after Core has been destroyed
2088 if( Stage::IsInstalled() )
2092 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2093 mNode = NULL; // Node is about to be destroyed
2099 #ifdef DYNAMICS_SUPPORT
2101 delete mDynamicsData;
2104 // Cleanup optional gesture data
2105 delete mGestureData;
2107 // Cleanup optional parent origin and anchor
2108 delete mParentOrigin;
2109 delete mAnchorPoint;
2112 void Actor::ConnectToStage( Stage& stage, int index )
2114 // This container is used instead of walking the Actor hierachy.
2115 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2116 ActorContainer connectionList;
2118 // This stage is atomic i.e. not interrupted by user callbacks
2119 RecursiveConnectToStage( stage, connectionList, index );
2121 // Notify applications about the newly connected actors.
2122 const ActorIter endIter = connectionList.end();
2123 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2125 Actor& actor = GetImplementation(*iter);
2126 actor.NotifyStageConnection();
2130 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList, int index )
2132 DALI_ASSERT_ALWAYS( !OnStage() );
2136 ConnectToSceneGraph(index);
2138 // Notification for internal derived classes
2139 OnStageConnectionInternal();
2141 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2142 connectionList.push_back( Dali::Actor(this) );
2144 // Recursively connect children
2147 ActorConstIter endIter = mChildren->end();
2148 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2150 Actor& actor = GetImplementation( *iter );
2151 actor.RecursiveConnectToStage( stage, connectionList );
2157 * This method is called when the Actor is connected to the Stage.
2158 * The parent must have added its Node to the scene-graph.
2159 * The child must connect its Node to the parent's Node.
2160 * This is resursive; the child calls ConnectToStage() for its children.
2162 void Actor::ConnectToSceneGraph(int index)
2164 DALI_ASSERT_DEBUG( mNode != NULL);
2165 DALI_ASSERT_DEBUG( mParent != NULL);
2166 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2170 // Reparent Node in next Update
2171 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2174 // Notify attachment
2177 mAttachment->Connect();
2180 #ifdef DYNAMICS_SUPPORT
2182 if( NULL != mDynamicsData )
2188 // Notification for ProxyObject::Observers
2192 void Actor::NotifyStageConnection()
2194 // Actors can be removed (in a callback), before the on-stage stage is reported.
2195 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2196 if ( OnStage() && !mOnStageSignalled )
2198 // Notification for external (CustomActor) derived classes
2199 OnStageConnectionExternal();
2201 if ( !mOnStageSignalV2.Empty() )
2203 Dali::Actor handle( this );
2204 mOnStageSignalV2.Emit( handle );
2207 // Guard against Remove during callbacks
2210 mOnStageSignalled = true; // signal required next time Actor is removed
2215 void Actor::DisconnectFromStage()
2217 // This container is used instead of walking the Actor hierachy.
2218 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2219 ActorContainer disconnectionList;
2221 // This stage is atomic i.e. not interrupted by user callbacks
2222 RecursiveDisconnectFromStage( disconnectionList );
2224 // Notify applications about the newly disconnected actors.
2225 const ActorIter endIter = disconnectionList.end();
2226 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2228 Actor& actor = GetImplementation(*iter);
2229 actor.NotifyStageDisconnection();
2233 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2235 DALI_ASSERT_ALWAYS( OnStage() );
2237 // Recursively disconnect children
2240 ActorConstIter endIter = mChildren->end();
2241 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2243 Actor& actor = GetImplementation( *iter );
2244 actor.RecursiveDisconnectFromStage( disconnectionList );
2248 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2249 disconnectionList.push_back( Dali::Actor(this) );
2251 // Notification for internal derived classes
2252 OnStageDisconnectionInternal();
2254 DisconnectFromSceneGraph();
2260 * This method is called by an actor or its parent, before a node removal message is sent.
2261 * This is recursive; the child calls DisconnectFromStage() for its children.
2263 void Actor::DisconnectFromSceneGraph()
2265 // Notification for ProxyObject::Observers
2266 OnSceneObjectRemove();
2268 // Notify attachment
2271 mAttachment->Disconnect();
2274 #ifdef DYNAMICS_SUPPORT
2276 if( NULL != mDynamicsData )
2278 DisconnectDynamics();
2283 void Actor::NotifyStageDisconnection()
2285 // Actors can be added (in a callback), before the off-stage state is reported.
2286 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2287 // only do this step if there is a stage, i.e. Core is not being shut down
2288 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2290 // Notification for external (CustomeActor) derived classes
2291 OnStageDisconnectionExternal();
2293 if( !mOffStageSignalV2.Empty() )
2295 Dali::Actor handle( this );
2296 mOffStageSignalV2.Emit( handle );
2299 // Guard against Add during callbacks
2302 mOnStageSignalled = false; // signal required next time Actor is added
2307 bool Actor::IsNodeConnected() const
2309 bool connected( false );
2314 if( mNode->IsRoot() || mNode->GetParent() )
2323 bool Actor::IsSceneObjectRemovable() const
2328 unsigned int Actor::GetDefaultPropertyCount() const
2330 return DEFAULT_PROPERTY_COUNT;
2333 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2335 indices.reserve( DEFAULT_PROPERTY_COUNT );
2337 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2339 indices.push_back( i );
2343 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2345 if( index < DEFAULT_PROPERTY_COUNT )
2347 return DEFAULT_PROPERTY_DETAILS[index].name;
2355 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2357 Property::Index index = Property::INVALID_INDEX;
2359 // Look for name in default properties
2360 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2362 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2363 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2373 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2375 if( index < DEFAULT_PROPERTY_COUNT )
2377 return DEFAULT_PROPERTY_DETAILS[index].writable;
2385 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2387 if( index < DEFAULT_PROPERTY_COUNT )
2389 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2397 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2399 if( index < DEFAULT_PROPERTY_COUNT )
2401 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2409 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2411 if( index < DEFAULT_PROPERTY_COUNT )
2413 return DEFAULT_PROPERTY_DETAILS[index].type;
2417 // index out of range...return Property::NONE
2418 return Property::NONE;
2422 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2426 case Dali::Actor::PARENT_ORIGIN:
2428 SetParentOrigin( property.Get<Vector3>() );
2432 case Dali::Actor::PARENT_ORIGIN_X:
2434 SetParentOriginX( property.Get<float>() );
2438 case Dali::Actor::PARENT_ORIGIN_Y:
2440 SetParentOriginY( property.Get<float>() );
2444 case Dali::Actor::PARENT_ORIGIN_Z:
2446 SetParentOriginZ( property.Get<float>() );
2450 case Dali::Actor::ANCHOR_POINT:
2452 SetAnchorPoint( property.Get<Vector3>() );
2456 case Dali::Actor::ANCHOR_POINT_X:
2458 SetAnchorPointX( property.Get<float>() );
2462 case Dali::Actor::ANCHOR_POINT_Y:
2464 SetAnchorPointY( property.Get<float>() );
2468 case Dali::Actor::ANCHOR_POINT_Z:
2470 SetAnchorPointZ( property.Get<float>() );
2474 case Dali::Actor::SIZE:
2476 SetSize( property.Get<Vector3>() );
2480 case Dali::Actor::SIZE_WIDTH:
2482 SetWidth( property.Get<float>() );
2486 case Dali::Actor::SIZE_HEIGHT:
2488 SetHeight( property.Get<float>() );
2492 case Dali::Actor::SIZE_DEPTH:
2494 SetDepth( property.Get<float>() );
2498 case Dali::Actor::POSITION:
2500 SetPosition( property.Get<Vector3>() );
2504 case Dali::Actor::POSITION_X:
2506 SetX( property.Get<float>() );
2510 case Dali::Actor::POSITION_Y:
2512 SetY( property.Get<float>() );
2516 case Dali::Actor::POSITION_Z:
2518 SetZ( property.Get<float>() );
2522 case Dali::Actor::ROTATION:
2524 SetRotation( property.Get<Quaternion>() );
2528 case Dali::Actor::SCALE:
2530 SetScale( property.Get<Vector3>() );
2534 case Dali::Actor::SCALE_X:
2536 SetScaleX( property.Get<float>() );
2540 case Dali::Actor::SCALE_Y:
2542 SetScaleY( property.Get<float>() );
2546 case Dali::Actor::SCALE_Z:
2548 SetScaleZ( property.Get<float>() );
2552 case Dali::Actor::VISIBLE:
2554 SetVisible( property.Get<bool>() );
2558 case Dali::Actor::COLOR:
2560 SetColor( property.Get<Vector4>() );
2564 case Dali::Actor::COLOR_RED:
2566 SetColorRed( property.Get<float>() );
2570 case Dali::Actor::COLOR_GREEN:
2572 SetColorGreen( property.Get<float>() );
2576 case Dali::Actor::COLOR_BLUE:
2578 SetColorBlue( property.Get<float>() );
2582 case Dali::Actor::COLOR_ALPHA:
2584 SetOpacity( property.Get<float>() );
2588 case Dali::Actor::NAME:
2590 SetName( property.Get<std::string>() );
2594 case Dali::Actor::SENSITIVE:
2596 SetSensitive( property.Get<bool>() );
2600 case Dali::Actor::LEAVE_REQUIRED:
2602 SetLeaveRequired( property.Get<bool>() );
2606 case Dali::Actor::INHERIT_ROTATION:
2608 SetInheritRotation( property.Get<bool>() );
2612 case Dali::Actor::INHERIT_SCALE:
2614 SetInheritScale( property.Get<bool>() );
2618 case Dali::Actor::COLOR_MODE:
2620 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2624 case Dali::Actor::POSITION_INHERITANCE:
2626 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2630 case Dali::Actor::DRAW_MODE:
2632 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2638 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2644 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2646 // TODO: This should be deprecated
2647 OnPropertySet(index, value);
2649 if(entry.IsAnimatable())
2651 switch ( entry.type )
2653 case Property::BOOLEAN:
2655 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( 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<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2664 case Property::FLOAT:
2666 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( 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<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2675 case Property::INTEGER:
2677 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( 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<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2686 case Property::VECTOR2:
2688 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( 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<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2697 case Property::VECTOR3:
2699 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2700 DALI_ASSERT_DEBUG( NULL != property );
2702 // property is being used in a separate thread; queue a message to set the property
2703 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2708 case Property::VECTOR4:
2710 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2711 DALI_ASSERT_DEBUG( NULL != property );
2713 // property is being used in a separate thread; queue a message to set the property
2714 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2719 case Property::ROTATION:
2721 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2722 DALI_ASSERT_DEBUG( NULL != property );
2724 // property is being used in a separate thread; queue a message to set the property
2725 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2730 case Property::MATRIX:
2732 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2733 DALI_ASSERT_DEBUG( NULL != property );
2735 // property is being used in a separate thread; queue a message to set the property
2736 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2741 case Property::MATRIX3:
2743 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2744 DALI_ASSERT_DEBUG( NULL != property );
2746 // property is being used in a separate thread; queue a message to set the property
2747 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2754 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2761 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2763 Property::Value value;
2767 case Dali::Actor::PARENT_ORIGIN:
2769 value = GetCurrentParentOrigin();
2773 case Dali::Actor::PARENT_ORIGIN_X:
2775 value = GetCurrentParentOrigin().x;
2779 case Dali::Actor::PARENT_ORIGIN_Y:
2781 value = GetCurrentParentOrigin().y;
2785 case Dali::Actor::PARENT_ORIGIN_Z:
2787 value = GetCurrentParentOrigin().z;
2791 case Dali::Actor::ANCHOR_POINT:
2793 value = GetCurrentAnchorPoint();
2797 case Dali::Actor::ANCHOR_POINT_X:
2799 value = GetCurrentAnchorPoint().x;
2803 case Dali::Actor::ANCHOR_POINT_Y:
2805 value = GetCurrentAnchorPoint().y;
2809 case Dali::Actor::ANCHOR_POINT_Z:
2811 value = GetCurrentAnchorPoint().z;
2815 case Dali::Actor::SIZE:
2817 value = GetCurrentSize();
2821 case Dali::Actor::SIZE_WIDTH:
2823 value = GetCurrentSize().width;
2827 case Dali::Actor::SIZE_HEIGHT:
2829 value = GetCurrentSize().height;
2833 case Dali::Actor::SIZE_DEPTH:
2835 value = GetCurrentSize().depth;
2839 case Dali::Actor::POSITION:
2841 value = GetCurrentPosition();
2845 case Dali::Actor::POSITION_X:
2847 value = GetCurrentPosition().x;
2851 case Dali::Actor::POSITION_Y:
2853 value = GetCurrentPosition().y;
2857 case Dali::Actor::POSITION_Z:
2859 value = GetCurrentPosition().z;
2863 case Dali::Actor::WORLD_POSITION:
2865 value = GetCurrentWorldPosition();
2869 case Dali::Actor::WORLD_POSITION_X:
2871 value = GetCurrentWorldPosition().x;
2875 case Dali::Actor::WORLD_POSITION_Y:
2877 value = GetCurrentWorldPosition().y;
2881 case Dali::Actor::WORLD_POSITION_Z:
2883 value = GetCurrentWorldPosition().z;
2887 case Dali::Actor::ROTATION:
2889 value = GetCurrentRotation();
2893 case Dali::Actor::WORLD_ROTATION:
2895 value = GetCurrentWorldRotation();
2899 case Dali::Actor::SCALE:
2901 value = GetCurrentScale();
2905 case Dali::Actor::SCALE_X:
2907 value = GetCurrentScale().x;
2911 case Dali::Actor::SCALE_Y:
2913 value = GetCurrentScale().y;
2917 case Dali::Actor::SCALE_Z:
2919 value = GetCurrentScale().z;
2923 case Dali::Actor::WORLD_SCALE:
2925 value = GetCurrentWorldScale();
2929 case Dali::Actor::VISIBLE:
2931 value = IsVisible();
2935 case Dali::Actor::COLOR:
2937 value = GetCurrentColor();
2941 case Dali::Actor::COLOR_RED:
2943 value = GetCurrentColor().r;
2947 case Dali::Actor::COLOR_GREEN:
2949 value = GetCurrentColor().g;
2953 case Dali::Actor::COLOR_BLUE:
2955 value = GetCurrentColor().b;
2959 case Dali::Actor::COLOR_ALPHA:
2961 value = GetCurrentColor().a;
2965 case Dali::Actor::WORLD_COLOR:
2967 value = GetCurrentWorldColor();
2971 case Dali::Actor::WORLD_MATRIX:
2973 value = GetCurrentWorldMatrix();
2977 case Dali::Actor::NAME:
2983 case Dali::Actor::SENSITIVE:
2985 value = IsSensitive();
2989 case Dali::Actor::LEAVE_REQUIRED:
2991 value = GetLeaveRequired();
2995 case Dali::Actor::INHERIT_ROTATION:
2997 value = IsRotationInherited();
3001 case Dali::Actor::INHERIT_SCALE:
3003 value = IsScaleInherited();
3007 case Dali::Actor::COLOR_MODE:
3009 value = Scripting::GetColorMode( GetColorMode() );
3013 case Dali::Actor::POSITION_INHERITANCE:
3015 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3019 case Dali::Actor::DRAW_MODE:
3021 value = Scripting::GetDrawMode( GetDrawMode() );
3027 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3035 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3039 // mNode is being used in a separate thread; queue a message to add the property
3040 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3044 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3046 // This method should only return an object connected to the scene-graph
3047 return OnStage() ? mNode : NULL;
3050 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3052 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3054 const PropertyBase* property( NULL );
3056 // This method should only return a property of an object connected to the scene-graph
3062 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3064 CustomProperty* custom = FindCustomProperty( index );
3065 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3067 property = custom->GetSceneGraphProperty();
3069 else if( NULL != mNode )
3073 case Dali::Actor::SIZE:
3074 property = &mNode->mSize;
3077 case Dali::Actor::SIZE_WIDTH:
3078 property = &mNode->mSize;
3081 case Dali::Actor::SIZE_HEIGHT:
3082 property = &mNode->mSize;
3085 case Dali::Actor::SIZE_DEPTH:
3086 property = &mNode->mSize;
3089 case Dali::Actor::POSITION:
3090 property = &mNode->mPosition;
3093 case Dali::Actor::POSITION_X:
3094 property = &mNode->mPosition;
3097 case Dali::Actor::POSITION_Y:
3098 property = &mNode->mPosition;
3101 case Dali::Actor::POSITION_Z:
3102 property = &mNode->mPosition;
3105 case Dali::Actor::ROTATION:
3106 property = &mNode->mRotation;
3109 case Dali::Actor::SCALE:
3110 property = &mNode->mScale;
3113 case Dali::Actor::SCALE_X:
3114 property = &mNode->mScale;
3117 case Dali::Actor::SCALE_Y:
3118 property = &mNode->mScale;
3121 case Dali::Actor::SCALE_Z:
3122 property = &mNode->mScale;
3125 case Dali::Actor::VISIBLE:
3126 property = &mNode->mVisible;
3129 case Dali::Actor::COLOR:
3130 property = &mNode->mColor;
3133 case Dali::Actor::COLOR_RED:
3134 property = &mNode->mColor;
3137 case Dali::Actor::COLOR_GREEN:
3138 property = &mNode->mColor;
3141 case Dali::Actor::COLOR_BLUE:
3142 property = &mNode->mColor;
3145 case Dali::Actor::COLOR_ALPHA:
3146 property = &mNode->mColor;
3157 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3159 const PropertyInputImpl* property( NULL );
3161 // This method should only return a property of an object connected to the scene-graph
3167 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3169 CustomProperty* custom = FindCustomProperty( index );
3170 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3171 property = custom->GetSceneGraphProperty();
3173 else if( NULL != mNode )
3177 case Dali::Actor::PARENT_ORIGIN:
3178 property = &mNode->mParentOrigin;
3181 case Dali::Actor::PARENT_ORIGIN_X:
3182 property = &mNode->mParentOrigin;
3185 case Dali::Actor::PARENT_ORIGIN_Y:
3186 property = &mNode->mParentOrigin;
3189 case Dali::Actor::PARENT_ORIGIN_Z:
3190 property = &mNode->mParentOrigin;
3193 case Dali::Actor::ANCHOR_POINT:
3194 property = &mNode->mAnchorPoint;
3197 case Dali::Actor::ANCHOR_POINT_X:
3198 property = &mNode->mAnchorPoint;
3201 case Dali::Actor::ANCHOR_POINT_Y:
3202 property = &mNode->mAnchorPoint;
3205 case Dali::Actor::ANCHOR_POINT_Z:
3206 property = &mNode->mAnchorPoint;
3209 case Dali::Actor::SIZE:
3210 property = &mNode->mSize;
3213 case Dali::Actor::SIZE_WIDTH:
3214 property = &mNode->mSize;
3217 case Dali::Actor::SIZE_HEIGHT:
3218 property = &mNode->mSize;
3221 case Dali::Actor::SIZE_DEPTH:
3222 property = &mNode->mSize;
3225 case Dali::Actor::POSITION:
3226 property = &mNode->mPosition;
3229 case Dali::Actor::POSITION_X:
3230 property = &mNode->mPosition;
3233 case Dali::Actor::POSITION_Y:
3234 property = &mNode->mPosition;
3237 case Dali::Actor::POSITION_Z:
3238 property = &mNode->mPosition;
3241 case Dali::Actor::WORLD_POSITION:
3242 property = &mNode->mWorldPosition;
3245 case Dali::Actor::WORLD_POSITION_X:
3246 property = &mNode->mWorldPosition;
3249 case Dali::Actor::WORLD_POSITION_Y:
3250 property = &mNode->mWorldPosition;
3253 case Dali::Actor::WORLD_POSITION_Z:
3254 property = &mNode->mWorldPosition;
3257 case Dali::Actor::ROTATION:
3258 property = &mNode->mRotation;
3261 case Dali::Actor::WORLD_ROTATION:
3262 property = &mNode->mWorldRotation;
3265 case Dali::Actor::SCALE:
3266 property = &mNode->mScale;
3269 case Dali::Actor::SCALE_X:
3270 property = &mNode->mScale;
3273 case Dali::Actor::SCALE_Y:
3274 property = &mNode->mScale;
3277 case Dali::Actor::SCALE_Z:
3278 property = &mNode->mScale;
3281 case Dali::Actor::WORLD_SCALE:
3282 property = &mNode->mWorldScale;
3285 case Dali::Actor::VISIBLE:
3286 property = &mNode->mVisible;
3289 case Dali::Actor::COLOR:
3290 property = &mNode->mColor;
3293 case Dali::Actor::COLOR_RED:
3294 property = &mNode->mColor;
3297 case Dali::Actor::COLOR_GREEN:
3298 property = &mNode->mColor;
3301 case Dali::Actor::COLOR_BLUE:
3302 property = &mNode->mColor;
3305 case Dali::Actor::COLOR_ALPHA:
3306 property = &mNode->mColor;
3309 case Dali::Actor::WORLD_COLOR:
3310 property = &mNode->mWorldColor;
3313 case Dali::Actor::WORLD_MATRIX:
3314 property = &mNode->mWorldMatrix;
3325 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3327 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3331 case Dali::Actor::PARENT_ORIGIN_X:
3332 case Dali::Actor::ANCHOR_POINT_X:
3333 case Dali::Actor::SIZE_WIDTH:
3334 case Dali::Actor::POSITION_X:
3335 case Dali::Actor::SCALE_X:
3336 case Dali::Actor::COLOR_RED:
3337 case Dali::Actor::WORLD_POSITION_X:
3343 case Dali::Actor::PARENT_ORIGIN_Y:
3344 case Dali::Actor::ANCHOR_POINT_Y:
3345 case Dali::Actor::SIZE_HEIGHT:
3346 case Dali::Actor::POSITION_Y:
3347 case Dali::Actor::SCALE_Y:
3348 case Dali::Actor::COLOR_GREEN:
3349 case Dali::Actor::WORLD_POSITION_Y:
3355 case Dali::Actor::PARENT_ORIGIN_Z:
3356 case Dali::Actor::ANCHOR_POINT_Z:
3357 case Dali::Actor::SIZE_DEPTH:
3358 case Dali::Actor::POSITION_Z:
3359 case Dali::Actor::SCALE_Z:
3360 case Dali::Actor::COLOR_BLUE:
3361 case Dali::Actor::WORLD_POSITION_Z:
3367 case Dali::Actor::COLOR_ALPHA:
3380 return componentIndex;
3383 void Actor::SetParent(Actor* parent, int index)
3387 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3391 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3394 StagePtr stage = parent->mStage;
3396 // Instruct each actor to create a corresponding node in the scene graph
3397 ConnectToStage(*stage, index);
3400 else // parent being set to NULL
3402 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3406 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3409 DALI_ASSERT_ALWAYS(mNode != NULL);
3413 // Disconnect the Node & its children from the scene-graph.
3414 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3417 // Instruct each actor to discard pointers to the scene-graph
3418 DisconnectFromStage();
3423 SceneGraph::Node* Actor::CreateNode() const
3428 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3431 Actor* actor = dynamic_cast<Actor*>(object);
3435 if(Dali::Actor::ACTION_SHOW == actionName)
3437 actor->SetVisible(true);
3440 else if(Dali::Actor::ACTION_HIDE == actionName)
3442 actor->SetVisible(false);
3450 } // namespace Internal