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/effects/shader-effect-impl.h>
50 #include <dali/internal/event/events/actor-gesture-data.h>
51 #include <dali/internal/common/message.h>
52 #include <dali/integration-api/debug.h>
54 #ifdef DYNAMICS_SUPPORT
55 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
58 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
61 using Dali::Internal::SceneGraph::Node;
62 using Dali::Internal::SceneGraph::AnimatableProperty;
63 using Dali::Internal::SceneGraph::PropertyBase;
64 using Dali::Internal::SceneGraph::Shader;
71 const Property::Index Actor::PARENT_ORIGIN = 0;
72 const Property::Index Actor::PARENT_ORIGIN_X = 1;
73 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
74 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
75 const Property::Index Actor::ANCHOR_POINT = 4;
76 const Property::Index Actor::ANCHOR_POINT_X = 5;
77 const Property::Index Actor::ANCHOR_POINT_Y = 6;
78 const Property::Index Actor::ANCHOR_POINT_Z = 7;
79 const Property::Index Actor::SIZE = 8;
80 const Property::Index Actor::SIZE_WIDTH = 9;
81 const Property::Index Actor::SIZE_HEIGHT = 10;
82 const Property::Index Actor::SIZE_DEPTH = 11;
83 const Property::Index Actor::POSITION = 12;
84 const Property::Index Actor::POSITION_X = 13;
85 const Property::Index Actor::POSITION_Y = 14;
86 const Property::Index Actor::POSITION_Z = 15;
87 const Property::Index Actor::WORLD_POSITION = 16;
88 const Property::Index Actor::WORLD_POSITION_X = 17;
89 const Property::Index Actor::WORLD_POSITION_Y = 18;
90 const Property::Index Actor::WORLD_POSITION_Z = 19;
91 const Property::Index Actor::ROTATION = 20;
92 const Property::Index Actor::WORLD_ROTATION = 21;
93 const Property::Index Actor::SCALE = 22;
94 const Property::Index Actor::SCALE_X = 23;
95 const Property::Index Actor::SCALE_Y = 24;
96 const Property::Index Actor::SCALE_Z = 25;
97 const Property::Index Actor::WORLD_SCALE = 26;
98 const Property::Index Actor::VISIBLE = 27;
99 const Property::Index Actor::COLOR = 28;
100 const Property::Index Actor::COLOR_RED = 29;
101 const Property::Index Actor::COLOR_GREEN = 30;
102 const Property::Index Actor::COLOR_BLUE = 31;
103 const Property::Index Actor::COLOR_ALPHA = 32;
104 const Property::Index Actor::WORLD_COLOR = 33;
105 const Property::Index Actor::WORLD_MATRIX = 34;
106 const Property::Index Actor::NAME = 35;
107 const Property::Index Actor::SENSITIVE = 36;
108 const Property::Index Actor::LEAVE_REQUIRED = 37;
109 const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
110 const Property::Index Actor::INHERIT_ROTATION = 39;
111 const Property::Index Actor::INHERIT_SCALE = 40;
112 const Property::Index Actor::COLOR_MODE = 41;
113 const Property::Index Actor::POSITION_INHERITANCE = 42;
114 const Property::Index Actor::DRAW_MODE = 43;
116 namespace // unnamed namespace
120 * We want to discourage the use of property strings (minimize string comparisons),
121 * particularly for the default properties.
123 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
125 // Name Type writable animatable constraint-input
126 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
127 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
128 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
129 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
130 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
131 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
132 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
133 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
134 { "size", Property::VECTOR3, true, true, true }, // SIZE
135 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
136 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
137 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
138 { "position", Property::VECTOR3, true, true, true }, // POSITION
139 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
140 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
141 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
142 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
143 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
144 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
145 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
146 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
147 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
148 { "scale", Property::VECTOR3, true, true, true }, // SCALE
149 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
150 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
151 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
152 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
153 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
154 { "color", Property::VECTOR4, true, true, true }, // COLOR
155 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
156 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
157 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
158 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
159 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
160 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
161 { "name", Property::STRING, true, false, false }, // NAME
162 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
163 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
164 { "inherit-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
165 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
166 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
167 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
168 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
169 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
171 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
173 } // unnamed namespace
178 unsigned int Actor::mActorCounter = 0;
179 ActorContainer Actor::mNullChildren;
181 #ifdef DYNAMICS_SUPPORT
183 // Encapsulate actor related dynamics data
186 DynamicsData( Actor* slotOwner )
187 : slotDelegate( slotOwner )
191 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
192 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
194 DynamicsBodyPtr body;
195 JointContainer joints;
196 ReferencedJointContainer referencedJoints;
198 SlotDelegate< Actor > slotDelegate;
201 #endif // DYNAMICS_SUPPORT
206 using namespace Dali;
208 BaseHandle CreateActor()
210 return Dali::Actor::New();
213 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
215 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
216 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
217 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
218 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
220 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
221 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
225 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
227 ActorPtr Actor::New()
229 ActorPtr actor( new Actor( BASIC ) );
231 // Second-phase construction
237 const std::string& Actor::GetName() const
242 void Actor::SetName(const std::string& name)
248 // ATTENTION: string for debug purposes is not thread safe.
249 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
253 unsigned int Actor::GetId() const
258 void Actor::Attach( ActorAttachment& attachment )
260 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
264 attachment.Connect();
267 mAttachment = ActorAttachmentPtr(&attachment);
270 ActorAttachmentPtr Actor::GetAttachment()
275 bool Actor::OnStage() const
280 Dali::Layer Actor::GetLayer()
284 // Short-circuit for Layer derived actors
287 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
290 // Find the immediate Layer parent
291 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
293 if( parent->IsLayer() )
295 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
302 void Actor::Add(Actor& child)
304 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
305 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
309 mChildren = new ActorContainer;
312 Actor* const oldParent( child.mParent );
314 // child might already be ours
315 if( this != oldParent )
317 // if we already have parent, unparent us first
320 oldParent->Remove( child ); // This causes OnChildRemove callback
323 // Guard against Add() during previous OnChildRemove callback
324 if ( !child.mParent )
326 // Do this first, since user callbacks from within SetParent() may need to remove child
327 mChildren->push_back(Dali::Actor(&child));
329 // SetParent asserts that child can be added
330 child.SetParent(this);
332 // Notification for derived classes
338 void Actor::Remove(Actor& child)
340 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
350 // Find the child in mChildren, and unparent it
351 ActorIter end = mChildren->end();
352 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
354 Actor& actor = GetImplementation(*iter);
356 if( &actor == &child )
358 // Keep handle for OnChildRemove notification
359 removed = Dali::Actor( &actor );
361 // Do this first, since user callbacks from within SetParent() may need to add the child
362 mChildren->erase(iter);
364 DALI_ASSERT_DEBUG( actor.GetParent() == this );
365 actor.SetParent( NULL );
373 // Notification for derived classes
374 OnChildRemove( GetImplementation(removed) );
378 void Actor::Unparent()
382 mParent->Remove( *this );
386 unsigned int Actor::GetChildCount() const
388 return ( NULL != mChildren ) ? mChildren->size() : 0;
391 Dali::Actor Actor::GetChildAt(unsigned int index) const
393 DALI_ASSERT_ALWAYS( index < GetChildCount() );
395 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
398 ActorContainer Actor::GetChildren()
400 if( NULL != mChildren )
405 // return copy of mNullChildren
406 return mNullChildren;
409 const ActorContainer& Actor::GetChildren() const
411 if( NULL != mChildren )
416 // return const reference to mNullChildren
417 return mNullChildren;
420 ActorPtr Actor::FindChildByName(const std::string& actorName)
423 if (actorName == mName)
429 ActorIter end = mChildren->end();
430 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
432 child = GetImplementation(*iter).FindChildByName(actorName);
443 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
445 Dali::Actor child = DoGetChildByAlias(actorAlias);
447 // If not found then search by name.
450 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
453 child = Dali::Actor(child_ptr.Get());
460 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
462 Dali::Actor child = GetChildByAlias(actorAlias);
464 if (!child && mChildren )
466 ActorIter end = mChildren->end();
467 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
469 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
481 ActorPtr Actor::FindChildById(const unsigned int id)
490 ActorIter end = mChildren->end();
491 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
493 child = GetImplementation(*iter).FindChildById(id);
504 void Actor::SetParentOrigin( const Vector3& origin )
508 // mNode is being used in a separate thread; queue a message to set the value & base value
509 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
512 // Cache for event-thread access
515 // not allocated, check if different from default
516 if( ParentOrigin::DEFAULT != origin )
518 mParentOrigin = new Vector3( origin );
523 // check if different from current costs more than just set
524 *mParentOrigin = origin;
528 void Actor::SetParentOriginX( float x )
530 const Vector3& current = GetCurrentParentOrigin();
532 SetParentOrigin( Vector3( x, current.y, current.z ) );
535 void Actor::SetParentOriginY( float y )
537 const Vector3& current = GetCurrentParentOrigin();
539 SetParentOrigin( Vector3( current.x, y, current.z ) );
542 void Actor::SetParentOriginZ( float z )
544 const Vector3& current = GetCurrentParentOrigin();
546 SetParentOrigin( Vector3( current.x, current.y, z ) );
549 const Vector3& Actor::GetCurrentParentOrigin() const
551 // Cached for event-thread access
552 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
555 void Actor::SetAnchorPoint(const Vector3& anchor)
559 // mNode is being used in a separate thread; queue a message to set the value & base value
560 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
563 // Cache for event-thread access
566 // not allocated, check if different from default
567 if( AnchorPoint::DEFAULT != anchor )
569 mAnchorPoint = new Vector3( anchor );
574 // check if different from current costs more than just set
575 *mAnchorPoint = anchor;
579 void Actor::SetAnchorPointX( float x )
581 const Vector3& current = GetCurrentAnchorPoint();
583 SetAnchorPoint( Vector3( x, current.y, current.z ) );
586 void Actor::SetAnchorPointY( float y )
588 const Vector3& current = GetCurrentAnchorPoint();
590 SetAnchorPoint( Vector3( current.x, y, current.z ) );
593 void Actor::SetAnchorPointZ( float z )
595 const Vector3& current = GetCurrentAnchorPoint();
597 SetAnchorPoint( Vector3( current.x, current.y, z ) );
600 const Vector3& Actor::GetCurrentAnchorPoint() const
602 // Cached for event-thread access
603 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
606 void Actor::SetPosition(float x, float y)
608 SetPosition(Vector3(x, y, 0.0f));
611 void Actor::SetPosition(float x, float y, float z)
613 SetPosition(Vector3(x, y, z));
616 void Actor::SetPosition(const Vector3& position)
620 // mNode is being used in a separate thread; queue a message to set the value & base value
621 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
625 void Actor::SetX(float x)
629 // mNode is being used in a separate thread; queue a message to set the value & base value
630 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
634 void Actor::SetY(float y)
638 // mNode is being used in a separate thread; queue a message to set the value & base value
639 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
643 void Actor::SetZ(float z)
647 // mNode is being used in a separate thread; queue a message to set the value & base value
648 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
652 void Actor::MoveBy(const Vector3& distance)
656 // mNode is being used in a separate thread; queue a message to set the value & base value
657 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
661 const Vector3& Actor::GetCurrentPosition() const
665 // mNode is being used in a separate thread; copy the value from the previous update
666 return mNode->GetPosition(mStage->GetEventBufferIndex());
669 return Vector3::ZERO;
672 const Vector3& Actor::GetCurrentWorldPosition() const
676 // mNode is being used in a separate thread; copy the value from the previous update
677 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
680 return Vector3::ZERO;
683 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
685 // this flag is not animatable so keep the value
686 mPositionInheritanceMode = mode;
689 // mNode is being used in a separate thread; queue a message to set the value
690 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
694 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
696 // Cached for event-thread access
697 return mPositionInheritanceMode;
700 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
702 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
703 normalizedAxis.Normalize();
705 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
707 SetRotation(rotation);
710 void Actor::SetRotation(const Quaternion& rotation)
714 // mNode is being used in a separate thread; queue a message to set the value & base value
715 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
719 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
723 // mNode is being used in a separate thread; queue a message to set the value & base value
724 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
728 void Actor::RotateBy(const Quaternion& relativeRotation)
732 // mNode is being used in a separate thread; queue a message to set the value & base value
733 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
737 const Quaternion& Actor::GetCurrentRotation() const
741 // mNode is being used in a separate thread; copy the value from the previous update
742 return mNode->GetRotation(mStage->GetEventBufferIndex());
745 return Quaternion::IDENTITY;
748 const Quaternion& Actor::GetCurrentWorldRotation() const
752 // mNode is being used in a separate thread; copy the value from the previous update
753 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
756 return Quaternion::IDENTITY;
759 void Actor::SetScale(float scale)
761 SetScale(Vector3(scale, scale, scale));
764 void Actor::SetScale(float x, float y, float z)
766 SetScale(Vector3(x, y, z));
769 void Actor::SetScale(const Vector3& scale)
773 // mNode is being used in a separate thread; queue a message to set the value & base value
774 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
778 void Actor::SetScaleX( float x )
782 // mNode is being used in a separate thread; queue a message to set the value & base value
783 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
787 void Actor::SetScaleY( float y )
791 // mNode is being used in a separate thread; queue a message to set the value & base value
792 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
796 void Actor::SetScaleZ( float z )
800 // mNode is being used in a separate thread; queue a message to set the value & base value
801 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
805 void Actor::SetInitialVolume(const Vector3& volume)
809 // mNode is being used in a separate thread; queue a message to set the value
810 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
814 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
818 // mNode is being used in a separate thread; queue a message to set the value
819 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
823 bool Actor::GetTransmitGeometryScaling() const
827 // mNode is being used in a separate thread; copy the value from the previous update
828 return mNode->GetTransmitGeometryScaling();
834 void Actor::ScaleBy(const Vector3& relativeScale)
838 // mNode is being used in a separate thread; queue a message to set the value & base value
839 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
843 const Vector3& Actor::GetCurrentScale() const
847 // mNode is being used in a separate thread; copy the value from the previous update
848 return mNode->GetScale(mStage->GetEventBufferIndex());
854 const Vector3& Actor::GetCurrentWorldScale() const
858 // mNode is being used in a separate thread; copy the value from the previous update
859 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
865 void Actor::SetInheritScale( bool inherit )
867 // non animateable so keep local copy
868 mInheritScale = inherit;
871 // mNode is being used in a separate thread; queue a message to set the value
872 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
876 bool Actor::IsScaleInherited() const
878 return mInheritScale;
881 Matrix Actor::GetCurrentWorldMatrix() const
885 // World matrix is no longer updated unless there is something observing the node.
886 // Need to calculate it from node's world position, rotation and scale:
887 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
888 Matrix worldMatrix(false);
889 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
890 mNode->GetWorldRotation( updateBufferIndex ),
891 mNode->GetWorldPosition( updateBufferIndex ) );
895 return Matrix::IDENTITY;
898 void Actor::SetVisible(bool visible)
902 // mNode is being used in a separate thread; queue a message to set the value & base value
903 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
907 bool Actor::IsVisible() const
911 // mNode is being used in a separate thread; copy the value from the previous update
912 return mNode->IsVisible( mStage->GetEventBufferIndex() );
918 void Actor::SetOpacity(float opacity)
922 // mNode is being used in a separate thread; queue a message to set the value & base value
923 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
927 void Actor::OpacityBy(float relativeOpacity)
931 // mNode is being used in a separate thread; queue a message to set the value & base value
932 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
936 float Actor::GetCurrentOpacity() const
940 // mNode is being used in a separate thread; copy the value from the previous update
941 return mNode->GetOpacity(mStage->GetEventBufferIndex());
947 const Vector4& Actor::GetCurrentWorldColor() const
951 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
957 void Actor::SetColor(const Vector4& color)
961 // mNode is being used in a separate thread; queue a message to set the value & base value
962 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
966 void Actor::SetColorRed( float red )
970 // mNode is being used in a separate thread; queue a message to set the value & base value
971 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
975 void Actor::SetColorGreen( float green )
979 // mNode is being used in a separate thread; queue a message to set the value & base value
980 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
984 void Actor::SetColorBlue( float blue )
988 // mNode is being used in a separate thread; queue a message to set the value & base value
989 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
993 void Actor::ColorBy(const Vector4& relativeColor)
997 // mNode is being used in a separate thread; queue a message to set the value & base value
998 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1002 const Vector4& Actor::GetCurrentColor() const
1006 // mNode is being used in a separate thread; copy the value from the previous update
1007 return mNode->GetColor(mStage->GetEventBufferIndex());
1010 return Color::WHITE;
1013 void Actor::SetInheritRotation(bool inherit)
1015 // non animateable so keep local copy
1016 mInheritRotation = inherit;
1019 // mNode is being used in a separate thread; queue a message to set the value
1020 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1024 bool Actor::IsRotationInherited() const
1026 return mInheritRotation;
1029 void Actor::SetColorMode(ColorMode colorMode)
1031 // non animateable so keep local copy
1032 mColorMode = colorMode;
1035 // mNode is being used in a separate thread; queue a message to set the value
1036 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1040 ColorMode Actor::GetColorMode() const
1042 // we have cached copy
1046 void Actor::SetSize(float width, float height)
1048 SetSize( Vector2( width, height ) );
1051 void Actor::SetSize(float width, float height, float depth)
1053 SetSize( Vector3( width, height, depth ) );
1056 void Actor::SetSize(const Vector2& size)
1058 Vector3 volume( size );
1059 volume.z = std::min( size.width, size.height );
1063 void Actor::SetSize(const Vector3& size)
1067 // mNode is being used in a separate thread; queue a message to set the value & base value
1068 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1070 // Notification for derived classes
1073 // Emit signal for application developer
1075 if( !mSetSizeSignalV2.Empty() )
1077 Dali::Actor handle( this );
1078 mSetSizeSignalV2.Emit( handle, size );
1083 void Actor::SetWidth( float width )
1087 // mNode is being used in a separate thread; queue a message to set the value & base value
1088 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1092 void Actor::SetHeight( float height )
1096 // mNode is being used in a separate thread; queue a message to set the value & base value
1097 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1101 void Actor::SetDepth( float depth )
1105 // mNode is being used in a separate thread; queue a message to set the value & base value
1106 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1110 const Vector3& Actor::GetCurrentSize() const
1114 // mNode is being used in a separate thread; copy the value from the previous update
1115 return mNode->GetSize( mStage->GetEventBufferIndex() );
1118 return Vector3::ZERO;
1121 void Actor::SetInheritShaderEffect(bool inherit)
1125 // mNode is being used in a separate thread; queue a message to set the value
1126 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1130 bool Actor::GetInheritShaderEffect() const
1134 // mNode is being used in a separate thread; copy the value from the previous update
1135 return mNode->GetInheritShader();
1141 void Actor::SetShaderEffect(ShaderEffect& effect)
1147 mShaderEffect->Disconnect();
1150 mShaderEffect = ShaderEffectPtr(&effect);
1152 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1156 // mNode is being used in a separate thread; queue a message to apply shader
1157 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1160 mShaderEffect->Connect();
1164 mShaderEffect = ShaderEffectPtr(&effect);
1166 // Effects can only be applied when the Node is connected to scene-graph
1169 ShaderEffectPtr Actor::GetShaderEffect() const
1171 return mShaderEffect;
1174 void Actor::RemoveShaderEffect()
1180 // mNode is being used in a separate thread; queue a message to remove shader
1181 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1184 // Notify shader effect
1187 mShaderEffect->Disconnect();
1191 mShaderEffect.Reset();
1194 #ifdef DYNAMICS_SUPPORT
1196 //--------------- Dynamics ---------------
1198 void Actor::DisableDynamics()
1200 if( NULL != mDynamicsData )
1202 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1204 // ensure dynamics object are disconnected from scene
1205 DisconnectDynamics();
1207 // delete joint owned by this actor
1208 while( !mDynamicsData->joints.empty() )
1210 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1213 // delete other joints referencing this actor
1214 while( !mDynamicsData->referencedJoints.empty() )
1216 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1217 ActorPtr jointOwner( joint->GetActor( true ) );
1220 jointOwner->RemoveDynamicsJoint( joint );
1224 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1227 // delete the DynamicsBody object
1228 mDynamicsData->body.Reset();
1230 // Discard Dynamics data structure
1231 delete mDynamicsData;
1232 mDynamicsData = NULL;
1236 DynamicsBodyPtr Actor::GetDynamicsBody() const
1238 DynamicsBodyPtr body;
1240 if( NULL != mDynamicsData )
1242 body = mDynamicsData->body;
1248 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1250 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1252 if( NULL == mDynamicsData )
1254 mDynamicsData = new DynamicsData( this );
1257 if( !mDynamicsData->body )
1259 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1263 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1266 if( mParent == world->GetRootActor().Get() )
1268 mDynamicsData->body->Connect(*mStage);
1274 return mDynamicsData->body;
1277 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1279 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1280 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1283 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1285 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1286 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1288 DynamicsJointPtr joint;
1290 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1294 if( NULL != mDynamicsData )
1296 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1298 if( mDynamicsData->joints.end() != it )
1300 // use existing joint
1306 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1307 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1311 bodyA = EnableDynamics( new DynamicsBodyConfig );
1316 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1319 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1320 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1322 if( OnStage() && attachedActor->OnStage() )
1324 joint->Connect(*mStage);
1327 attachedActor->ReferenceJoint( joint );
1329 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1330 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1337 const int Actor::GetNumberOfJoints() const
1339 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1342 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1344 DynamicsJointPtr joint;
1346 if( NULL != mDynamicsData )
1348 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1350 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1352 for( int i = 0; i < index; ++i )
1364 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1366 DynamicsJointPtr joint;
1368 if( NULL != mDynamicsData )
1370 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1372 if( mDynamicsData->joints.end() != it )
1374 // use existing joint
1382 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1384 if( NULL != mDynamicsData )
1386 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1387 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1389 for( ; it != endIt; ++it )
1391 if( it->second == joint.Get() )
1393 ActorPtr attachedActor( it->first );
1395 if( OnStage() && attachedActor && attachedActor->OnStage() )
1397 joint->Disconnect(*mStage);
1402 attachedActor->ReleaseJoint( joint );
1403 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1404 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1407 mDynamicsData->joints.erase(it);
1414 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1416 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1418 if( NULL != mDynamicsData )
1420 mDynamicsData->referencedJoints.push_back(joint);
1424 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1426 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1428 if( NULL != mDynamicsData )
1430 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1432 if( it != mDynamicsData->referencedJoints.end() )
1434 mDynamicsData->referencedJoints.erase( it );
1439 void Actor::SetDynamicsRoot(bool flag)
1441 if( mIsDynamicsRoot != flag )
1443 mIsDynamicsRoot = flag;
1445 if( OnStage() && mChildren )
1447 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1448 ActorIter end = mChildren->end();
1449 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1451 Actor& child = GetImplementation(*iter);
1453 if( child.GetDynamicsBody() )
1455 if( mIsDynamicsRoot )
1457 child.ConnectDynamics();
1461 child.DisconnectDynamics();
1469 bool Actor::IsDynamicsRoot() const
1471 return mIsDynamicsRoot;
1474 void Actor::AttachedActorOnStage( Dali::Actor actor )
1476 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1480 ActorPtr attachedActor( &GetImplementation(actor) );
1482 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1483 if( NULL != mDynamicsData )
1485 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1486 if( mDynamicsData->joints.end() != it )
1488 DynamicsJointPtr joint( it->second );
1489 joint->Connect(*mStage);
1495 void Actor::AttachedActorOffStage( Dali::Actor actor )
1497 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1501 ActorPtr attachedActor( &GetImplementation(actor) );
1503 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1504 if( NULL != mDynamicsData )
1506 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1507 if( mDynamicsData->joints.end() != it )
1509 DynamicsJointPtr joint( it->second );
1510 joint->Disconnect(*mStage);
1516 void Actor::ConnectDynamics()
1518 if( NULL != mDynamicsData && mDynamicsData->body )
1520 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1522 mDynamicsData->body->Connect(*mStage);
1524 // Connect all joints where attachedActor is also on stage
1525 if( !mDynamicsData->joints.empty() )
1527 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1528 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1530 for( ; it != endIt; ++it )
1532 Actor* attachedActor( it->first );
1533 if( NULL != attachedActor && attachedActor->OnStage() )
1535 DynamicsJointPtr joint( it->second );
1537 joint->Connect(*mStage);
1545 void Actor::DisconnectDynamics()
1547 if( NULL != mDynamicsData && mDynamicsData->body )
1551 mDynamicsData->body->Disconnect(*mStage);
1553 // Disconnect all joints
1554 if( !mDynamicsData->joints.empty() )
1556 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1557 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1559 for( ; it != endIt; ++it )
1561 DynamicsJointPtr joint( it->second );
1563 joint->Disconnect(*mStage);
1570 #endif // DYNAMICS_SUPPORT
1572 void Actor::SetOverlay(bool enable)
1574 // Setting STENCIL will override OVERLAY
1575 if( DrawMode::STENCIL != mDrawMode )
1577 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1581 bool Actor::IsOverlay() const
1583 return ( DrawMode::OVERLAY == mDrawMode );
1586 void Actor::SetDrawMode( DrawMode::Type drawMode )
1588 // this flag is not animatable so keep the value
1589 mDrawMode = drawMode;
1592 // mNode is being used in a separate thread; queue a message to set the value
1593 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1597 DrawMode::Type Actor::GetDrawMode() const
1602 bool Actor::ScreenToLocal( float& localX,
1605 float screenY ) const
1607 // only valid when on-stage
1610 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1612 Vector2 converted( screenX, screenY );
1614 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1615 const int taskCount = taskList.GetTaskCount();
1616 for( int i = taskCount - 1; i >= 0; --i )
1618 Dali::RenderTask task = taskList.GetTask( i );
1619 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1621 // found a task where this conversion was ok so return
1629 bool Actor::ScreenToLocal( RenderTask& renderTask,
1633 float screenY ) const
1635 bool retval = false;
1636 // only valid when on-stage
1639 CameraActor* camera = renderTask.GetCameraActor();
1643 renderTask.GetViewport( viewport );
1645 // need to translate coordinates to render tasks coordinate space
1646 Vector2 converted( screenX, screenY );
1647 if( renderTask.TranslateCoordinates( converted ) )
1649 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1656 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1657 const Matrix& projectionMatrix,
1658 const Viewport& viewport,
1662 float screenY ) const
1664 // Early-out if mNode is NULL
1670 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1672 // Calculate the ModelView matrix
1673 Matrix modelView(false/*don't init*/);
1674 // need to use the components as world matrix is only updated for actors that need it
1675 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1676 Matrix::Multiply(modelView, modelView, viewMatrix);
1678 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1679 Matrix invertedMvp(false/*don't init*/);
1680 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1681 bool success = invertedMvp.Invert();
1683 // Convert to GL coordinates
1684 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1689 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1696 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1702 if (XyPlaneIntersect(nearPos, farPos, local))
1704 Vector3 size = GetCurrentSize();
1705 localX = local.x + size.x * 0.5f;
1706 localY = local.y + size.y * 0.5f;
1717 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1720 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1722 Mathematical Formulation
1724 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1726 ( p - c ) dot ( p - c ) = r^2
1728 Given a ray with a point of origin 'o', and a direction vector 'd':
1730 ray(t) = o + td, t >= 0
1732 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1734 (o + td - c ) dot ( o + td - c ) = r^2
1736 To solve for t we first expand the above into a more recognisable quadratic equation form
1738 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1747 B = 2( o - c ) dot d
1748 C = ( o - c ) dot ( o - c ) - r^2
1750 which can be solved using a standard quadratic formula.
1752 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1754 Practical Simplification
1756 In a renderer, we often differentiate between world space and object space. In the object space
1757 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1758 into object space, the mathematical solution presented above can be simplified significantly.
1760 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1764 and we can find the t at which the (transformed) ray intersects the sphere by
1766 ( o + td ) dot ( o + td ) = r^2
1768 According to the reasoning above, we expand the above quadratic equation into the general form
1772 which now has coefficients:
1779 // Early out if mNode is NULL
1785 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1787 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1788 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1789 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1790 rayOrigin.y - translation.y,
1791 rayOrigin.z - translation.z);
1793 // Compute the radius is not needed, square radius it's enough.
1794 const Vector3& size( mNode->GetSize( bufferIndex ) );
1796 // Scale the sphere.
1797 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1799 const float width = size.width * scale.width;
1800 const float height = size.height * scale.height;
1802 float squareSphereRadius = 0.5f * ( width * width + height * height );
1804 float a = rayDir.Dot( rayDir ); // a
1805 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1806 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1808 return ( b2*b2 - a*c ) >= 0.f;
1811 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1818 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1820 // Transforms the ray to the local reference system.
1822 // Calculate the inverse of Model matrix
1823 Matrix invModelMatrix(false/*don't init*/);
1824 // need to use the components as world matrix is only updated for actors that need it
1825 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1827 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1828 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1830 // Test with the actor's XY plane (Normal = 0 0 1 1).
1832 float a = -rayOriginLocal.z;
1833 float b = rayDirLocal.z;
1835 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1837 // Ray travels distance * rayDirLocal to intersect with plane.
1840 const Vector3& size = mNode->GetSize( bufferIndex );
1842 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1843 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1845 // Test with the actor's geometry.
1846 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1853 void Actor::SetLeaveRequired(bool required)
1855 mLeaveRequired = required;
1858 bool Actor::GetLeaveRequired() const
1860 return mLeaveRequired;
1863 void Actor::SetKeyboardFocusable( bool focusable )
1865 mKeyboardFocusable = focusable;
1868 bool Actor::IsKeyboardFocusable() const
1870 return mKeyboardFocusable;
1873 bool Actor::GetTouchRequired() const
1875 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1878 bool Actor::GetMouseWheelEventRequired() const
1880 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1883 bool Actor::IsHittable() const
1885 return IsSensitive() &&
1887 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1891 ActorGestureData& Actor::GetGestureData()
1893 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1894 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1895 if ( NULL == mGestureData )
1897 mGestureData = new ActorGestureData;
1899 return *mGestureData;
1902 bool Actor::IsGestureRequred( Gesture::Type type ) const
1904 return mGestureData && mGestureData->IsGestureRequred( type );
1907 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1909 bool consumed = false;
1911 if ( !mTouchedSignalV2.Empty() )
1913 Dali::Actor handle( this );
1914 consumed = mTouchedSignalV2.Emit( handle, event );
1919 // Notification for derived classes
1920 consumed = OnTouchEvent( event );
1926 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1928 bool consumed = false;
1930 if ( !mMouseWheelEventSignalV2.Empty() )
1932 Dali::Actor handle( this );
1933 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1938 // Notification for derived classes
1939 consumed = OnMouseWheelEvent(event);
1945 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1947 return mTouchedSignalV2;
1950 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1952 return mMouseWheelEventSignalV2;
1955 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1957 return mSetSizeSignalV2;
1960 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1962 return mOnStageSignalV2;
1965 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1967 return mOffStageSignalV2;
1970 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1972 bool connected( true );
1973 Actor* actor = dynamic_cast<Actor*>(object);
1975 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1977 actor->TouchedSignal().Connect( tracker, functor );
1979 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1981 actor->MouseWheelEventSignal().Connect( tracker, functor );
1983 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1985 actor->SetSizeSignal().Connect( tracker, functor );
1987 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1989 actor->OnStageSignal().Connect( tracker, functor );
1991 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1993 actor->OffStageSignal().Connect( tracker, functor );
1997 // signalName does not match any signal
2004 Actor::Actor( DerivedType derivedType )
2009 mParentOrigin( NULL ),
2010 mAnchorPoint( NULL ),
2011 #ifdef DYNAMICS_SUPPORT
2012 mDynamicsData( NULL ),
2014 mGestureData( NULL ),
2018 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2019 mIsRoot( ROOT_LAYER == derivedType ),
2020 mIsRenderable( RENDERABLE == derivedType ),
2021 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2022 mIsOnStage( false ),
2023 mIsDynamicsRoot(false),
2025 mLeaveRequired( false ),
2026 mKeyboardFocusable( false ),
2027 mDerivedRequiresTouch( false ),
2028 mDerivedRequiresMouseWheelEvent( false ),
2029 mOnStageSignalled( false ),
2030 mInheritRotation( true ),
2031 mInheritScale( true ),
2032 mDrawMode( DrawMode::NORMAL ),
2033 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2034 mColorMode( Node::DEFAULT_COLOR_MODE )
2038 void Actor::Initialize()
2040 mStage = Stage::GetCurrent();
2043 SceneGraph::Node* node = CreateNode();
2045 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2046 mNode = node; // Keep raw-pointer to Node
2048 if(!mDefaultPropertyLookup)
2050 mDefaultPropertyLookup = new DefaultPropertyLookup();
2052 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2054 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2065 // Remove mParent pointers from children even if we're destroying core,
2066 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2069 ActorConstIter endIter = mChildren->end();
2070 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2072 Actor& actor = GetImplementation( *iter );
2073 actor.SetParent( NULL );
2078 // Guard to allow handle destruction after Core has been destroyed
2079 if( Stage::IsInstalled() )
2083 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2084 mNode = NULL; // Node is about to be destroyed
2090 #ifdef DYNAMICS_SUPPORT
2092 delete mDynamicsData;
2095 // Cleanup optional gesture data
2096 delete mGestureData;
2098 // Cleanup optional parent origin and anchor
2099 delete mParentOrigin;
2100 delete mAnchorPoint;
2103 void Actor::ConnectToStage( Stage& stage )
2105 // This container is used instead of walking the Actor hierachy.
2106 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2107 ActorContainer connectionList;
2109 // This stage is atomic i.e. not interrupted by user callbacks
2110 RecursiveConnectToStage( stage, connectionList );
2112 // Notify applications about the newly connected actors.
2113 const ActorIter endIter = connectionList.end();
2114 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2116 Actor& actor = GetImplementation(*iter);
2117 actor.NotifyStageConnection();
2121 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2123 DALI_ASSERT_ALWAYS( !OnStage() );
2127 ConnectToSceneGraph();
2129 // Notification for internal derived classes
2130 OnStageConnectionInternal();
2132 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2133 connectionList.push_back( Dali::Actor(this) );
2135 // Recursively connect children
2138 ActorConstIter endIter = mChildren->end();
2139 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2141 Actor& actor = GetImplementation( *iter );
2142 actor.RecursiveConnectToStage( stage, connectionList );
2148 * This method is called when the Actor is connected to the Stage.
2149 * The parent must have added its Node to the scene-graph.
2150 * The child must connect its Node to the parent's Node.
2151 * This is resursive; the child calls ConnectToStage() for its children.
2153 void Actor::ConnectToSceneGraph()
2155 DALI_ASSERT_DEBUG( mNode != NULL);
2156 DALI_ASSERT_DEBUG( mParent != NULL);
2157 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2161 // Reparent Node in next Update
2162 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2167 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2171 // Effects can only be applied when the node is on-stage
2172 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2175 // Notify shader effect
2176 mShaderEffect->Connect();
2179 // Notify attachment
2182 mAttachment->Connect();
2185 #ifdef DYNAMICS_SUPPORT
2187 if( NULL != mDynamicsData )
2193 // Notification for ProxyObject::Observers
2197 void Actor::NotifyStageConnection()
2199 // Actors can be removed (in a callback), before the on-stage stage is reported.
2200 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2201 if ( OnStage() && !mOnStageSignalled )
2203 // Notification for external (CustomActor) derived classes
2204 OnStageConnectionExternal();
2206 if ( !mOnStageSignalV2.Empty() )
2208 Dali::Actor handle( this );
2209 mOnStageSignalV2.Emit( handle );
2212 // Guard against Remove during callbacks
2215 mOnStageSignalled = true; // signal required next time Actor is removed
2220 void Actor::DisconnectFromStage()
2222 // This container is used instead of walking the Actor hierachy.
2223 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2224 ActorContainer disconnectionList;
2226 // This stage is atomic i.e. not interrupted by user callbacks
2227 RecursiveDisconnectFromStage( disconnectionList );
2229 // Notify applications about the newly disconnected actors.
2230 const ActorIter endIter = disconnectionList.end();
2231 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2233 Actor& actor = GetImplementation(*iter);
2234 actor.NotifyStageDisconnection();
2238 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2240 DALI_ASSERT_ALWAYS( OnStage() );
2242 // Recursively disconnect children
2245 ActorConstIter endIter = mChildren->end();
2246 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2248 Actor& actor = GetImplementation( *iter );
2249 actor.RecursiveDisconnectFromStage( disconnectionList );
2253 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2254 disconnectionList.push_back( Dali::Actor(this) );
2256 // Notification for internal derived classes
2257 OnStageDisconnectionInternal();
2259 DisconnectFromSceneGraph();
2265 * This method is called by an actor or its parent, before a node removal message is sent.
2266 * This is recursive; the child calls DisconnectFromStage() for its children.
2268 void Actor::DisconnectFromSceneGraph()
2270 // Notification for ProxyObject::Observers
2271 OnSceneObjectRemove();
2273 // Notify shader effect
2276 mShaderEffect->Disconnect();
2279 // Notify attachment
2282 mAttachment->Disconnect();
2285 #ifdef DYNAMICS_SUPPORT
2287 if( NULL != mDynamicsData )
2289 DisconnectDynamics();
2294 void Actor::NotifyStageDisconnection()
2296 // Actors can be added (in a callback), before the off-stage state is reported.
2297 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2298 // only do this step if there is a stage, i.e. Core is not being shut down
2299 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2301 // Notification for external (CustomeActor) derived classes
2302 OnStageDisconnectionExternal();
2304 if( !mOffStageSignalV2.Empty() )
2306 Dali::Actor handle( this );
2307 mOffStageSignalV2.Emit( handle );
2310 // Guard against Add during callbacks
2313 mOnStageSignalled = false; // signal required next time Actor is added
2318 bool Actor::IsNodeConnected() const
2320 bool connected( false );
2325 if( mNode->IsRoot() || mNode->GetParent() )
2334 bool Actor::IsSceneObjectRemovable() const
2339 unsigned int Actor::GetDefaultPropertyCount() const
2341 return DEFAULT_PROPERTY_COUNT;
2344 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2346 indices.reserve( DEFAULT_PROPERTY_COUNT );
2348 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2350 indices.push_back( i );
2354 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2356 if( index < DEFAULT_PROPERTY_COUNT )
2358 return DEFAULT_PROPERTY_DETAILS[index].name;
2362 // index out of range..return empty string
2363 return String::EMPTY;
2367 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2369 Property::Index index = Property::INVALID_INDEX;
2371 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2373 // Look for name in default properties
2374 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2375 if ( mDefaultPropertyLookup->end() != result )
2377 index = result->second;
2383 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2385 if( index < DEFAULT_PROPERTY_COUNT )
2387 return DEFAULT_PROPERTY_DETAILS[index].writable;
2395 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2397 if( index < DEFAULT_PROPERTY_COUNT )
2399 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2407 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2409 if( index < DEFAULT_PROPERTY_COUNT )
2411 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2419 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2421 if( index < DEFAULT_PROPERTY_COUNT )
2423 return DEFAULT_PROPERTY_DETAILS[index].type;
2427 // index out of range...return Property::NONE
2428 return Property::NONE;
2432 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2436 case Dali::Actor::PARENT_ORIGIN:
2438 SetParentOrigin( property.Get<Vector3>() );
2442 case Dali::Actor::PARENT_ORIGIN_X:
2444 SetParentOriginX( property.Get<float>() );
2448 case Dali::Actor::PARENT_ORIGIN_Y:
2450 SetParentOriginY( property.Get<float>() );
2454 case Dali::Actor::PARENT_ORIGIN_Z:
2456 SetParentOriginZ( property.Get<float>() );
2460 case Dali::Actor::ANCHOR_POINT:
2462 SetAnchorPoint( property.Get<Vector3>() );
2466 case Dali::Actor::ANCHOR_POINT_X:
2468 SetAnchorPointX( property.Get<float>() );
2472 case Dali::Actor::ANCHOR_POINT_Y:
2474 SetAnchorPointY( property.Get<float>() );
2478 case Dali::Actor::ANCHOR_POINT_Z:
2480 SetAnchorPointZ( property.Get<float>() );
2484 case Dali::Actor::SIZE:
2486 SetSize( property.Get<Vector3>() );
2490 case Dali::Actor::SIZE_WIDTH:
2492 SetWidth( property.Get<float>() );
2496 case Dali::Actor::SIZE_HEIGHT:
2498 SetHeight( property.Get<float>() );
2502 case Dali::Actor::SIZE_DEPTH:
2504 SetDepth( property.Get<float>() );
2508 case Dali::Actor::POSITION:
2510 SetPosition( property.Get<Vector3>() );
2514 case Dali::Actor::POSITION_X:
2516 SetX( property.Get<float>() );
2520 case Dali::Actor::POSITION_Y:
2522 SetY( property.Get<float>() );
2526 case Dali::Actor::POSITION_Z:
2528 SetZ( property.Get<float>() );
2532 case Dali::Actor::ROTATION:
2534 SetRotation( property.Get<Quaternion>() );
2538 case Dali::Actor::SCALE:
2540 SetScale( property.Get<Vector3>() );
2544 case Dali::Actor::SCALE_X:
2546 SetScaleX( property.Get<float>() );
2550 case Dali::Actor::SCALE_Y:
2552 SetScaleY( property.Get<float>() );
2556 case Dali::Actor::SCALE_Z:
2558 SetScaleZ( property.Get<float>() );
2562 case Dali::Actor::VISIBLE:
2564 SetVisible( property.Get<bool>() );
2568 case Dali::Actor::COLOR:
2570 SetColor( property.Get<Vector4>() );
2574 case Dali::Actor::COLOR_RED:
2576 SetColorRed( property.Get<float>() );
2580 case Dali::Actor::COLOR_GREEN:
2582 SetColorGreen( property.Get<float>() );
2586 case Dali::Actor::COLOR_BLUE:
2588 SetColorBlue( property.Get<float>() );
2592 case Dali::Actor::COLOR_ALPHA:
2594 SetOpacity( property.Get<float>() );
2598 case Dali::Actor::NAME:
2600 SetName( property.Get<std::string>() );
2604 case Dali::Actor::SENSITIVE:
2606 SetSensitive( property.Get<bool>() );
2610 case Dali::Actor::LEAVE_REQUIRED:
2612 SetLeaveRequired( property.Get<bool>() );
2616 case Dali::Actor::INHERIT_SHADER_EFFECT:
2618 SetInheritShaderEffect( property.Get<bool>() );
2622 case Dali::Actor::INHERIT_ROTATION:
2624 SetInheritRotation( property.Get<bool>() );
2628 case Dali::Actor::INHERIT_SCALE:
2630 SetInheritScale( property.Get<bool>() );
2634 case Dali::Actor::COLOR_MODE:
2636 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2640 case Dali::Actor::POSITION_INHERITANCE:
2642 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2646 case Dali::Actor::DRAW_MODE:
2648 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2654 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2660 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2662 // TODO: This should be deprecated
2663 OnPropertySet(index, value);
2665 if(entry.IsAnimatable())
2667 // TODO: ADD MATRIX & MATRIX3 types
2669 switch ( entry.type )
2671 case Property::BOOLEAN:
2673 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2674 DALI_ASSERT_DEBUG( NULL != property );
2676 // property is being used in a separate thread; queue a message to set the property
2677 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2682 case Property::FLOAT:
2684 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2685 DALI_ASSERT_DEBUG( NULL != property );
2687 // property is being used in a separate thread; queue a message to set the property
2688 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2693 case Property::INTEGER:
2695 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2696 DALI_ASSERT_DEBUG( NULL != property );
2698 // property is being used in a separate thread; queue a message to set the property
2699 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2704 case Property::VECTOR2:
2706 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2707 DALI_ASSERT_DEBUG( NULL != property );
2709 // property is being used in a separate thread; queue a message to set the property
2710 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2715 case Property::VECTOR3:
2717 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2718 DALI_ASSERT_DEBUG( NULL != property );
2720 // property is being used in a separate thread; queue a message to set the property
2721 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2726 case Property::VECTOR4:
2728 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2729 DALI_ASSERT_DEBUG( NULL != property );
2731 // property is being used in a separate thread; queue a message to set the property
2732 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2737 case Property::ROTATION:
2739 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2740 DALI_ASSERT_DEBUG( NULL != property );
2742 // property is being used in a separate thread; queue a message to set the property
2743 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2750 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2757 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2759 Property::Value value;
2763 case Dali::Actor::PARENT_ORIGIN:
2765 value = GetCurrentParentOrigin();
2769 case Dali::Actor::PARENT_ORIGIN_X:
2771 value = GetCurrentParentOrigin().x;
2775 case Dali::Actor::PARENT_ORIGIN_Y:
2777 value = GetCurrentParentOrigin().y;
2781 case Dali::Actor::PARENT_ORIGIN_Z:
2783 value = GetCurrentParentOrigin().z;
2787 case Dali::Actor::ANCHOR_POINT:
2789 value = GetCurrentAnchorPoint();
2793 case Dali::Actor::ANCHOR_POINT_X:
2795 value = GetCurrentAnchorPoint().x;
2799 case Dali::Actor::ANCHOR_POINT_Y:
2801 value = GetCurrentAnchorPoint().y;
2805 case Dali::Actor::ANCHOR_POINT_Z:
2807 value = GetCurrentAnchorPoint().z;
2811 case Dali::Actor::SIZE:
2813 value = GetCurrentSize();
2817 case Dali::Actor::SIZE_WIDTH:
2819 value = GetCurrentSize().width;
2823 case Dali::Actor::SIZE_HEIGHT:
2825 value = GetCurrentSize().height;
2829 case Dali::Actor::SIZE_DEPTH:
2831 value = GetCurrentSize().depth;
2835 case Dali::Actor::POSITION:
2837 value = GetCurrentPosition();
2841 case Dali::Actor::POSITION_X:
2843 value = GetCurrentPosition().x;
2847 case Dali::Actor::POSITION_Y:
2849 value = GetCurrentPosition().y;
2853 case Dali::Actor::POSITION_Z:
2855 value = GetCurrentPosition().z;
2859 case Dali::Actor::WORLD_POSITION:
2861 value = GetCurrentWorldPosition();
2865 case Dali::Actor::WORLD_POSITION_X:
2867 value = GetCurrentWorldPosition().x;
2871 case Dali::Actor::WORLD_POSITION_Y:
2873 value = GetCurrentWorldPosition().y;
2877 case Dali::Actor::WORLD_POSITION_Z:
2879 value = GetCurrentWorldPosition().z;
2883 case Dali::Actor::ROTATION:
2885 value = GetCurrentRotation();
2889 case Dali::Actor::WORLD_ROTATION:
2891 value = GetCurrentWorldRotation();
2895 case Dali::Actor::SCALE:
2897 value = GetCurrentScale();
2901 case Dali::Actor::SCALE_X:
2903 value = GetCurrentScale().x;
2907 case Dali::Actor::SCALE_Y:
2909 value = GetCurrentScale().y;
2913 case Dali::Actor::SCALE_Z:
2915 value = GetCurrentScale().z;
2919 case Dali::Actor::WORLD_SCALE:
2921 value = GetCurrentWorldScale();
2925 case Dali::Actor::VISIBLE:
2927 value = IsVisible();
2931 case Dali::Actor::COLOR:
2933 value = GetCurrentColor();
2937 case Dali::Actor::COLOR_RED:
2939 value = GetCurrentColor().r;
2943 case Dali::Actor::COLOR_GREEN:
2945 value = GetCurrentColor().g;
2949 case Dali::Actor::COLOR_BLUE:
2951 value = GetCurrentColor().b;
2955 case Dali::Actor::COLOR_ALPHA:
2957 value = GetCurrentColor().a;
2961 case Dali::Actor::WORLD_COLOR:
2963 value = GetCurrentWorldColor();
2967 case Dali::Actor::WORLD_MATRIX:
2969 value = GetCurrentWorldMatrix();
2973 case Dali::Actor::NAME:
2979 case Dali::Actor::SENSITIVE:
2981 value = IsSensitive();
2985 case Dali::Actor::LEAVE_REQUIRED:
2987 value = GetLeaveRequired();
2991 case Dali::Actor::INHERIT_SHADER_EFFECT:
2993 value = GetInheritShaderEffect();
2997 case Dali::Actor::INHERIT_ROTATION:
2999 value = IsRotationInherited();
3003 case Dali::Actor::INHERIT_SCALE:
3005 value = IsScaleInherited();
3009 case Dali::Actor::COLOR_MODE:
3011 value = Scripting::GetColorMode( GetColorMode() );
3015 case Dali::Actor::POSITION_INHERITANCE:
3017 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
3021 case Dali::Actor::DRAW_MODE:
3023 value = Scripting::GetDrawMode( GetDrawMode() );
3029 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3037 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3041 // mNode is being used in a separate thread; queue a message to add the property
3042 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3046 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3048 // This method should only return an object connected to the scene-graph
3049 return OnStage() ? mNode : NULL;
3052 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3054 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3056 const PropertyBase* property( NULL );
3058 // This method should only return a property of an object connected to the scene-graph
3064 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3066 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3068 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3070 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3072 else if( NULL != mNode )
3076 case Dali::Actor::SIZE:
3077 property = &mNode->mSize;
3080 case Dali::Actor::SIZE_WIDTH:
3081 property = &mNode->mSize;
3084 case Dali::Actor::SIZE_HEIGHT:
3085 property = &mNode->mSize;
3088 case Dali::Actor::SIZE_DEPTH:
3089 property = &mNode->mSize;
3092 case Dali::Actor::POSITION:
3093 property = &mNode->mPosition;
3096 case Dali::Actor::POSITION_X:
3097 property = &mNode->mPosition;
3100 case Dali::Actor::POSITION_Y:
3101 property = &mNode->mPosition;
3104 case Dali::Actor::POSITION_Z:
3105 property = &mNode->mPosition;
3108 case Dali::Actor::ROTATION:
3109 property = &mNode->mRotation;
3112 case Dali::Actor::SCALE:
3113 property = &mNode->mScale;
3116 case Dali::Actor::SCALE_X:
3117 property = &mNode->mScale;
3120 case Dali::Actor::SCALE_Y:
3121 property = &mNode->mScale;
3124 case Dali::Actor::SCALE_Z:
3125 property = &mNode->mScale;
3128 case Dali::Actor::VISIBLE:
3129 property = &mNode->mVisible;
3132 case Dali::Actor::COLOR:
3133 property = &mNode->mColor;
3136 case Dali::Actor::COLOR_RED:
3137 property = &mNode->mColor;
3140 case Dali::Actor::COLOR_GREEN:
3141 property = &mNode->mColor;
3144 case Dali::Actor::COLOR_BLUE:
3145 property = &mNode->mColor;
3148 case Dali::Actor::COLOR_ALPHA:
3149 property = &mNode->mColor;
3160 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3162 const PropertyInputImpl* property( NULL );
3164 // This method should only return a property of an object connected to the scene-graph
3170 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3172 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3174 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3176 property = entry->second.GetSceneGraphProperty();
3178 else if( NULL != mNode )
3182 case Dali::Actor::PARENT_ORIGIN:
3183 property = &mNode->mParentOrigin;
3186 case Dali::Actor::PARENT_ORIGIN_X:
3187 property = &mNode->mParentOrigin;
3190 case Dali::Actor::PARENT_ORIGIN_Y:
3191 property = &mNode->mParentOrigin;
3194 case Dali::Actor::PARENT_ORIGIN_Z:
3195 property = &mNode->mParentOrigin;
3198 case Dali::Actor::ANCHOR_POINT:
3199 property = &mNode->mAnchorPoint;
3202 case Dali::Actor::ANCHOR_POINT_X:
3203 property = &mNode->mAnchorPoint;
3206 case Dali::Actor::ANCHOR_POINT_Y:
3207 property = &mNode->mAnchorPoint;
3210 case Dali::Actor::ANCHOR_POINT_Z:
3211 property = &mNode->mAnchorPoint;
3214 case Dali::Actor::SIZE:
3215 property = &mNode->mSize;
3218 case Dali::Actor::SIZE_WIDTH:
3219 property = &mNode->mSize;
3222 case Dali::Actor::SIZE_HEIGHT:
3223 property = &mNode->mSize;
3226 case Dali::Actor::SIZE_DEPTH:
3227 property = &mNode->mSize;
3230 case Dali::Actor::POSITION:
3231 property = &mNode->mPosition;
3234 case Dali::Actor::POSITION_X:
3235 property = &mNode->mPosition;
3238 case Dali::Actor::POSITION_Y:
3239 property = &mNode->mPosition;
3242 case Dali::Actor::POSITION_Z:
3243 property = &mNode->mPosition;
3246 case Dali::Actor::WORLD_POSITION:
3247 property = &mNode->mWorldPosition;
3250 case Dali::Actor::WORLD_POSITION_X:
3251 property = &mNode->mWorldPosition;
3254 case Dali::Actor::WORLD_POSITION_Y:
3255 property = &mNode->mWorldPosition;
3258 case Dali::Actor::WORLD_POSITION_Z:
3259 property = &mNode->mWorldPosition;
3262 case Dali::Actor::ROTATION:
3263 property = &mNode->mRotation;
3266 case Dali::Actor::WORLD_ROTATION:
3267 property = &mNode->mWorldRotation;
3270 case Dali::Actor::SCALE:
3271 property = &mNode->mScale;
3274 case Dali::Actor::SCALE_X:
3275 property = &mNode->mScale;
3278 case Dali::Actor::SCALE_Y:
3279 property = &mNode->mScale;
3282 case Dali::Actor::SCALE_Z:
3283 property = &mNode->mScale;
3286 case Dali::Actor::WORLD_SCALE:
3287 property = &mNode->mWorldScale;
3290 case Dali::Actor::VISIBLE:
3291 property = &mNode->mVisible;
3294 case Dali::Actor::COLOR:
3295 property = &mNode->mColor;
3298 case Dali::Actor::COLOR_RED:
3299 property = &mNode->mColor;
3302 case Dali::Actor::COLOR_GREEN:
3303 property = &mNode->mColor;
3306 case Dali::Actor::COLOR_BLUE:
3307 property = &mNode->mColor;
3310 case Dali::Actor::COLOR_ALPHA:
3311 property = &mNode->mColor;
3314 case Dali::Actor::WORLD_COLOR:
3315 property = &mNode->mWorldColor;
3318 case Dali::Actor::WORLD_MATRIX:
3319 property = &mNode->mWorldMatrix;
3330 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3332 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3336 case Dali::Actor::PARENT_ORIGIN_X:
3337 case Dali::Actor::ANCHOR_POINT_X:
3338 case Dali::Actor::SIZE_WIDTH:
3339 case Dali::Actor::POSITION_X:
3340 case Dali::Actor::SCALE_X:
3341 case Dali::Actor::COLOR_RED:
3342 case Dali::Actor::WORLD_POSITION_X:
3348 case Dali::Actor::PARENT_ORIGIN_Y:
3349 case Dali::Actor::ANCHOR_POINT_Y:
3350 case Dali::Actor::SIZE_HEIGHT:
3351 case Dali::Actor::POSITION_Y:
3352 case Dali::Actor::SCALE_Y:
3353 case Dali::Actor::COLOR_GREEN:
3354 case Dali::Actor::WORLD_POSITION_Y:
3360 case Dali::Actor::PARENT_ORIGIN_Z:
3361 case Dali::Actor::ANCHOR_POINT_Z:
3362 case Dali::Actor::SIZE_DEPTH:
3363 case Dali::Actor::POSITION_Z:
3364 case Dali::Actor::SCALE_Z:
3365 case Dali::Actor::COLOR_BLUE:
3366 case Dali::Actor::WORLD_POSITION_Z:
3372 case Dali::Actor::COLOR_ALPHA:
3385 return componentIndex;
3388 void Actor::SetParent(Actor* parent)
3392 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3396 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3399 StagePtr stage = parent->mStage;
3401 // Instruct each actor to create a corresponding node in the scene graph
3402 ConnectToStage(*stage);
3405 else // parent being set to NULL
3407 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3411 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3414 DALI_ASSERT_ALWAYS(mNode != NULL);
3418 // Disconnect the Node & its children from the scene-graph.
3419 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3422 // Instruct each actor to discard pointers to the scene-graph
3423 DisconnectFromStage();
3428 SceneGraph::Node* Actor::CreateNode() const
3433 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3436 Actor* actor = dynamic_cast<Actor*>(object);
3440 if(Dali::Actor::ACTION_SHOW == actionName)
3442 actor->SetVisible(true);
3445 else if(Dali::Actor::ACTION_HIDE == actionName)
3447 actor->SetVisible(false);
3455 } // namespace Internal