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::VECTOR2:
2695 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( 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<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2704 case Property::VECTOR3:
2706 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( 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<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2715 case Property::VECTOR4:
2717 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( 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<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2726 case Property::ROTATION:
2728 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( 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<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2739 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2746 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2748 Property::Value value;
2752 case Dali::Actor::PARENT_ORIGIN:
2754 value = GetCurrentParentOrigin();
2758 case Dali::Actor::PARENT_ORIGIN_X:
2760 value = GetCurrentParentOrigin().x;
2764 case Dali::Actor::PARENT_ORIGIN_Y:
2766 value = GetCurrentParentOrigin().y;
2770 case Dali::Actor::PARENT_ORIGIN_Z:
2772 value = GetCurrentParentOrigin().z;
2776 case Dali::Actor::ANCHOR_POINT:
2778 value = GetCurrentAnchorPoint();
2782 case Dali::Actor::ANCHOR_POINT_X:
2784 value = GetCurrentAnchorPoint().x;
2788 case Dali::Actor::ANCHOR_POINT_Y:
2790 value = GetCurrentAnchorPoint().y;
2794 case Dali::Actor::ANCHOR_POINT_Z:
2796 value = GetCurrentAnchorPoint().z;
2800 case Dali::Actor::SIZE:
2802 value = GetCurrentSize();
2806 case Dali::Actor::SIZE_WIDTH:
2808 value = GetCurrentSize().width;
2812 case Dali::Actor::SIZE_HEIGHT:
2814 value = GetCurrentSize().height;
2818 case Dali::Actor::SIZE_DEPTH:
2820 value = GetCurrentSize().depth;
2824 case Dali::Actor::POSITION:
2826 value = GetCurrentPosition();
2830 case Dali::Actor::POSITION_X:
2832 value = GetCurrentPosition().x;
2836 case Dali::Actor::POSITION_Y:
2838 value = GetCurrentPosition().y;
2842 case Dali::Actor::POSITION_Z:
2844 value = GetCurrentPosition().z;
2848 case Dali::Actor::WORLD_POSITION:
2850 value = GetCurrentWorldPosition();
2854 case Dali::Actor::WORLD_POSITION_X:
2856 value = GetCurrentWorldPosition().x;
2860 case Dali::Actor::WORLD_POSITION_Y:
2862 value = GetCurrentWorldPosition().y;
2866 case Dali::Actor::WORLD_POSITION_Z:
2868 value = GetCurrentWorldPosition().z;
2872 case Dali::Actor::ROTATION:
2874 value = GetCurrentRotation();
2878 case Dali::Actor::WORLD_ROTATION:
2880 value = GetCurrentWorldRotation();
2884 case Dali::Actor::SCALE:
2886 value = GetCurrentScale();
2890 case Dali::Actor::SCALE_X:
2892 value = GetCurrentScale().x;
2896 case Dali::Actor::SCALE_Y:
2898 value = GetCurrentScale().y;
2902 case Dali::Actor::SCALE_Z:
2904 value = GetCurrentScale().z;
2908 case Dali::Actor::WORLD_SCALE:
2910 value = GetCurrentWorldScale();
2914 case Dali::Actor::VISIBLE:
2916 value = IsVisible();
2920 case Dali::Actor::COLOR:
2922 value = GetCurrentColor();
2926 case Dali::Actor::COLOR_RED:
2928 value = GetCurrentColor().r;
2932 case Dali::Actor::COLOR_GREEN:
2934 value = GetCurrentColor().g;
2938 case Dali::Actor::COLOR_BLUE:
2940 value = GetCurrentColor().b;
2944 case Dali::Actor::COLOR_ALPHA:
2946 value = GetCurrentColor().a;
2950 case Dali::Actor::WORLD_COLOR:
2952 value = GetCurrentWorldColor();
2956 case Dali::Actor::WORLD_MATRIX:
2958 value = GetCurrentWorldMatrix();
2962 case Dali::Actor::NAME:
2968 case Dali::Actor::SENSITIVE:
2970 value = IsSensitive();
2974 case Dali::Actor::LEAVE_REQUIRED:
2976 value = GetLeaveRequired();
2980 case Dali::Actor::INHERIT_SHADER_EFFECT:
2982 value = GetInheritShaderEffect();
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 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3030 // mNode is being used in a separate thread; queue a message to add the property
3031 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3035 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3037 // This method should only return an object connected to the scene-graph
3038 return OnStage() ? mNode : NULL;
3041 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3043 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3045 const PropertyBase* property( NULL );
3047 // This method should only return a property of an object connected to the scene-graph
3053 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3055 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3057 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3059 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3061 else if( NULL != mNode )
3065 case Dali::Actor::SIZE:
3066 property = &mNode->mSize;
3069 case Dali::Actor::SIZE_WIDTH:
3070 property = &mNode->mSize;
3073 case Dali::Actor::SIZE_HEIGHT:
3074 property = &mNode->mSize;
3077 case Dali::Actor::SIZE_DEPTH:
3078 property = &mNode->mSize;
3081 case Dali::Actor::POSITION:
3082 property = &mNode->mPosition;
3085 case Dali::Actor::POSITION_X:
3086 property = &mNode->mPosition;
3089 case Dali::Actor::POSITION_Y:
3090 property = &mNode->mPosition;
3093 case Dali::Actor::POSITION_Z:
3094 property = &mNode->mPosition;
3097 case Dali::Actor::ROTATION:
3098 property = &mNode->mRotation;
3101 case Dali::Actor::SCALE:
3102 property = &mNode->mScale;
3105 case Dali::Actor::SCALE_X:
3106 property = &mNode->mScale;
3109 case Dali::Actor::SCALE_Y:
3110 property = &mNode->mScale;
3113 case Dali::Actor::SCALE_Z:
3114 property = &mNode->mScale;
3117 case Dali::Actor::VISIBLE:
3118 property = &mNode->mVisible;
3121 case Dali::Actor::COLOR:
3122 property = &mNode->mColor;
3125 case Dali::Actor::COLOR_RED:
3126 property = &mNode->mColor;
3129 case Dali::Actor::COLOR_GREEN:
3130 property = &mNode->mColor;
3133 case Dali::Actor::COLOR_BLUE:
3134 property = &mNode->mColor;
3137 case Dali::Actor::COLOR_ALPHA:
3138 property = &mNode->mColor;
3149 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3151 const PropertyInputImpl* property( NULL );
3153 // This method should only return a property of an object connected to the scene-graph
3159 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3161 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3163 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3165 property = entry->second.GetSceneGraphProperty();
3167 else if( NULL != mNode )
3171 case Dali::Actor::PARENT_ORIGIN:
3172 property = &mNode->mParentOrigin;
3175 case Dali::Actor::PARENT_ORIGIN_X:
3176 property = &mNode->mParentOrigin;
3179 case Dali::Actor::PARENT_ORIGIN_Y:
3180 property = &mNode->mParentOrigin;
3183 case Dali::Actor::PARENT_ORIGIN_Z:
3184 property = &mNode->mParentOrigin;
3187 case Dali::Actor::ANCHOR_POINT:
3188 property = &mNode->mAnchorPoint;
3191 case Dali::Actor::ANCHOR_POINT_X:
3192 property = &mNode->mAnchorPoint;
3195 case Dali::Actor::ANCHOR_POINT_Y:
3196 property = &mNode->mAnchorPoint;
3199 case Dali::Actor::ANCHOR_POINT_Z:
3200 property = &mNode->mAnchorPoint;
3203 case Dali::Actor::SIZE:
3204 property = &mNode->mSize;
3207 case Dali::Actor::SIZE_WIDTH:
3208 property = &mNode->mSize;
3211 case Dali::Actor::SIZE_HEIGHT:
3212 property = &mNode->mSize;
3215 case Dali::Actor::SIZE_DEPTH:
3216 property = &mNode->mSize;
3219 case Dali::Actor::POSITION:
3220 property = &mNode->mPosition;
3223 case Dali::Actor::POSITION_X:
3224 property = &mNode->mPosition;
3227 case Dali::Actor::POSITION_Y:
3228 property = &mNode->mPosition;
3231 case Dali::Actor::POSITION_Z:
3232 property = &mNode->mPosition;
3235 case Dali::Actor::WORLD_POSITION:
3236 property = &mNode->mWorldPosition;
3239 case Dali::Actor::WORLD_POSITION_X:
3240 property = &mNode->mWorldPosition;
3243 case Dali::Actor::WORLD_POSITION_Y:
3244 property = &mNode->mWorldPosition;
3247 case Dali::Actor::WORLD_POSITION_Z:
3248 property = &mNode->mWorldPosition;
3251 case Dali::Actor::ROTATION:
3252 property = &mNode->mRotation;
3255 case Dali::Actor::WORLD_ROTATION:
3256 property = &mNode->mWorldRotation;
3259 case Dali::Actor::SCALE:
3260 property = &mNode->mScale;
3263 case Dali::Actor::SCALE_X:
3264 property = &mNode->mScale;
3267 case Dali::Actor::SCALE_Y:
3268 property = &mNode->mScale;
3271 case Dali::Actor::SCALE_Z:
3272 property = &mNode->mScale;
3275 case Dali::Actor::WORLD_SCALE:
3276 property = &mNode->mWorldScale;
3279 case Dali::Actor::VISIBLE:
3280 property = &mNode->mVisible;
3283 case Dali::Actor::COLOR:
3284 property = &mNode->mColor;
3287 case Dali::Actor::COLOR_RED:
3288 property = &mNode->mColor;
3291 case Dali::Actor::COLOR_GREEN:
3292 property = &mNode->mColor;
3295 case Dali::Actor::COLOR_BLUE:
3296 property = &mNode->mColor;
3299 case Dali::Actor::COLOR_ALPHA:
3300 property = &mNode->mColor;
3303 case Dali::Actor::WORLD_COLOR:
3304 property = &mNode->mWorldColor;
3307 case Dali::Actor::WORLD_MATRIX:
3308 property = &mNode->mWorldMatrix;
3319 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3321 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3325 case Dali::Actor::PARENT_ORIGIN_X:
3326 case Dali::Actor::ANCHOR_POINT_X:
3327 case Dali::Actor::SIZE_WIDTH:
3328 case Dali::Actor::POSITION_X:
3329 case Dali::Actor::SCALE_X:
3330 case Dali::Actor::COLOR_RED:
3331 case Dali::Actor::WORLD_POSITION_X:
3337 case Dali::Actor::PARENT_ORIGIN_Y:
3338 case Dali::Actor::ANCHOR_POINT_Y:
3339 case Dali::Actor::SIZE_HEIGHT:
3340 case Dali::Actor::POSITION_Y:
3341 case Dali::Actor::SCALE_Y:
3342 case Dali::Actor::COLOR_GREEN:
3343 case Dali::Actor::WORLD_POSITION_Y:
3349 case Dali::Actor::PARENT_ORIGIN_Z:
3350 case Dali::Actor::ANCHOR_POINT_Z:
3351 case Dali::Actor::SIZE_DEPTH:
3352 case Dali::Actor::POSITION_Z:
3353 case Dali::Actor::SCALE_Z:
3354 case Dali::Actor::COLOR_BLUE:
3355 case Dali::Actor::WORLD_POSITION_Z:
3361 case Dali::Actor::COLOR_ALPHA:
3374 return componentIndex;
3377 void Actor::SetParent(Actor* parent)
3381 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3385 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3388 StagePtr stage = parent->mStage;
3390 // Instruct each actor to create a corresponding node in the scene graph
3391 ConnectToStage(*stage);
3394 else // parent being set to NULL
3396 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3400 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3403 DALI_ASSERT_ALWAYS(mNode != NULL);
3407 // Disconnect the Node & its children from the scene-graph.
3408 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3411 // Instruct each actor to discard pointers to the scene-graph
3412 DisconnectFromStage();
3417 SceneGraph::Node* Actor::CreateNode() const
3422 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3425 Actor* actor = dynamic_cast<Actor*>(object);
3429 if(Dali::Actor::ACTION_SHOW == actionName)
3431 actor->SetVisible(true);
3434 else if(Dali::Actor::ACTION_HIDE == actionName)
3436 actor->SetVisible(false);
3444 } // namespace Internal