2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/common/constants.h>
29 #include <dali/public-api/math/vector2.h>
30 #include <dali/public-api/math/vector3.h>
31 #include <dali/public-api/math/radian.h>
32 #include <dali/public-api/object/type-registry.h>
33 #include <dali/public-api/scripting/scripting.h>
35 #include <dali/internal/common/internal-constants.h>
36 #include <dali/internal/event/render-tasks/render-task-impl.h>
37 #include <dali/internal/event/actors/camera-actor-impl.h>
38 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
39 #include <dali/internal/event/common/property-index-ranges.h>
40 #include <dali/internal/event/common/stage-impl.h>
41 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
42 #include <dali/internal/event/animation/constraint-impl.h>
43 #include <dali/internal/event/common/projection.h>
44 #include <dali/internal/update/common/animatable-property.h>
45 #include <dali/internal/update/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
59 using Dali::Internal::SceneGraph::Node;
60 using Dali::Internal::SceneGraph::AnimatableProperty;
61 using Dali::Internal::SceneGraph::PropertyBase;
66 const Property::Index Actor::PARENT_ORIGIN = 0;
67 const Property::Index Actor::PARENT_ORIGIN_X = 1;
68 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
69 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
70 const Property::Index Actor::ANCHOR_POINT = 4;
71 const Property::Index Actor::ANCHOR_POINT_X = 5;
72 const Property::Index Actor::ANCHOR_POINT_Y = 6;
73 const Property::Index Actor::ANCHOR_POINT_Z = 7;
74 const Property::Index Actor::SIZE = 8;
75 const Property::Index Actor::SIZE_WIDTH = 9;
76 const Property::Index Actor::SIZE_HEIGHT = 10;
77 const Property::Index Actor::SIZE_DEPTH = 11;
78 const Property::Index Actor::POSITION = 12;
79 const Property::Index Actor::POSITION_X = 13;
80 const Property::Index Actor::POSITION_Y = 14;
81 const Property::Index Actor::POSITION_Z = 15;
82 const Property::Index Actor::WORLD_POSITION = 16;
83 const Property::Index Actor::WORLD_POSITION_X = 17;
84 const Property::Index Actor::WORLD_POSITION_Y = 18;
85 const Property::Index Actor::WORLD_POSITION_Z = 19;
86 const Property::Index Actor::ROTATION = 20;
87 const Property::Index Actor::WORLD_ROTATION = 21;
88 const Property::Index Actor::SCALE = 22;
89 const Property::Index Actor::SCALE_X = 23;
90 const Property::Index Actor::SCALE_Y = 24;
91 const Property::Index Actor::SCALE_Z = 25;
92 const Property::Index Actor::WORLD_SCALE = 26;
93 const Property::Index Actor::VISIBLE = 27;
94 const Property::Index Actor::COLOR = 28;
95 const Property::Index Actor::COLOR_RED = 29;
96 const Property::Index Actor::COLOR_GREEN = 30;
97 const Property::Index Actor::COLOR_BLUE = 31;
98 const Property::Index Actor::COLOR_ALPHA = 32;
99 const Property::Index Actor::WORLD_COLOR = 33;
100 const Property::Index Actor::WORLD_MATRIX = 34;
101 const Property::Index Actor::NAME = 35;
102 const Property::Index Actor::SENSITIVE = 36;
103 const Property::Index Actor::LEAVE_REQUIRED = 37;
104 const Property::Index Actor::INHERIT_ROTATION = 38;
105 const Property::Index Actor::INHERIT_SCALE = 39;
106 const Property::Index Actor::COLOR_MODE = 40;
107 const Property::Index Actor::POSITION_INHERITANCE = 41;
108 const Property::Index Actor::DRAW_MODE = 42;
110 namespace // unnamed namespace
114 * We want to discourage the use of property strings (minimize string comparisons),
115 * particularly for the default properties.
117 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
119 // Name Type writable animatable constraint-input
120 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
121 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
122 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
123 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
124 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
125 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
126 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
127 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
128 { "size", Property::VECTOR3, true, true, true }, // SIZE
129 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
130 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
131 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
132 { "position", Property::VECTOR3, true, true, true }, // POSITION
133 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
134 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
135 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
136 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
137 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
138 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
139 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
140 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
141 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
142 { "scale", Property::VECTOR3, true, true, true }, // SCALE
143 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
144 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
145 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
146 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
147 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
148 { "color", Property::VECTOR4, true, true, true }, // COLOR
149 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
150 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
151 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
152 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
153 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
154 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
155 { "name", Property::STRING, true, false, false }, // NAME
156 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
157 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
158 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
159 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
160 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
161 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
162 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
164 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
166 } // unnamed namespace
171 unsigned int Actor::mActorCounter = 0;
172 ActorContainer Actor::mNullChildren;
174 #ifdef DYNAMICS_SUPPORT
176 // Encapsulate actor related dynamics data
179 DynamicsData( Actor* slotOwner )
180 : slotDelegate( slotOwner )
184 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
185 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
187 DynamicsBodyPtr body;
188 JointContainer joints;
189 ReferencedJointContainer referencedJoints;
191 SlotDelegate< Actor > slotDelegate;
194 #endif // DYNAMICS_SUPPORT
199 using namespace Dali;
201 BaseHandle CreateActor()
203 return Dali::Actor::New();
206 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
208 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
209 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_HOVERED, &Actor::DoConnectSignal);
210 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
211 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
212 SignalConnectorType signalConnector5(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
214 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
215 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
219 ActorPtr Actor::New()
221 ActorPtr actor( new Actor( BASIC ) );
223 // Second-phase construction
229 const std::string& Actor::GetName() const
234 void Actor::SetName(const std::string& name)
240 // ATTENTION: string for debug purposes is not thread safe.
241 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
245 unsigned int Actor::GetId() const
250 void Actor::Attach( ActorAttachment& attachment )
252 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
256 attachment.Connect();
259 mAttachment = ActorAttachmentPtr(&attachment);
262 ActorAttachmentPtr Actor::GetAttachment()
267 bool Actor::OnStage() const
272 Dali::Layer Actor::GetLayer()
276 // Short-circuit for Layer derived actors
279 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
282 // Find the immediate Layer parent
283 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
285 if( parent->IsLayer() )
287 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
294 void Actor::Add(Actor& child)
296 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
297 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
301 mChildren = new ActorContainer;
304 Actor* const oldParent( child.mParent );
306 // child might already be ours
307 if( this != oldParent )
309 // if we already have parent, unparent us first
312 oldParent->Remove( child ); // This causes OnChildRemove callback
315 // Guard against Add() during previous OnChildRemove callback
316 if ( !child.mParent )
318 // Do this first, since user callbacks from within SetParent() may need to remove child
319 mChildren->push_back(Dali::Actor(&child));
321 // SetParent asserts that child can be added
322 child.SetParent(this);
324 // Notification for derived classes
330 void Actor::Insert(unsigned int index, Actor& child)
332 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
333 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
337 mChildren = new ActorContainer;
340 Actor* const oldParent( child.mParent );
342 // since an explicit position has been given, always insert, even if already a child
345 oldParent->Remove( child ); // This causes OnChildRemove callback
348 // Guard against Add() during previous OnChildRemove callback
349 if ( !child.mParent )
351 // Do this first, since user callbacks from within SetParent() may need to remove child
352 if (index < GetChildCount())
354 ActorIter it = mChildren->begin();
355 std::advance(it, index);
356 mChildren->insert(it, Dali::Actor(&child));
360 mChildren->push_back(Dali::Actor(&child));
362 // SetParent asserts that child can be added
363 child.SetParent(this, index);
365 // Notification for derived classes
370 void Actor::Remove(Actor& child)
372 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
382 // Find the child in mChildren, and unparent it
383 ActorIter end = mChildren->end();
384 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
386 Actor& actor = GetImplementation(*iter);
388 if( &actor == &child )
390 // Keep handle for OnChildRemove notification
391 removed = Dali::Actor( &actor );
393 // Do this first, since user callbacks from within SetParent() may need to add the child
394 mChildren->erase(iter);
396 DALI_ASSERT_DEBUG( actor.GetParent() == this );
397 actor.SetParent( NULL );
405 // Notification for derived classes
406 OnChildRemove( GetImplementation(removed) );
410 void Actor::Unparent()
414 mParent->Remove( *this );
418 unsigned int Actor::GetChildCount() const
420 return ( NULL != mChildren ) ? mChildren->size() : 0;
423 Dali::Actor Actor::GetChildAt(unsigned int index) const
425 DALI_ASSERT_ALWAYS( index < GetChildCount() );
427 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
430 ActorContainer Actor::GetChildren()
432 if( NULL != mChildren )
437 // return copy of mNullChildren
438 return mNullChildren;
441 const ActorContainer& Actor::GetChildren() const
443 if( NULL != mChildren )
448 // return const reference to mNullChildren
449 return mNullChildren;
452 ActorPtr Actor::FindChildByName(const std::string& actorName)
455 if (actorName == mName)
461 ActorIter end = mChildren->end();
462 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
464 child = GetImplementation(*iter).FindChildByName(actorName);
475 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
477 Dali::Actor child = DoGetChildByAlias(actorAlias);
479 // If not found then search by name.
482 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
485 child = Dali::Actor(child_ptr.Get());
492 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
494 Dali::Actor child = GetChildByAlias(actorAlias);
496 if (!child && mChildren )
498 ActorIter end = mChildren->end();
499 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
501 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
513 ActorPtr Actor::FindChildById(const unsigned int id)
522 ActorIter end = mChildren->end();
523 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
525 child = GetImplementation(*iter).FindChildById(id);
536 void Actor::SetParentOrigin( const Vector3& origin )
540 // mNode is being used in a separate thread; queue a message to set the value & base value
541 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
544 // Cache for event-thread access
547 // not allocated, check if different from default
548 if( ParentOrigin::DEFAULT != origin )
550 mParentOrigin = new Vector3( origin );
555 // check if different from current costs more than just set
556 *mParentOrigin = origin;
560 void Actor::SetParentOriginX( float x )
562 const Vector3& current = GetCurrentParentOrigin();
564 SetParentOrigin( Vector3( x, current.y, current.z ) );
567 void Actor::SetParentOriginY( float y )
569 const Vector3& current = GetCurrentParentOrigin();
571 SetParentOrigin( Vector3( current.x, y, current.z ) );
574 void Actor::SetParentOriginZ( float z )
576 const Vector3& current = GetCurrentParentOrigin();
578 SetParentOrigin( Vector3( current.x, current.y, z ) );
581 const Vector3& Actor::GetCurrentParentOrigin() const
583 // Cached for event-thread access
584 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
587 void Actor::SetAnchorPoint(const Vector3& anchor)
591 // mNode is being used in a separate thread; queue a message to set the value & base value
592 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
595 // Cache for event-thread access
598 // not allocated, check if different from default
599 if( AnchorPoint::DEFAULT != anchor )
601 mAnchorPoint = new Vector3( anchor );
606 // check if different from current costs more than just set
607 *mAnchorPoint = anchor;
611 void Actor::SetAnchorPointX( float x )
613 const Vector3& current = GetCurrentAnchorPoint();
615 SetAnchorPoint( Vector3( x, current.y, current.z ) );
618 void Actor::SetAnchorPointY( float y )
620 const Vector3& current = GetCurrentAnchorPoint();
622 SetAnchorPoint( Vector3( current.x, y, current.z ) );
625 void Actor::SetAnchorPointZ( float z )
627 const Vector3& current = GetCurrentAnchorPoint();
629 SetAnchorPoint( Vector3( current.x, current.y, z ) );
632 const Vector3& Actor::GetCurrentAnchorPoint() const
634 // Cached for event-thread access
635 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
638 void Actor::SetPosition(float x, float y)
640 SetPosition(Vector3(x, y, 0.0f));
643 void Actor::SetPosition(float x, float y, float z)
645 SetPosition(Vector3(x, y, z));
648 void Actor::SetPosition(const Vector3& position)
652 // mNode is being used in a separate thread; queue a message to set the value & base value
653 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
657 void Actor::SetX(float x)
661 // mNode is being used in a separate thread; queue a message to set the value & base value
662 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
666 void Actor::SetY(float y)
670 // mNode is being used in a separate thread; queue a message to set the value & base value
671 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
675 void Actor::SetZ(float z)
679 // mNode is being used in a separate thread; queue a message to set the value & base value
680 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
684 void Actor::MoveBy(const Vector3& distance)
688 // mNode is being used in a separate thread; queue a message to set the value & base value
689 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
693 const Vector3& Actor::GetCurrentPosition() const
697 // mNode is being used in a separate thread; copy the value from the previous update
698 return mNode->GetPosition(mStage->GetEventBufferIndex());
701 return Vector3::ZERO;
704 const Vector3& Actor::GetCurrentWorldPosition() const
708 // mNode is being used in a separate thread; copy the value from the previous update
709 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
712 return Vector3::ZERO;
715 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
717 // this flag is not animatable so keep the value
718 mPositionInheritanceMode = mode;
721 // mNode is being used in a separate thread; queue a message to set the value
722 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
726 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
728 // Cached for event-thread access
729 return mPositionInheritanceMode;
732 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
734 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
735 normalizedAxis.Normalize();
737 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
739 SetRotation(rotation);
742 void Actor::SetRotation(const Quaternion& rotation)
746 // mNode is being used in a separate thread; queue a message to set the value & base value
747 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
751 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
755 // mNode is being used in a separate thread; queue a message to set the value & base value
756 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
760 void Actor::RotateBy(const Quaternion& relativeRotation)
764 // mNode is being used in a separate thread; queue a message to set the value & base value
765 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
769 const Quaternion& Actor::GetCurrentRotation() const
773 // mNode is being used in a separate thread; copy the value from the previous update
774 return mNode->GetRotation(mStage->GetEventBufferIndex());
777 return Quaternion::IDENTITY;
780 const Quaternion& Actor::GetCurrentWorldRotation() const
784 // mNode is being used in a separate thread; copy the value from the previous update
785 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
788 return Quaternion::IDENTITY;
791 void Actor::SetScale(float scale)
793 SetScale(Vector3(scale, scale, scale));
796 void Actor::SetScale(float x, float y, float z)
798 SetScale(Vector3(x, y, z));
801 void Actor::SetScale(const Vector3& scale)
805 // mNode is being used in a separate thread; queue a message to set the value & base value
806 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
810 void Actor::SetScaleX( float x )
814 // mNode is being used in a separate thread; queue a message to set the value & base value
815 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
819 void Actor::SetScaleY( float y )
823 // mNode is being used in a separate thread; queue a message to set the value & base value
824 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
828 void Actor::SetScaleZ( float z )
832 // mNode is being used in a separate thread; queue a message to set the value & base value
833 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
837 void Actor::SetInitialVolume(const Vector3& volume)
841 // mNode is being used in a separate thread; queue a message to set the value
842 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
846 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
850 // mNode is being used in a separate thread; queue a message to set the value
851 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
855 bool Actor::GetTransmitGeometryScaling() const
859 // mNode is being used in a separate thread; copy the value from the previous update
860 return mNode->GetTransmitGeometryScaling();
866 void Actor::ScaleBy(const Vector3& relativeScale)
870 // mNode is being used in a separate thread; queue a message to set the value & base value
871 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
875 const Vector3& Actor::GetCurrentScale() const
879 // mNode is being used in a separate thread; copy the value from the previous update
880 return mNode->GetScale(mStage->GetEventBufferIndex());
886 const Vector3& Actor::GetCurrentWorldScale() const
890 // mNode is being used in a separate thread; copy the value from the previous update
891 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
897 void Actor::SetInheritScale( bool inherit )
899 // non animateable so keep local copy
900 mInheritScale = inherit;
903 // mNode is being used in a separate thread; queue a message to set the value
904 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
908 bool Actor::IsScaleInherited() const
910 return mInheritScale;
913 Matrix Actor::GetCurrentWorldMatrix() const
917 // World matrix is no longer updated unless there is something observing the node.
918 // Need to calculate it from node's world position, rotation and scale:
919 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
920 Matrix worldMatrix(false);
921 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
922 mNode->GetWorldRotation( updateBufferIndex ),
923 mNode->GetWorldPosition( updateBufferIndex ) );
927 return Matrix::IDENTITY;
930 void Actor::SetVisible(bool visible)
934 // mNode is being used in a separate thread; queue a message to set the value & base value
935 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
939 bool Actor::IsVisible() const
943 // mNode is being used in a separate thread; copy the value from the previous update
944 return mNode->IsVisible( mStage->GetEventBufferIndex() );
950 void Actor::SetOpacity(float opacity)
954 // mNode is being used in a separate thread; queue a message to set the value & base value
955 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
959 void Actor::OpacityBy(float relativeOpacity)
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>::BakeWRelative, relativeOpacity );
968 float Actor::GetCurrentOpacity() const
972 // mNode is being used in a separate thread; copy the value from the previous update
973 return mNode->GetOpacity(mStage->GetEventBufferIndex());
979 const Vector4& Actor::GetCurrentWorldColor() const
983 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
989 void Actor::SetColor(const Vector4& color)
993 // mNode is being used in a separate thread; queue a message to set the value & base value
994 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
998 void Actor::SetColorRed( float red )
1002 // mNode is being used in a separate thread; queue a message to set the value & base value
1003 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1007 void Actor::SetColorGreen( float green )
1011 // mNode is being used in a separate thread; queue a message to set the value & base value
1012 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1016 void Actor::SetColorBlue( float blue )
1020 // mNode is being used in a separate thread; queue a message to set the value & base value
1021 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1025 void Actor::ColorBy(const Vector4& relativeColor)
1029 // mNode is being used in a separate thread; queue a message to set the value & base value
1030 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1034 const Vector4& Actor::GetCurrentColor() const
1038 // mNode is being used in a separate thread; copy the value from the previous update
1039 return mNode->GetColor(mStage->GetEventBufferIndex());
1042 return Color::WHITE;
1045 void Actor::SetInheritRotation(bool inherit)
1047 // non animateable so keep local copy
1048 mInheritRotation = inherit;
1051 // mNode is being used in a separate thread; queue a message to set the value
1052 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1056 bool Actor::IsRotationInherited() const
1058 return mInheritRotation;
1061 void Actor::SetColorMode(ColorMode colorMode)
1063 // non animateable so keep local copy
1064 mColorMode = colorMode;
1067 // mNode is being used in a separate thread; queue a message to set the value
1068 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1072 ColorMode Actor::GetColorMode() const
1074 // we have cached copy
1078 void Actor::SetSize(float width, float height)
1080 SetSize( Vector2( width, height ) );
1083 void Actor::SetSize(float width, float height, float depth)
1085 SetSize( Vector3( width, height, depth ) );
1088 void Actor::SetSize(const Vector2& size)
1090 SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
1093 float Actor::CalculateSizeZ( const Vector2& size ) const
1095 return std::min( size.width, size.height );
1098 void Actor::SetSize(const Vector3& size)
1104 // mNode is being used in a separate thread; queue a message to set the value & base value
1105 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
1107 // Notification for derived classes
1110 // Emit signal for application developer
1112 if( !mSetSizeSignal.Empty() )
1114 Dali::Actor handle( this );
1115 mSetSizeSignal.Emit( handle, mSize );
1120 void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
1124 // Notify deriving classes
1125 OnSizeAnimation( animation, targetSize );
1128 void Actor::SetWidth( float width )
1132 // mNode is being used in a separate thread; queue a message to set the value & base value
1133 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1137 void Actor::SetHeight( float height )
1141 // mNode is being used in a separate thread; queue a message to set the value & base value
1142 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1146 void Actor::SetDepth( float depth )
1150 // mNode is being used in a separate thread; queue a message to set the value & base value
1151 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1155 const Vector3& Actor::GetSize() const
1160 const Vector3& Actor::GetCurrentSize() const
1164 // mNode is being used in a separate thread; copy the value from the previous update
1165 return mNode->GetSize( mStage->GetEventBufferIndex() );
1168 return Vector3::ZERO;
1171 Vector3 Actor::GetNaturalSize() const
1173 // It is up to deriving classes to return the appropriate natural size
1174 return Vector3( 0.0f, 0.0f, 0.0f );
1178 #ifdef DYNAMICS_SUPPORT
1180 //--------------- Dynamics ---------------
1182 void Actor::DisableDynamics()
1184 if( NULL != mDynamicsData )
1186 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1188 // ensure dynamics object are disconnected from scene
1189 DisconnectDynamics();
1191 // delete joint owned by this actor
1192 while( !mDynamicsData->joints.empty() )
1194 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1197 // delete other joints referencing this actor
1198 while( !mDynamicsData->referencedJoints.empty() )
1200 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1201 ActorPtr jointOwner( joint->GetActor( true ) );
1204 jointOwner->RemoveDynamicsJoint( joint );
1208 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1211 // delete the DynamicsBody object
1212 mDynamicsData->body.Reset();
1214 // Discard Dynamics data structure
1215 delete mDynamicsData;
1216 mDynamicsData = NULL;
1220 DynamicsBodyPtr Actor::GetDynamicsBody() const
1222 DynamicsBodyPtr body;
1224 if( NULL != mDynamicsData )
1226 body = mDynamicsData->body;
1232 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1234 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1236 if( NULL == mDynamicsData )
1238 mDynamicsData = new DynamicsData( this );
1241 if( !mDynamicsData->body )
1243 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1247 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1250 if( mParent == world->GetRootActor().Get() )
1252 mDynamicsData->body->Connect(*mStage);
1258 return mDynamicsData->body;
1261 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1263 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1264 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1267 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1269 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1270 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1272 DynamicsJointPtr joint;
1274 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1278 if( NULL != mDynamicsData )
1280 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1282 if( mDynamicsData->joints.end() != it )
1284 // use existing joint
1290 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1291 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1295 bodyA = EnableDynamics( new DynamicsBodyConfig );
1300 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1303 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1304 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1306 if( OnStage() && attachedActor->OnStage() )
1308 joint->Connect(*mStage);
1311 attachedActor->ReferenceJoint( joint );
1313 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1314 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1321 const int Actor::GetNumberOfJoints() const
1323 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1326 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1328 DynamicsJointPtr joint;
1330 if( NULL != mDynamicsData )
1332 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1334 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1336 for( int i = 0; i < index; ++i )
1348 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1350 DynamicsJointPtr joint;
1352 if( NULL != mDynamicsData )
1354 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1356 if( mDynamicsData->joints.end() != it )
1358 // use existing joint
1366 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1368 if( NULL != mDynamicsData )
1370 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1371 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1373 for( ; it != endIt; ++it )
1375 if( it->second == joint.Get() )
1377 ActorPtr attachedActor( it->first );
1379 if( OnStage() && attachedActor && attachedActor->OnStage() )
1381 joint->Disconnect(*mStage);
1386 attachedActor->ReleaseJoint( joint );
1387 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1388 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1391 mDynamicsData->joints.erase(it);
1398 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1400 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1402 if( NULL != mDynamicsData )
1404 mDynamicsData->referencedJoints.push_back(joint);
1408 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1410 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1412 if( NULL != mDynamicsData )
1414 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1416 if( it != mDynamicsData->referencedJoints.end() )
1418 mDynamicsData->referencedJoints.erase( it );
1423 void Actor::SetDynamicsRoot(bool flag)
1425 if( mIsDynamicsRoot != flag )
1427 mIsDynamicsRoot = flag;
1429 if( OnStage() && mChildren )
1431 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1432 ActorIter end = mChildren->end();
1433 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1435 Actor& child = GetImplementation(*iter);
1437 if( child.GetDynamicsBody() )
1439 if( mIsDynamicsRoot )
1441 child.ConnectDynamics();
1445 child.DisconnectDynamics();
1453 bool Actor::IsDynamicsRoot() const
1455 return mIsDynamicsRoot;
1458 void Actor::AttachedActorOnStage( Dali::Actor actor )
1460 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1464 ActorPtr attachedActor( &GetImplementation(actor) );
1466 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1467 if( NULL != mDynamicsData )
1469 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1470 if( mDynamicsData->joints.end() != it )
1472 DynamicsJointPtr joint( it->second );
1473 joint->Connect(*mStage);
1479 void Actor::AttachedActorOffStage( Dali::Actor actor )
1481 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1485 ActorPtr attachedActor( &GetImplementation(actor) );
1487 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1488 if( NULL != mDynamicsData )
1490 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1491 if( mDynamicsData->joints.end() != it )
1493 DynamicsJointPtr joint( it->second );
1494 joint->Disconnect(*mStage);
1500 void Actor::ConnectDynamics()
1502 if( NULL != mDynamicsData && mDynamicsData->body )
1504 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1506 mDynamicsData->body->Connect(*mStage);
1508 // Connect all joints where attachedActor is also on stage
1509 if( !mDynamicsData->joints.empty() )
1511 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1512 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1514 for( ; it != endIt; ++it )
1516 Actor* attachedActor( it->first );
1517 if( NULL != attachedActor && attachedActor->OnStage() )
1519 DynamicsJointPtr joint( it->second );
1521 joint->Connect(*mStage);
1529 void Actor::DisconnectDynamics()
1531 if( NULL != mDynamicsData && mDynamicsData->body )
1535 mDynamicsData->body->Disconnect(*mStage);
1537 // Disconnect all joints
1538 if( !mDynamicsData->joints.empty() )
1540 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1541 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1543 for( ; it != endIt; ++it )
1545 DynamicsJointPtr joint( it->second );
1547 joint->Disconnect(*mStage);
1554 #endif // DYNAMICS_SUPPORT
1556 void Actor::SetOverlay(bool enable)
1558 // Setting STENCIL will override OVERLAY
1559 if( DrawMode::STENCIL != mDrawMode )
1561 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1565 bool Actor::IsOverlay() const
1567 return ( DrawMode::OVERLAY == mDrawMode );
1570 void Actor::SetDrawMode( DrawMode::Type drawMode )
1572 // this flag is not animatable so keep the value
1573 mDrawMode = drawMode;
1576 // mNode is being used in a separate thread; queue a message to set the value
1577 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1581 DrawMode::Type Actor::GetDrawMode() const
1586 bool Actor::ScreenToLocal( float& localX,
1589 float screenY ) const
1591 // only valid when on-stage
1594 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1596 Vector2 converted( screenX, screenY );
1598 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1599 const int taskCount = taskList.GetTaskCount();
1600 for( int i = taskCount - 1; i >= 0; --i )
1602 Dali::RenderTask task = taskList.GetTask( i );
1603 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1605 // found a task where this conversion was ok so return
1613 bool Actor::ScreenToLocal( RenderTask& renderTask,
1617 float screenY ) const
1619 bool retval = false;
1620 // only valid when on-stage
1623 CameraActor* camera = renderTask.GetCameraActor();
1627 renderTask.GetViewport( viewport );
1629 // need to translate coordinates to render tasks coordinate space
1630 Vector2 converted( screenX, screenY );
1631 if( renderTask.TranslateCoordinates( converted ) )
1633 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1640 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1641 const Matrix& projectionMatrix,
1642 const Viewport& viewport,
1646 float screenY ) const
1648 // Early-out if mNode is NULL
1654 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1656 // Calculate the ModelView matrix
1657 Matrix modelView(false/*don't init*/);
1658 // need to use the components as world matrix is only updated for actors that need it
1659 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1660 Matrix::Multiply(modelView, modelView, viewMatrix);
1662 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1663 Matrix invertedMvp(false/*don't init*/);
1664 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1665 bool success = invertedMvp.Invert();
1667 // Convert to GL coordinates
1668 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1673 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1680 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1686 if (XyPlaneIntersect(nearPos, farPos, local))
1688 Vector3 size = GetCurrentSize();
1689 localX = local.x + size.x * 0.5f;
1690 localY = local.y + size.y * 0.5f;
1701 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1704 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1706 Mathematical Formulation
1708 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1710 ( p - c ) dot ( p - c ) = r^2
1712 Given a ray with a point of origin 'o', and a direction vector 'd':
1714 ray(t) = o + td, t >= 0
1716 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1718 (o + td - c ) dot ( o + td - c ) = r^2
1720 To solve for t we first expand the above into a more recognisable quadratic equation form
1722 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1731 B = 2( o - c ) dot d
1732 C = ( o - c ) dot ( o - c ) - r^2
1734 which can be solved using a standard quadratic formula.
1736 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1738 Practical Simplification
1740 In a renderer, we often differentiate between world space and object space. In the object space
1741 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1742 into object space, the mathematical solution presented above can be simplified significantly.
1744 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1748 and we can find the t at which the (transformed) ray intersects the sphere by
1750 ( o + td ) dot ( o + td ) = r^2
1752 According to the reasoning above, we expand the above quadratic equation into the general form
1756 which now has coefficients:
1763 // Early out if mNode is NULL
1769 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1771 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1772 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1773 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1774 rayOrigin.y - translation.y,
1775 rayOrigin.z - translation.z);
1777 // Compute the radius is not needed, square radius it's enough.
1778 const Vector3& size( mNode->GetSize( bufferIndex ) );
1780 // Scale the sphere.
1781 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1783 const float width = size.width * scale.width;
1784 const float height = size.height * scale.height;
1786 float squareSphereRadius = 0.5f * ( width * width + height * height );
1788 float a = rayDir.Dot( rayDir ); // a
1789 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1790 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1792 return ( b2*b2 - a*c ) >= 0.f;
1795 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1802 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1804 // Transforms the ray to the local reference system.
1806 // Calculate the inverse of Model matrix
1807 Matrix invModelMatrix(false/*don't init*/);
1808 // need to use the components as world matrix is only updated for actors that need it
1809 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1811 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1812 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1814 // Test with the actor's XY plane (Normal = 0 0 1 1).
1816 float a = -rayOriginLocal.z;
1817 float b = rayDirLocal.z;
1819 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1821 // Ray travels distance * rayDirLocal to intersect with plane.
1824 const Vector3& size = mNode->GetSize( bufferIndex );
1826 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1827 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1829 // Test with the actor's geometry.
1830 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1837 void Actor::SetLeaveRequired(bool required)
1839 mLeaveRequired = required;
1842 bool Actor::GetLeaveRequired() const
1844 return mLeaveRequired;
1847 void Actor::SetKeyboardFocusable( bool focusable )
1849 mKeyboardFocusable = focusable;
1852 bool Actor::IsKeyboardFocusable() const
1854 return mKeyboardFocusable;
1857 bool Actor::GetTouchRequired() const
1859 return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
1862 bool Actor::GetHoverRequired() const
1864 return !mHoveredSignal.Empty() || mDerivedRequiresHover;
1867 bool Actor::GetMouseWheelEventRequired() const
1869 return !mMouseWheelEventSignal.Empty() || mDerivedRequiresMouseWheelEvent;
1872 bool Actor::IsHittable() const
1874 return IsSensitive() &&
1876 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1880 ActorGestureData& Actor::GetGestureData()
1882 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1883 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1884 if ( NULL == mGestureData )
1886 mGestureData = new ActorGestureData;
1888 return *mGestureData;
1891 bool Actor::IsGestureRequred( Gesture::Type type ) const
1893 return mGestureData && mGestureData->IsGestureRequred( type );
1896 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1898 bool consumed = false;
1900 if ( !mTouchedSignal.Empty() )
1902 Dali::Actor handle( this );
1903 consumed = mTouchedSignal.Emit( handle, event );
1908 // Notification for derived classes
1909 consumed = OnTouchEvent( event );
1915 bool Actor::EmitHoverEventSignal(const HoverEvent& event)
1917 bool consumed = false;
1919 if ( !mHoveredSignal.Empty() )
1921 Dali::Actor handle( this );
1922 consumed = mHoveredSignal.Emit( handle, event );
1927 // Notification for derived classes
1928 consumed = OnHoverEvent( event );
1934 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1936 bool consumed = false;
1938 if ( !mMouseWheelEventSignal.Empty() )
1940 Dali::Actor handle( this );
1941 consumed = mMouseWheelEventSignal.Emit( handle, event );
1946 // Notification for derived classes
1947 consumed = OnMouseWheelEvent(event);
1953 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
1955 return mTouchedSignal;
1958 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
1960 return mHoveredSignal;
1963 Dali::Actor::MouseWheelEventSignalType& Actor::MouseWheelEventSignal()
1965 return mMouseWheelEventSignal;
1968 Dali::Actor::SetSizeSignalType& Actor::SetSizeSignal()
1970 return mSetSizeSignal;
1973 Dali::Actor::OnStageSignalType& Actor::OnStageSignal()
1975 return mOnStageSignal;
1978 Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
1980 return mOffStageSignal;
1983 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1985 bool connected( true );
1986 Actor* actor = dynamic_cast<Actor*>(object);
1988 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1990 actor->TouchedSignal().Connect( tracker, functor );
1992 else if(Dali::Actor::SIGNAL_HOVERED == signalName)
1994 actor->HoveredSignal().Connect( tracker, functor );
1996 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1998 actor->MouseWheelEventSignal().Connect( tracker, functor );
2000 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
2002 actor->SetSizeSignal().Connect( tracker, functor );
2004 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
2006 actor->OnStageSignal().Connect( tracker, functor );
2008 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
2010 actor->OffStageSignal().Connect( tracker, functor );
2014 // signalName does not match any signal
2021 Actor::Actor( DerivedType derivedType )
2026 mParentOrigin( NULL ),
2027 mAnchorPoint( NULL ),
2028 #ifdef DYNAMICS_SUPPORT
2029 mDynamicsData( NULL ),
2031 mGestureData( NULL ),
2033 mSize( 0.0f, 0.0f, 0.0f ),
2035 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2036 mIsRoot( ROOT_LAYER == derivedType ),
2037 mIsRenderable( RENDERABLE == derivedType ),
2038 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2039 mIsOnStage( false ),
2040 mIsDynamicsRoot(false),
2042 mLeaveRequired( false ),
2043 mKeyboardFocusable( false ),
2044 mDerivedRequiresTouch( false ),
2045 mDerivedRequiresHover( false ),
2046 mDerivedRequiresMouseWheelEvent( false ),
2047 mOnStageSignalled( false ),
2048 mInheritRotation( true ),
2049 mInheritScale( true ),
2050 mDrawMode( DrawMode::NORMAL ),
2051 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2052 mColorMode( Node::DEFAULT_COLOR_MODE )
2056 void Actor::Initialize()
2058 mStage = Stage::GetCurrent();
2061 SceneGraph::Node* node = CreateNode();
2063 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2064 mNode = node; // Keep raw-pointer to Node
2073 // Remove mParent pointers from children even if we're destroying core,
2074 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2077 ActorConstIter endIter = mChildren->end();
2078 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2080 Actor& actor = GetImplementation( *iter );
2081 actor.SetParent( NULL );
2086 // Guard to allow handle destruction after Core has been destroyed
2087 if( Stage::IsInstalled() )
2091 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2092 mNode = NULL; // Node is about to be destroyed
2098 #ifdef DYNAMICS_SUPPORT
2100 delete mDynamicsData;
2103 // Cleanup optional gesture data
2104 delete mGestureData;
2106 // Cleanup optional parent origin and anchor
2107 delete mParentOrigin;
2108 delete mAnchorPoint;
2111 void Actor::ConnectToStage( int index )
2113 // This container is used instead of walking the Actor hierachy.
2114 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2115 ActorContainer connectionList;
2117 // This stage is atomic i.e. not interrupted by user callbacks
2118 RecursiveConnectToStage( connectionList, index );
2120 // Notify applications about the newly connected actors.
2121 const ActorIter endIter = connectionList.end();
2122 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2124 Actor& actor = GetImplementation(*iter);
2125 actor.NotifyStageConnection();
2129 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
2131 DALI_ASSERT_ALWAYS( !OnStage() );
2135 ConnectToSceneGraph(index);
2137 // Notification for internal derived classes
2138 OnStageConnectionInternal();
2140 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2141 connectionList.push_back( Dali::Actor(this) );
2143 // Recursively connect children
2146 ActorConstIter endIter = mChildren->end();
2147 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2149 Actor& actor = GetImplementation( *iter );
2150 actor.RecursiveConnectToStage( connectionList );
2156 * This method is called when the Actor is connected to the Stage.
2157 * The parent must have added its Node to the scene-graph.
2158 * The child must connect its Node to the parent's Node.
2159 * This is resursive; the child calls ConnectToStage() for its children.
2161 void Actor::ConnectToSceneGraph(int index)
2163 DALI_ASSERT_DEBUG( mNode != NULL);
2164 DALI_ASSERT_DEBUG( mParent != NULL);
2165 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2169 // Reparent Node in next Update
2170 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2173 // Notify attachment
2176 mAttachment->Connect();
2179 #ifdef DYNAMICS_SUPPORT
2181 if( NULL != mDynamicsData )
2187 // Notification for ProxyObject::Observers
2191 void Actor::NotifyStageConnection()
2193 // Actors can be removed (in a callback), before the on-stage stage is reported.
2194 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2195 if ( OnStage() && !mOnStageSignalled )
2197 // Notification for external (CustomActor) derived classes
2198 OnStageConnectionExternal();
2200 if ( !mOnStageSignal.Empty() )
2202 Dali::Actor handle( this );
2203 mOnStageSignal.Emit( handle );
2206 // Guard against Remove during callbacks
2209 mOnStageSignalled = true; // signal required next time Actor is removed
2214 void Actor::DisconnectFromStage()
2216 // This container is used instead of walking the Actor hierachy.
2217 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2218 ActorContainer disconnectionList;
2220 // This stage is atomic i.e. not interrupted by user callbacks
2221 RecursiveDisconnectFromStage( disconnectionList );
2223 // Notify applications about the newly disconnected actors.
2224 const ActorIter endIter = disconnectionList.end();
2225 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2227 Actor& actor = GetImplementation(*iter);
2228 actor.NotifyStageDisconnection();
2232 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2234 DALI_ASSERT_ALWAYS( OnStage() );
2236 // Recursively disconnect children
2239 ActorConstIter endIter = mChildren->end();
2240 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2242 Actor& actor = GetImplementation( *iter );
2243 actor.RecursiveDisconnectFromStage( disconnectionList );
2247 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2248 disconnectionList.push_back( Dali::Actor(this) );
2250 // Notification for internal derived classes
2251 OnStageDisconnectionInternal();
2253 DisconnectFromSceneGraph();
2259 * This method is called by an actor or its parent, before a node removal message is sent.
2260 * This is recursive; the child calls DisconnectFromStage() for its children.
2262 void Actor::DisconnectFromSceneGraph()
2264 // Notification for ProxyObject::Observers
2265 OnSceneObjectRemove();
2267 // Notify attachment
2270 mAttachment->Disconnect();
2273 #ifdef DYNAMICS_SUPPORT
2275 if( NULL != mDynamicsData )
2277 DisconnectDynamics();
2282 void Actor::NotifyStageDisconnection()
2284 // Actors can be added (in a callback), before the off-stage state is reported.
2285 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2286 // only do this step if there is a stage, i.e. Core is not being shut down
2287 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2289 // Notification for external (CustomeActor) derived classes
2290 OnStageDisconnectionExternal();
2292 if( !mOffStageSignal.Empty() )
2294 Dali::Actor handle( this );
2295 mOffStageSignal.Emit( handle );
2298 // Guard against Add during callbacks
2301 mOnStageSignalled = false; // signal required next time Actor is added
2306 bool Actor::IsNodeConnected() const
2308 bool connected( false );
2313 if( mNode->IsRoot() || mNode->GetParent() )
2322 unsigned int Actor::GetDefaultPropertyCount() const
2324 return DEFAULT_PROPERTY_COUNT;
2327 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2329 indices.reserve( DEFAULT_PROPERTY_COUNT );
2331 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2333 indices.push_back( i );
2337 const char* Actor::GetDefaultPropertyName( Property::Index index ) const
2339 if( index < DEFAULT_PROPERTY_COUNT )
2341 return DEFAULT_PROPERTY_DETAILS[index].name;
2349 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2351 Property::Index index = Property::INVALID_INDEX;
2353 // Look for name in default properties
2354 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2356 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
2357 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
2367 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2369 if( index < DEFAULT_PROPERTY_COUNT )
2371 return DEFAULT_PROPERTY_DETAILS[index].writable;
2379 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2381 if( index < DEFAULT_PROPERTY_COUNT )
2383 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2391 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2393 if( index < DEFAULT_PROPERTY_COUNT )
2395 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2403 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2405 if( index < DEFAULT_PROPERTY_COUNT )
2407 return DEFAULT_PROPERTY_DETAILS[index].type;
2411 // index out of range...return Property::NONE
2412 return Property::NONE;
2416 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2420 case Dali::Actor::PARENT_ORIGIN:
2422 SetParentOrigin( property.Get<Vector3>() );
2426 case Dali::Actor::PARENT_ORIGIN_X:
2428 SetParentOriginX( property.Get<float>() );
2432 case Dali::Actor::PARENT_ORIGIN_Y:
2434 SetParentOriginY( property.Get<float>() );
2438 case Dali::Actor::PARENT_ORIGIN_Z:
2440 SetParentOriginZ( property.Get<float>() );
2444 case Dali::Actor::ANCHOR_POINT:
2446 SetAnchorPoint( property.Get<Vector3>() );
2450 case Dali::Actor::ANCHOR_POINT_X:
2452 SetAnchorPointX( property.Get<float>() );
2456 case Dali::Actor::ANCHOR_POINT_Y:
2458 SetAnchorPointY( property.Get<float>() );
2462 case Dali::Actor::ANCHOR_POINT_Z:
2464 SetAnchorPointZ( property.Get<float>() );
2468 case Dali::Actor::SIZE:
2470 SetSize( property.Get<Vector3>() );
2474 case Dali::Actor::SIZE_WIDTH:
2476 SetWidth( property.Get<float>() );
2480 case Dali::Actor::SIZE_HEIGHT:
2482 SetHeight( property.Get<float>() );
2486 case Dali::Actor::SIZE_DEPTH:
2488 SetDepth( property.Get<float>() );
2492 case Dali::Actor::POSITION:
2494 SetPosition( property.Get<Vector3>() );
2498 case Dali::Actor::POSITION_X:
2500 SetX( property.Get<float>() );
2504 case Dali::Actor::POSITION_Y:
2506 SetY( property.Get<float>() );
2510 case Dali::Actor::POSITION_Z:
2512 SetZ( property.Get<float>() );
2516 case Dali::Actor::ROTATION:
2518 SetRotation( property.Get<Quaternion>() );
2522 case Dali::Actor::SCALE:
2524 SetScale( property.Get<Vector3>() );
2528 case Dali::Actor::SCALE_X:
2530 SetScaleX( property.Get<float>() );
2534 case Dali::Actor::SCALE_Y:
2536 SetScaleY( property.Get<float>() );
2540 case Dali::Actor::SCALE_Z:
2542 SetScaleZ( property.Get<float>() );
2546 case Dali::Actor::VISIBLE:
2548 SetVisible( property.Get<bool>() );
2552 case Dali::Actor::COLOR:
2554 SetColor( property.Get<Vector4>() );
2558 case Dali::Actor::COLOR_RED:
2560 SetColorRed( property.Get<float>() );
2564 case Dali::Actor::COLOR_GREEN:
2566 SetColorGreen( property.Get<float>() );
2570 case Dali::Actor::COLOR_BLUE:
2572 SetColorBlue( property.Get<float>() );
2576 case Dali::Actor::COLOR_ALPHA:
2578 SetOpacity( property.Get<float>() );
2582 case Dali::Actor::NAME:
2584 SetName( property.Get<std::string>() );
2588 case Dali::Actor::SENSITIVE:
2590 SetSensitive( property.Get<bool>() );
2594 case Dali::Actor::LEAVE_REQUIRED:
2596 SetLeaveRequired( property.Get<bool>() );
2600 case Dali::Actor::INHERIT_ROTATION:
2602 SetInheritRotation( property.Get<bool>() );
2606 case Dali::Actor::INHERIT_SCALE:
2608 SetInheritScale( property.Get<bool>() );
2612 case Dali::Actor::COLOR_MODE:
2614 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2618 case Dali::Actor::POSITION_INHERITANCE:
2620 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2624 case Dali::Actor::DRAW_MODE:
2626 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2632 // this can happen in the case of a non-animatable default property so just do nothing
2638 // TODO: This method needs to be removed
2639 void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2641 OnPropertySet(index, value);
2643 switch ( entry.type )
2645 case Property::BOOLEAN:
2647 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2648 DALI_ASSERT_DEBUG( NULL != property );
2650 // property is being used in a separate thread; queue a message to set the property
2651 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2656 case Property::FLOAT:
2658 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2659 DALI_ASSERT_DEBUG( NULL != property );
2661 // property is being used in a separate thread; queue a message to set the property
2662 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2667 case Property::INTEGER:
2669 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2670 DALI_ASSERT_DEBUG( NULL != property );
2672 // property is being used in a separate thread; queue a message to set the property
2673 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2678 case Property::VECTOR2:
2680 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2681 DALI_ASSERT_DEBUG( NULL != property );
2683 // property is being used in a separate thread; queue a message to set the property
2684 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2689 case Property::VECTOR3:
2691 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2692 DALI_ASSERT_DEBUG( NULL != property );
2694 // property is being used in a separate thread; queue a message to set the property
2695 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2700 case Property::VECTOR4:
2702 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2703 DALI_ASSERT_DEBUG( NULL != property );
2705 // property is being used in a separate thread; queue a message to set the property
2706 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2711 case Property::ROTATION:
2713 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2714 DALI_ASSERT_DEBUG( NULL != property );
2716 // property is being used in a separate thread; queue a message to set the property
2717 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2722 case Property::MATRIX:
2724 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
2725 DALI_ASSERT_DEBUG( NULL != property );
2727 // property is being used in a separate thread; queue a message to set the property
2728 SceneGraph::NodePropertyMessage<Matrix>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix>::Bake, value.Get<Matrix>() );
2733 case Property::MATRIX3:
2735 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
2736 DALI_ASSERT_DEBUG( NULL != property );
2738 // property is being used in a separate thread; queue a message to set the property
2739 SceneGraph::NodePropertyMessage<Matrix3>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Matrix3>::Bake, value.Get<Matrix3>() );
2746 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2752 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2754 Property::Value value;
2758 case Dali::Actor::PARENT_ORIGIN:
2760 value = GetCurrentParentOrigin();
2764 case Dali::Actor::PARENT_ORIGIN_X:
2766 value = GetCurrentParentOrigin().x;
2770 case Dali::Actor::PARENT_ORIGIN_Y:
2772 value = GetCurrentParentOrigin().y;
2776 case Dali::Actor::PARENT_ORIGIN_Z:
2778 value = GetCurrentParentOrigin().z;
2782 case Dali::Actor::ANCHOR_POINT:
2784 value = GetCurrentAnchorPoint();
2788 case Dali::Actor::ANCHOR_POINT_X:
2790 value = GetCurrentAnchorPoint().x;
2794 case Dali::Actor::ANCHOR_POINT_Y:
2796 value = GetCurrentAnchorPoint().y;
2800 case Dali::Actor::ANCHOR_POINT_Z:
2802 value = GetCurrentAnchorPoint().z;
2806 case Dali::Actor::SIZE:
2808 value = GetCurrentSize();
2812 case Dali::Actor::SIZE_WIDTH:
2814 value = GetCurrentSize().width;
2818 case Dali::Actor::SIZE_HEIGHT:
2820 value = GetCurrentSize().height;
2824 case Dali::Actor::SIZE_DEPTH:
2826 value = GetCurrentSize().depth;
2830 case Dali::Actor::POSITION:
2832 value = GetCurrentPosition();
2836 case Dali::Actor::POSITION_X:
2838 value = GetCurrentPosition().x;
2842 case Dali::Actor::POSITION_Y:
2844 value = GetCurrentPosition().y;
2848 case Dali::Actor::POSITION_Z:
2850 value = GetCurrentPosition().z;
2854 case Dali::Actor::WORLD_POSITION:
2856 value = GetCurrentWorldPosition();
2860 case Dali::Actor::WORLD_POSITION_X:
2862 value = GetCurrentWorldPosition().x;
2866 case Dali::Actor::WORLD_POSITION_Y:
2868 value = GetCurrentWorldPosition().y;
2872 case Dali::Actor::WORLD_POSITION_Z:
2874 value = GetCurrentWorldPosition().z;
2878 case Dali::Actor::ROTATION:
2880 value = GetCurrentRotation();
2884 case Dali::Actor::WORLD_ROTATION:
2886 value = GetCurrentWorldRotation();
2890 case Dali::Actor::SCALE:
2892 value = GetCurrentScale();
2896 case Dali::Actor::SCALE_X:
2898 value = GetCurrentScale().x;
2902 case Dali::Actor::SCALE_Y:
2904 value = GetCurrentScale().y;
2908 case Dali::Actor::SCALE_Z:
2910 value = GetCurrentScale().z;
2914 case Dali::Actor::WORLD_SCALE:
2916 value = GetCurrentWorldScale();
2920 case Dali::Actor::VISIBLE:
2922 value = IsVisible();
2926 case Dali::Actor::COLOR:
2928 value = GetCurrentColor();
2932 case Dali::Actor::COLOR_RED:
2934 value = GetCurrentColor().r;
2938 case Dali::Actor::COLOR_GREEN:
2940 value = GetCurrentColor().g;
2944 case Dali::Actor::COLOR_BLUE:
2946 value = GetCurrentColor().b;
2950 case Dali::Actor::COLOR_ALPHA:
2952 value = GetCurrentColor().a;
2956 case Dali::Actor::WORLD_COLOR:
2958 value = GetCurrentWorldColor();
2962 case Dali::Actor::WORLD_MATRIX:
2964 value = GetCurrentWorldMatrix();
2968 case Dali::Actor::NAME:
2974 case Dali::Actor::SENSITIVE:
2976 value = IsSensitive();
2980 case Dali::Actor::LEAVE_REQUIRED:
2982 value = GetLeaveRequired();
2986 case Dali::Actor::INHERIT_ROTATION:
2988 value = IsRotationInherited();
2992 case Dali::Actor::INHERIT_SCALE:
2994 value = IsScaleInherited();
2998 case Dali::Actor::COLOR_MODE:
3000 value = Scripting::GetColorMode( GetColorMode() );
3004 case Dali::Actor::POSITION_INHERITANCE:
3006 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3010 case Dali::Actor::DRAW_MODE:
3012 value = Scripting::GetDrawMode( GetDrawMode() );
3018 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3026 const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
3031 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3033 // This method should only return an object connected to the scene-graph
3034 return OnStage() ? mNode : NULL;
3037 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3039 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3041 const PropertyBase* property( NULL );
3043 // This method should only return a property of an object connected to the scene-graph
3049 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3051 CustomProperty* custom = FindCustomProperty( index );
3052 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3054 property = custom->GetSceneGraphProperty();
3056 else if( NULL != mNode )
3060 case Dali::Actor::SIZE:
3061 property = &mNode->mSize;
3064 case Dali::Actor::SIZE_WIDTH:
3065 property = &mNode->mSize;
3068 case Dali::Actor::SIZE_HEIGHT:
3069 property = &mNode->mSize;
3072 case Dali::Actor::SIZE_DEPTH:
3073 property = &mNode->mSize;
3076 case Dali::Actor::POSITION:
3077 property = &mNode->mPosition;
3080 case Dali::Actor::POSITION_X:
3081 property = &mNode->mPosition;
3084 case Dali::Actor::POSITION_Y:
3085 property = &mNode->mPosition;
3088 case Dali::Actor::POSITION_Z:
3089 property = &mNode->mPosition;
3092 case Dali::Actor::ROTATION:
3093 property = &mNode->mRotation;
3096 case Dali::Actor::SCALE:
3097 property = &mNode->mScale;
3100 case Dali::Actor::SCALE_X:
3101 property = &mNode->mScale;
3104 case Dali::Actor::SCALE_Y:
3105 property = &mNode->mScale;
3108 case Dali::Actor::SCALE_Z:
3109 property = &mNode->mScale;
3112 case Dali::Actor::VISIBLE:
3113 property = &mNode->mVisible;
3116 case Dali::Actor::COLOR:
3117 property = &mNode->mColor;
3120 case Dali::Actor::COLOR_RED:
3121 property = &mNode->mColor;
3124 case Dali::Actor::COLOR_GREEN:
3125 property = &mNode->mColor;
3128 case Dali::Actor::COLOR_BLUE:
3129 property = &mNode->mColor;
3132 case Dali::Actor::COLOR_ALPHA:
3133 property = &mNode->mColor;
3144 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3146 const PropertyInputImpl* property( NULL );
3148 // This method should only return a property of an object connected to the scene-graph
3154 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3156 CustomProperty* custom = FindCustomProperty( index );
3157 DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
3158 property = custom->GetSceneGraphProperty();
3160 else if( NULL != mNode )
3164 case Dali::Actor::PARENT_ORIGIN:
3165 property = &mNode->mParentOrigin;
3168 case Dali::Actor::PARENT_ORIGIN_X:
3169 property = &mNode->mParentOrigin;
3172 case Dali::Actor::PARENT_ORIGIN_Y:
3173 property = &mNode->mParentOrigin;
3176 case Dali::Actor::PARENT_ORIGIN_Z:
3177 property = &mNode->mParentOrigin;
3180 case Dali::Actor::ANCHOR_POINT:
3181 property = &mNode->mAnchorPoint;
3184 case Dali::Actor::ANCHOR_POINT_X:
3185 property = &mNode->mAnchorPoint;
3188 case Dali::Actor::ANCHOR_POINT_Y:
3189 property = &mNode->mAnchorPoint;
3192 case Dali::Actor::ANCHOR_POINT_Z:
3193 property = &mNode->mAnchorPoint;
3196 case Dali::Actor::SIZE:
3197 property = &mNode->mSize;
3200 case Dali::Actor::SIZE_WIDTH:
3201 property = &mNode->mSize;
3204 case Dali::Actor::SIZE_HEIGHT:
3205 property = &mNode->mSize;
3208 case Dali::Actor::SIZE_DEPTH:
3209 property = &mNode->mSize;
3212 case Dali::Actor::POSITION:
3213 property = &mNode->mPosition;
3216 case Dali::Actor::POSITION_X:
3217 property = &mNode->mPosition;
3220 case Dali::Actor::POSITION_Y:
3221 property = &mNode->mPosition;
3224 case Dali::Actor::POSITION_Z:
3225 property = &mNode->mPosition;
3228 case Dali::Actor::WORLD_POSITION:
3229 property = &mNode->mWorldPosition;
3232 case Dali::Actor::WORLD_POSITION_X:
3233 property = &mNode->mWorldPosition;
3236 case Dali::Actor::WORLD_POSITION_Y:
3237 property = &mNode->mWorldPosition;
3240 case Dali::Actor::WORLD_POSITION_Z:
3241 property = &mNode->mWorldPosition;
3244 case Dali::Actor::ROTATION:
3245 property = &mNode->mRotation;
3248 case Dali::Actor::WORLD_ROTATION:
3249 property = &mNode->mWorldRotation;
3252 case Dali::Actor::SCALE:
3253 property = &mNode->mScale;
3256 case Dali::Actor::SCALE_X:
3257 property = &mNode->mScale;
3260 case Dali::Actor::SCALE_Y:
3261 property = &mNode->mScale;
3264 case Dali::Actor::SCALE_Z:
3265 property = &mNode->mScale;
3268 case Dali::Actor::WORLD_SCALE:
3269 property = &mNode->mWorldScale;
3272 case Dali::Actor::VISIBLE:
3273 property = &mNode->mVisible;
3276 case Dali::Actor::COLOR:
3277 property = &mNode->mColor;
3280 case Dali::Actor::COLOR_RED:
3281 property = &mNode->mColor;
3284 case Dali::Actor::COLOR_GREEN:
3285 property = &mNode->mColor;
3288 case Dali::Actor::COLOR_BLUE:
3289 property = &mNode->mColor;
3292 case Dali::Actor::COLOR_ALPHA:
3293 property = &mNode->mColor;
3296 case Dali::Actor::WORLD_COLOR:
3297 property = &mNode->mWorldColor;
3300 case Dali::Actor::WORLD_MATRIX:
3301 property = &mNode->mWorldMatrix;
3312 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3314 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3318 case Dali::Actor::PARENT_ORIGIN_X:
3319 case Dali::Actor::ANCHOR_POINT_X:
3320 case Dali::Actor::SIZE_WIDTH:
3321 case Dali::Actor::POSITION_X:
3322 case Dali::Actor::SCALE_X:
3323 case Dali::Actor::COLOR_RED:
3324 case Dali::Actor::WORLD_POSITION_X:
3330 case Dali::Actor::PARENT_ORIGIN_Y:
3331 case Dali::Actor::ANCHOR_POINT_Y:
3332 case Dali::Actor::SIZE_HEIGHT:
3333 case Dali::Actor::POSITION_Y:
3334 case Dali::Actor::SCALE_Y:
3335 case Dali::Actor::COLOR_GREEN:
3336 case Dali::Actor::WORLD_POSITION_Y:
3342 case Dali::Actor::PARENT_ORIGIN_Z:
3343 case Dali::Actor::ANCHOR_POINT_Z:
3344 case Dali::Actor::SIZE_DEPTH:
3345 case Dali::Actor::POSITION_Z:
3346 case Dali::Actor::SCALE_Z:
3347 case Dali::Actor::COLOR_BLUE:
3348 case Dali::Actor::WORLD_POSITION_Z:
3354 case Dali::Actor::COLOR_ALPHA:
3367 return componentIndex;
3370 void Actor::SetParent(Actor* parent, int index)
3374 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3378 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3381 // Instruct each actor to create a corresponding node in the scene graph
3382 ConnectToStage( index );
3385 else // parent being set to NULL
3387 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3391 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3394 DALI_ASSERT_ALWAYS(mNode != NULL);
3398 // Disconnect the Node & its children from the scene-graph.
3399 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3402 // Instruct each actor to discard pointers to the scene-graph
3403 DisconnectFromStage();
3408 SceneGraph::Node* Actor::CreateNode() const
3413 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3416 Actor* actor = dynamic_cast<Actor*>(object);
3420 if(Dali::Actor::ACTION_SHOW == actionName)
3422 actor->SetVisible(true);
3425 else if(Dali::Actor::ACTION_HIDE == actionName)
3427 actor->SetVisible(false);
3435 } // namespace Internal