2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include <dali/internal/event/actors/actor-impl.h>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector3.h>
30 #include <dali/public-api/math/radian.h>
31 #include <dali/public-api/object/type-registry.h>
32 #include <dali/public-api/scripting/scripting.h>
34 #include <dali/internal/common/internal-constants.h>
35 #include <dali/internal/event/render-tasks/render-task-impl.h>
36 #include <dali/internal/event/actors/camera-actor-impl.h>
37 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
38 #include <dali/internal/event/common/property-index-ranges.h>
39 #include <dali/internal/event/common/stage-impl.h>
40 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
41 #include <dali/internal/event/animation/constraint-impl.h>
42 #include <dali/internal/event/common/projection.h>
43 #include <dali/internal/update/common/animatable-property.h>
44 #include <dali/internal/update/common/property-owner-messages.h>
45 #include <dali/internal/update/nodes/node-messages.h>
46 #include <dali/internal/update/nodes/node-declarations.h>
47 #include <dali/internal/update/animation/scene-graph-constraint.h>
48 #include <dali/internal/event/effects/shader-effect-impl.h>
49 #include <dali/internal/common/message.h>
50 #include <dali/integration-api/debug.h>
52 #ifdef DYNAMICS_SUPPORT
53 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
54 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
59 using Dali::Internal::SceneGraph::Node;
60 using Dali::Internal::SceneGraph::AnimatableProperty;
61 using Dali::Internal::SceneGraph::PropertyBase;
62 using Dali::Internal::SceneGraph::Shader;
69 const Property::Index Actor::PARENT_ORIGIN = 0;
70 const Property::Index Actor::PARENT_ORIGIN_X = 1;
71 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
72 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
73 const Property::Index Actor::ANCHOR_POINT = 4;
74 const Property::Index Actor::ANCHOR_POINT_X = 5;
75 const Property::Index Actor::ANCHOR_POINT_Y = 6;
76 const Property::Index Actor::ANCHOR_POINT_Z = 7;
77 const Property::Index Actor::SIZE = 8;
78 const Property::Index Actor::SIZE_WIDTH = 9;
79 const Property::Index Actor::SIZE_HEIGHT = 10;
80 const Property::Index Actor::SIZE_DEPTH = 11;
81 const Property::Index Actor::POSITION = 12;
82 const Property::Index Actor::POSITION_X = 13;
83 const Property::Index Actor::POSITION_Y = 14;
84 const Property::Index Actor::POSITION_Z = 15;
85 const Property::Index Actor::WORLD_POSITION = 16;
86 const Property::Index Actor::WORLD_POSITION_X = 17;
87 const Property::Index Actor::WORLD_POSITION_Y = 18;
88 const Property::Index Actor::WORLD_POSITION_Z = 19;
89 const Property::Index Actor::ROTATION = 20;
90 const Property::Index Actor::WORLD_ROTATION = 21;
91 const Property::Index Actor::SCALE = 22;
92 const Property::Index Actor::SCALE_X = 23;
93 const Property::Index Actor::SCALE_Y = 24;
94 const Property::Index Actor::SCALE_Z = 25;
95 const Property::Index Actor::WORLD_SCALE = 26;
96 const Property::Index Actor::VISIBLE = 27;
97 const Property::Index Actor::COLOR = 28;
98 const Property::Index Actor::COLOR_RED = 29;
99 const Property::Index Actor::COLOR_GREEN = 30;
100 const Property::Index Actor::COLOR_BLUE = 31;
101 const Property::Index Actor::COLOR_ALPHA = 32;
102 const Property::Index Actor::WORLD_COLOR = 33;
103 const Property::Index Actor::WORLD_MATRIX = 34;
104 const Property::Index Actor::NAME = 35;
105 const Property::Index Actor::SENSITIVE = 36;
106 const Property::Index Actor::LEAVE_REQUIRED = 37;
107 const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
108 const Property::Index Actor::INHERIT_ROTATION = 39;
109 const Property::Index Actor::INHERIT_SCALE = 40;
110 const Property::Index Actor::COLOR_MODE = 41;
111 const Property::Index Actor::POSITION_INHERITANCE = 42;
112 const Property::Index Actor::DRAW_MODE = 43;
114 namespace // unnamed namespace
118 * We want to discourage the use of property strings (minimize string comparisons),
119 * particularly for the default properties.
121 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
123 // Name Type writable animatable constraint-input
124 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
125 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
126 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
127 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
128 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
129 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
130 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
131 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
132 { "size", Property::VECTOR3, true, true, true }, // SIZE
133 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
134 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
135 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
136 { "position", Property::VECTOR3, true, true, true }, // POSITION
137 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
138 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
139 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
140 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
141 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
142 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
143 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
144 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
145 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
146 { "scale", Property::VECTOR3, true, true, true }, // SCALE
147 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
148 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
149 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
150 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
151 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
152 { "color", Property::VECTOR4, true, true, true }, // COLOR
153 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
154 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
155 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
156 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
157 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
158 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
159 { "name", Property::STRING, true, false, false }, // NAME
160 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
161 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
162 { "inherit-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
163 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
164 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
165 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
166 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
167 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
169 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
171 } // unnamed namespace
176 unsigned int Actor::mActorCounter = 0;
177 ActorContainer Actor::mNullChildren;
179 #ifdef DYNAMICS_SUPPORT
181 // Encapsulate actor related dynamics data
184 DynamicsData( Actor* slotOwner )
185 : slotDelegate( slotOwner )
189 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
190 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
192 DynamicsBodyPtr body;
193 JointContainer joints;
194 ReferencedJointContainer referencedJoints;
196 SlotDelegate< Actor > slotDelegate;
199 #endif // DYNAMICS_SUPPORT
204 using namespace Dali;
206 BaseHandle CreateActor()
208 return Dali::Actor::New();
211 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
213 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
214 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
215 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
216 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
218 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
219 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
223 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
225 ActorPtr Actor::New()
227 ActorPtr actor( new Actor( BASIC ) );
229 // Second-phase construction
235 const std::string& Actor::GetName() const
240 void Actor::SetName(const std::string& name)
246 // ATTENTION: string for debug purposes is not thread safe.
247 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
251 unsigned int Actor::GetId() const
256 void Actor::Attach( ActorAttachment& attachment )
258 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
262 attachment.Connect();
265 mAttachment = ActorAttachmentPtr(&attachment);
268 ActorAttachmentPtr Actor::GetAttachment()
273 bool Actor::OnStage() const
278 Dali::Layer Actor::GetLayer()
282 // Short-circuit for Layer derived actors
285 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
288 // Find the immediate Layer parent
289 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
291 if( parent->IsLayer() )
293 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
300 void Actor::Add(Actor& child)
302 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
303 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
307 mChildren = new ActorContainer;
310 Actor* const oldParent( child.mParent );
312 // child might already be ours
313 if( this != oldParent )
315 // if we already have parent, unparent us first
318 oldParent->Remove( child ); // This causes OnChildRemove callback
321 // Guard against Add() during previous OnChildRemove callback
322 if ( !child.mParent )
324 // Do this first, since user callbacks from within SetParent() may need to remove child
325 mChildren->push_back(Dali::Actor(&child));
327 // SetParent asserts that child can be added
328 child.SetParent(this);
330 // Notification for derived classes
336 void Actor::Remove(Actor& child)
338 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
348 // Find the child in mChildren, and unparent it
349 ActorIter end = mChildren->end();
350 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
352 Actor& actor = GetImplementation(*iter);
354 if( &actor == &child )
356 // Keep handle for OnChildRemove notification
357 removed = Dali::Actor( &actor );
359 // Do this first, since user callbacks from within SetParent() may need to add the child
360 mChildren->erase(iter);
362 DALI_ASSERT_DEBUG( actor.GetParent() == this );
363 actor.SetParent( NULL );
371 // Notification for derived classes
372 OnChildRemove( GetImplementation(removed) );
376 void Actor::Unparent()
380 mParent->Remove( *this );
384 unsigned int Actor::GetChildCount() const
386 return ( NULL != mChildren ) ? mChildren->size() : 0;
389 Dali::Actor Actor::GetChildAt(unsigned int index) const
391 DALI_ASSERT_ALWAYS( index < GetChildCount() );
393 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
396 ActorContainer Actor::GetChildren()
398 if( NULL != mChildren )
403 // return copy of mNullChildren
404 return mNullChildren;
407 const ActorContainer& Actor::GetChildren() const
409 if( NULL != mChildren )
414 // return const reference to mNullChildren
415 return mNullChildren;
418 ActorPtr Actor::FindChildByName(const std::string& actorName)
421 if (actorName == mName)
427 ActorIter end = mChildren->end();
428 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
430 child = GetImplementation(*iter).FindChildByName(actorName);
441 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
443 Dali::Actor child = DoGetChildByAlias(actorAlias);
445 // If not found then search by name.
448 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
451 child = Dali::Actor(child_ptr.Get());
458 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
460 Dali::Actor child = GetChildByAlias(actorAlias);
462 if (!child && mChildren )
464 ActorIter end = mChildren->end();
465 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
467 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
479 ActorPtr Actor::FindChildById(const unsigned int id)
488 ActorIter end = mChildren->end();
489 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
491 child = GetImplementation(*iter).FindChildById(id);
502 void Actor::SetParentOrigin( const Vector3& origin )
506 // mNode is being used in a separate thread; queue a message to set the value & base value
507 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
510 // Cache for event-thread access
513 // not allocated, check if different from default
514 if( ParentOrigin::DEFAULT != origin )
516 mParentOrigin = new Vector3( origin );
521 // check if different from current costs more than just set
522 *mParentOrigin = origin;
526 void Actor::SetParentOriginX( float x )
528 const Vector3& current = GetCurrentParentOrigin();
530 SetParentOrigin( Vector3( x, current.y, current.z ) );
533 void Actor::SetParentOriginY( float y )
535 const Vector3& current = GetCurrentParentOrigin();
537 SetParentOrigin( Vector3( current.x, y, current.z ) );
540 void Actor::SetParentOriginZ( float z )
542 const Vector3& current = GetCurrentParentOrigin();
544 SetParentOrigin( Vector3( current.x, current.y, z ) );
547 const Vector3& Actor::GetCurrentParentOrigin() const
549 // Cached for event-thread access
550 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
553 void Actor::SetAnchorPoint(const Vector3& anchor)
557 // mNode is being used in a separate thread; queue a message to set the value & base value
558 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
561 // Cache for event-thread access
564 // not allocated, check if different from default
565 if( AnchorPoint::DEFAULT != anchor )
567 mAnchorPoint = new Vector3( anchor );
572 // check if different from current costs more than just set
573 *mAnchorPoint = anchor;
577 void Actor::SetAnchorPointX( float x )
579 const Vector3& current = GetCurrentAnchorPoint();
581 SetAnchorPoint( Vector3( x, current.y, current.z ) );
584 void Actor::SetAnchorPointY( float y )
586 const Vector3& current = GetCurrentAnchorPoint();
588 SetAnchorPoint( Vector3( current.x, y, current.z ) );
591 void Actor::SetAnchorPointZ( float z )
593 const Vector3& current = GetCurrentAnchorPoint();
595 SetAnchorPoint( Vector3( current.x, current.y, z ) );
598 const Vector3& Actor::GetCurrentAnchorPoint() const
600 // Cached for event-thread access
601 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
604 void Actor::SetPosition(float x, float y)
606 SetPosition(Vector3(x, y, 0.0f));
609 void Actor::SetPosition(float x, float y, float z)
611 SetPosition(Vector3(x, y, z));
614 void Actor::SetPosition(const Vector3& position)
618 // mNode is being used in a separate thread; queue a message to set the value & base value
619 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
623 void Actor::SetX(float x)
627 // mNode is being used in a separate thread; queue a message to set the value & base value
628 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
632 void Actor::SetY(float y)
636 // mNode is being used in a separate thread; queue a message to set the value & base value
637 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
641 void Actor::SetZ(float z)
645 // mNode is being used in a separate thread; queue a message to set the value & base value
646 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
650 void Actor::MoveBy(const Vector3& distance)
654 // mNode is being used in a separate thread; queue a message to set the value & base value
655 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
659 const Vector3& Actor::GetCurrentPosition() const
663 // mNode is being used in a separate thread; copy the value from the previous update
664 return mNode->GetPosition(mStage->GetEventBufferIndex());
667 return Vector3::ZERO;
670 const Vector3& Actor::GetCurrentWorldPosition() const
674 // mNode is being used in a separate thread; copy the value from the previous update
675 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
678 return Vector3::ZERO;
681 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
683 // this flag is not animatable so keep the value
684 mPositionInheritanceMode = mode;
687 // mNode is being used in a separate thread; queue a message to set the value
688 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
692 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
694 // Cached for event-thread access
695 return mPositionInheritanceMode;
698 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
700 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
701 normalizedAxis.Normalize();
703 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
705 SetRotation(rotation);
708 void Actor::SetRotation(const Quaternion& rotation)
712 // mNode is being used in a separate thread; queue a message to set the value & base value
713 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
717 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
721 // mNode is being used in a separate thread; queue a message to set the value & base value
722 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
726 void Actor::RotateBy(const Quaternion& relativeRotation)
730 // mNode is being used in a separate thread; queue a message to set the value & base value
731 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
735 const Quaternion& Actor::GetCurrentRotation() const
739 // mNode is being used in a separate thread; copy the value from the previous update
740 return mNode->GetRotation(mStage->GetEventBufferIndex());
743 return Quaternion::IDENTITY;
746 const Quaternion& Actor::GetCurrentWorldRotation() const
750 // mNode is being used in a separate thread; copy the value from the previous update
751 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
754 return Quaternion::IDENTITY;
757 void Actor::SetScale(float scale)
759 SetScale(Vector3(scale, scale, scale));
762 void Actor::SetScale(float x, float y, float z)
764 SetScale(Vector3(x, y, z));
767 void Actor::SetScale(const Vector3& scale)
771 // mNode is being used in a separate thread; queue a message to set the value & base value
772 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
776 void Actor::SetScaleX( float x )
780 // mNode is being used in a separate thread; queue a message to set the value & base value
781 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
785 void Actor::SetScaleY( float y )
789 // mNode is being used in a separate thread; queue a message to set the value & base value
790 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
794 void Actor::SetScaleZ( float z )
798 // mNode is being used in a separate thread; queue a message to set the value & base value
799 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
803 void Actor::SetInitialVolume(const Vector3& volume)
807 // mNode is being used in a separate thread; queue a message to set the value
808 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
812 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
816 // mNode is being used in a separate thread; queue a message to set the value
817 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
821 bool Actor::GetTransmitGeometryScaling() const
825 // mNode is being used in a separate thread; copy the value from the previous update
826 return mNode->GetTransmitGeometryScaling();
832 void Actor::ScaleBy(const Vector3& relativeScale)
836 // mNode is being used in a separate thread; queue a message to set the value & base value
837 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
841 const Vector3& Actor::GetCurrentScale() const
845 // mNode is being used in a separate thread; copy the value from the previous update
846 return mNode->GetScale(mStage->GetEventBufferIndex());
852 const Vector3& Actor::GetCurrentWorldScale() const
856 // mNode is being used in a separate thread; copy the value from the previous update
857 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
863 void Actor::SetInheritScale( bool inherit )
865 // non animateable so keep local copy
866 mInheritScale = inherit;
869 // mNode is being used in a separate thread; queue a message to set the value
870 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
874 bool Actor::IsScaleInherited() const
876 return mInheritScale;
879 Matrix Actor::GetCurrentWorldMatrix() const
883 // World matrix is no longer updated unless there is something observing the node.
884 // Need to calculate it from node's world position, rotation and scale:
885 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
886 Matrix worldMatrix(false);
887 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
888 mNode->GetWorldRotation( updateBufferIndex ),
889 mNode->GetWorldPosition( updateBufferIndex ) );
893 return Matrix::IDENTITY;
896 void Actor::SetVisible(bool visible)
900 // mNode is being used in a separate thread; queue a message to set the value & base value
901 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
905 bool Actor::IsVisible() const
909 // mNode is being used in a separate thread; copy the value from the previous update
910 return mNode->IsVisible( mStage->GetEventBufferIndex() );
916 void Actor::SetOpacity(float opacity)
920 // mNode is being used in a separate thread; queue a message to set the value & base value
921 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
925 void Actor::OpacityBy(float relativeOpacity)
929 // mNode is being used in a separate thread; queue a message to set the value & base value
930 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
934 float Actor::GetCurrentOpacity() const
938 // mNode is being used in a separate thread; copy the value from the previous update
939 return mNode->GetOpacity(mStage->GetEventBufferIndex());
945 const Vector4& Actor::GetCurrentWorldColor() const
949 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
955 void Actor::SetColor(const Vector4& color)
959 // mNode is being used in a separate thread; queue a message to set the value & base value
960 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
964 void Actor::SetColorRed( float red )
968 // mNode is being used in a separate thread; queue a message to set the value & base value
969 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
973 void Actor::SetColorGreen( float green )
977 // mNode is being used in a separate thread; queue a message to set the value & base value
978 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
982 void Actor::SetColorBlue( float blue )
986 // mNode is being used in a separate thread; queue a message to set the value & base value
987 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
991 void Actor::ColorBy(const Vector4& relativeColor)
995 // mNode is being used in a separate thread; queue a message to set the value & base value
996 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1000 const Vector4& Actor::GetCurrentColor() const
1004 // mNode is being used in a separate thread; copy the value from the previous update
1005 return mNode->GetColor(mStage->GetEventBufferIndex());
1008 return Color::WHITE;
1011 void Actor::SetInheritRotation(bool inherit)
1013 // non animateable so keep local copy
1014 mInheritRotation = inherit;
1017 // mNode is being used in a separate thread; queue a message to set the value
1018 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1022 bool Actor::IsRotationInherited() const
1024 return mInheritRotation;
1027 void Actor::SetColorMode(ColorMode colorMode)
1029 // non animateable so keep local copy
1030 mColorMode = colorMode;
1033 // mNode is being used in a separate thread; queue a message to set the value
1034 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1038 ColorMode Actor::GetColorMode() const
1040 // we have cached copy
1044 void Actor::SetSize(float width, float height)
1046 SetSize( Vector2( width, height ) );
1049 void Actor::SetSize(float width, float height, float depth)
1051 SetSize( Vector3( width, height, depth ) );
1054 void Actor::SetSize(const Vector2& size)
1056 Vector3 volume( size );
1057 volume.z = std::min( size.width, size.height );
1061 void Actor::SetSize(const Vector3& size)
1065 // mNode is being used in a separate thread; queue a message to set the value & base value
1066 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1068 // Notification for derived classes
1071 // Emit signal for application developer
1073 if( !mSetSizeSignalV2.Empty() )
1075 Dali::Actor handle( this );
1076 mSetSizeSignalV2.Emit( handle, size );
1081 void Actor::SetWidth( float width )
1085 // mNode is being used in a separate thread; queue a message to set the value & base value
1086 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1090 void Actor::SetHeight( float height )
1094 // mNode is being used in a separate thread; queue a message to set the value & base value
1095 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1099 void Actor::SetDepth( float depth )
1103 // mNode is being used in a separate thread; queue a message to set the value & base value
1104 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1108 const Vector3& Actor::GetCurrentSize() const
1112 // mNode is being used in a separate thread; copy the value from the previous update
1113 return mNode->GetSize( mStage->GetEventBufferIndex() );
1116 return Vector3::ZERO;
1119 void Actor::SetInheritShaderEffect(bool inherit)
1123 // mNode is being used in a separate thread; queue a message to set the value
1124 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1128 bool Actor::GetInheritShaderEffect() const
1132 // mNode is being used in a separate thread; copy the value from the previous update
1133 return mNode->GetInheritShader();
1139 void Actor::SetShaderEffect(ShaderEffect& effect)
1145 mShaderEffect->Disconnect();
1148 mShaderEffect = ShaderEffectPtr(&effect);
1150 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1154 // mNode is being used in a separate thread; queue a message to apply shader
1155 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1158 mShaderEffect->Connect();
1162 mShaderEffect = ShaderEffectPtr(&effect);
1164 // Effects can only be applied when the Node is connected to scene-graph
1167 ShaderEffectPtr Actor::GetShaderEffect() const
1169 return mShaderEffect;
1172 void Actor::RemoveShaderEffect()
1178 // mNode is being used in a separate thread; queue a message to remove shader
1179 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1182 // Notify shader effect
1185 mShaderEffect->Disconnect();
1189 mShaderEffect.Reset();
1192 #ifdef DYNAMICS_SUPPORT
1194 //--------------- Dynamics ---------------
1196 void Actor::DisableDynamics()
1198 if( NULL != mDynamicsData )
1200 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1202 // ensure dynamics object are disconnected from scene
1203 DisconnectDynamics();
1205 // delete joint owned by this actor
1206 while( !mDynamicsData->joints.empty() )
1208 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1211 // delete other joints referencing this actor
1212 while( !mDynamicsData->referencedJoints.empty() )
1214 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1215 ActorPtr jointOwner( joint->GetActor( true ) );
1218 jointOwner->RemoveDynamicsJoint( joint );
1222 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1225 // delete the DynamicsBody object
1226 mDynamicsData->body.Reset();
1228 // Discard Dynamics data structure
1229 delete mDynamicsData;
1230 mDynamicsData = NULL;
1234 DynamicsBodyPtr Actor::GetDynamicsBody() const
1236 DynamicsBodyPtr body;
1238 if( NULL != mDynamicsData )
1240 body = mDynamicsData->body;
1246 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1248 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1250 if( NULL == mDynamicsData )
1252 mDynamicsData = new DynamicsData( this );
1255 if( !mDynamicsData->body )
1257 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1261 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1264 if( mParent == world->GetRootActor().Get() )
1266 mDynamicsData->body->Connect(*mStage);
1272 return mDynamicsData->body;
1275 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1277 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1278 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1281 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1283 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1284 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1286 DynamicsJointPtr joint;
1288 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1292 if( NULL != mDynamicsData )
1294 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1296 if( mDynamicsData->joints.end() != it )
1298 // use existing joint
1304 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1305 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1309 bodyA = EnableDynamics( new DynamicsBodyConfig );
1314 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1317 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1318 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1320 if( OnStage() && attachedActor->OnStage() )
1322 joint->Connect(*mStage);
1325 attachedActor->ReferenceJoint( joint );
1327 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1328 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1335 const int Actor::GetNumberOfJoints() const
1337 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1340 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1342 DynamicsJointPtr joint;
1344 if( NULL != mDynamicsData )
1346 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1348 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1350 for( int i = 0; i < index; ++i )
1362 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1364 DynamicsJointPtr joint;
1366 if( NULL != mDynamicsData )
1368 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1370 if( mDynamicsData->joints.end() != it )
1372 // use existing joint
1380 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1382 if( NULL != mDynamicsData )
1384 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1385 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1387 for( ; it != endIt; ++it )
1389 if( it->second == joint.Get() )
1391 ActorPtr attachedActor( it->first );
1393 if( OnStage() && attachedActor && attachedActor->OnStage() )
1395 joint->Disconnect(*mStage);
1400 attachedActor->ReleaseJoint( joint );
1401 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1402 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1405 mDynamicsData->joints.erase(it);
1412 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1414 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1416 if( NULL != mDynamicsData )
1418 mDynamicsData->referencedJoints.push_back(joint);
1422 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1424 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1426 if( NULL != mDynamicsData )
1428 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1430 if( it != mDynamicsData->referencedJoints.end() )
1432 mDynamicsData->referencedJoints.erase( it );
1437 void Actor::SetDynamicsRoot(bool flag)
1439 if( mIsDynamicsRoot != flag )
1441 mIsDynamicsRoot = flag;
1443 if( OnStage() && mChildren )
1445 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1446 ActorIter end = mChildren->end();
1447 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1449 Actor& child = GetImplementation(*iter);
1451 if( child.GetDynamicsBody() )
1453 if( mIsDynamicsRoot )
1455 child.ConnectDynamics();
1459 child.DisconnectDynamics();
1467 bool Actor::IsDynamicsRoot() const
1469 return mIsDynamicsRoot;
1472 void Actor::AttachedActorOnStage( Dali::Actor actor )
1474 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1478 ActorPtr attachedActor( &GetImplementation(actor) );
1480 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1481 if( NULL != mDynamicsData )
1483 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1484 if( mDynamicsData->joints.end() != it )
1486 DynamicsJointPtr joint( it->second );
1487 joint->Connect(*mStage);
1493 void Actor::AttachedActorOffStage( Dali::Actor actor )
1495 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1499 ActorPtr attachedActor( &GetImplementation(actor) );
1501 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1502 if( NULL != mDynamicsData )
1504 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1505 if( mDynamicsData->joints.end() != it )
1507 DynamicsJointPtr joint( it->second );
1508 joint->Disconnect(*mStage);
1514 void Actor::ConnectDynamics()
1516 if( NULL != mDynamicsData && mDynamicsData->body )
1518 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1520 mDynamicsData->body->Connect(*mStage);
1522 // Connect all joints where attachedActor is also on stage
1523 if( !mDynamicsData->joints.empty() )
1525 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1526 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1528 for( ; it != endIt; ++it )
1530 Actor* attachedActor( it->first );
1531 if( NULL != attachedActor && attachedActor->OnStage() )
1533 DynamicsJointPtr joint( it->second );
1535 joint->Connect(*mStage);
1543 void Actor::DisconnectDynamics()
1545 if( NULL != mDynamicsData && mDynamicsData->body )
1549 mDynamicsData->body->Disconnect(*mStage);
1551 // Disconnect all joints
1552 if( !mDynamicsData->joints.empty() )
1554 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1555 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1557 for( ; it != endIt; ++it )
1559 DynamicsJointPtr joint( it->second );
1561 joint->Disconnect(*mStage);
1568 #endif // DYNAMICS_SUPPORT
1570 void Actor::SetOverlay(bool enable)
1572 // Setting STENCIL will override OVERLAY
1573 if( DrawMode::STENCIL != mDrawMode )
1575 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1579 bool Actor::IsOverlay() const
1581 return ( DrawMode::OVERLAY == mDrawMode );
1584 void Actor::SetDrawMode( DrawMode::Type drawMode )
1586 // this flag is not animatable so keep the value
1587 mDrawMode = drawMode;
1590 // mNode is being used in a separate thread; queue a message to set the value
1591 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1595 DrawMode::Type Actor::GetDrawMode() const
1600 bool Actor::ScreenToLocal( float& localX,
1603 float screenY ) const
1605 // only valid when on-stage
1608 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1610 Vector2 converted( screenX, screenY );
1612 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1613 const int taskCount = taskList.GetTaskCount();
1614 for( int i = taskCount - 1; i >= 0; --i )
1616 Dali::RenderTask task = taskList.GetTask( i );
1617 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1619 // found a task where this conversion was ok so return
1627 bool Actor::ScreenToLocal( RenderTask& renderTask,
1631 float screenY ) const
1633 bool retval = false;
1634 // only valid when on-stage
1637 CameraActor* camera = renderTask.GetCameraActor();
1641 renderTask.GetViewport( viewport );
1643 // need to translate coordinates to render tasks coordinate space
1644 Vector2 converted( screenX, screenY );
1645 if( renderTask.TranslateCoordinates( converted ) )
1647 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1654 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1655 const Matrix& projectionMatrix,
1656 const Viewport& viewport,
1660 float screenY ) const
1662 // Early-out if mNode is NULL
1668 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1670 // Calculate the ModelView matrix
1671 Matrix modelView(false/*don't init*/);
1672 // need to use the components as world matrix is only updated for actors that need it
1673 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1674 Matrix::Multiply(modelView, modelView, viewMatrix);
1676 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1677 Matrix invertedMvp(false/*don't init*/);
1678 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1679 bool success = invertedMvp.Invert();
1681 // Convert to GL coordinates
1682 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1687 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1694 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1700 if (XyPlaneIntersect(nearPos, farPos, local))
1702 Vector3 size = GetCurrentSize();
1703 localX = local.x + size.x * 0.5f;
1704 localY = local.y + size.y * 0.5f;
1715 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1718 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1720 Mathematical Formulation
1722 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1724 ( p - c ) dot ( p - c ) = r^2
1726 Given a ray with a point of origin 'o', and a direction vector 'd':
1728 ray(t) = o + td, t >= 0
1730 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1732 (o + td - c ) dot ( o + td - c ) = r^2
1734 To solve for t we first expand the above into a more recognisable quadratic equation form
1736 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1745 B = 2( o - c ) dot d
1746 C = ( o - c ) dot ( o - c ) - r^2
1748 which can be solved using a standard quadratic formula.
1750 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1752 Practical Simplification
1754 In a renderer, we often differentiate between world space and object space. In the object space
1755 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1756 into object space, the mathematical solution presented above can be simplified significantly.
1758 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1762 and we can find the t at which the (transformed) ray intersects the sphere by
1764 ( o + td ) dot ( o + td ) = r^2
1766 According to the reasoning above, we expand the above quadratic equation into the general form
1770 which now has coefficients:
1777 // Early out if mNode is NULL
1783 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1785 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1786 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1787 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1788 rayOrigin.y - translation.y,
1789 rayOrigin.z - translation.z);
1791 // Compute the radius is not needed, square radius it's enough.
1792 const Vector3& size( mNode->GetSize( bufferIndex ) );
1794 // Scale the sphere.
1795 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1797 const float width = size.width * scale.width;
1798 const float height = size.height * scale.height;
1800 float squareSphereRadius = 0.5f * ( width * width + height * height );
1802 float a = rayDir.Dot( rayDir ); // a
1803 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1804 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1806 return ( b2*b2 - a*c ) >= 0.f;
1809 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1816 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1818 // Transforms the ray to the local reference system.
1820 // Calculate the inverse of Model matrix
1821 Matrix invModelMatrix(false/*don't init*/);
1822 // need to use the components as world matrix is only updated for actors that need it
1823 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1825 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1826 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1828 // Test with the actor's XY plane (Normal = 0 0 1 1).
1830 float a = -rayOriginLocal.z;
1831 float b = rayDirLocal.z;
1833 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1835 // Ray travels distance * rayDirLocal to intersect with plane.
1838 const Vector3& size = mNode->GetSize( bufferIndex );
1840 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1841 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1843 // Test with the actor's geometry.
1844 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1851 void Actor::SetLeaveRequired(bool required)
1853 mLeaveRequired = required;
1856 bool Actor::GetLeaveRequired() const
1858 return mLeaveRequired;
1861 void Actor::SetKeyboardFocusable( bool focusable )
1863 mKeyboardFocusable = focusable;
1866 bool Actor::IsKeyboardFocusable() const
1868 return mKeyboardFocusable;
1871 bool Actor::GetTouchRequired() const
1873 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1876 bool Actor::GetMouseWheelEventRequired() const
1878 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1881 bool Actor::IsHittable() const
1883 return IsSensitive() &&
1885 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1889 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1891 bool consumed = false;
1893 if ( !mTouchedSignalV2.Empty() )
1895 Dali::Actor handle( this );
1896 consumed = mTouchedSignalV2.Emit( handle, event );
1901 // Notification for derived classes
1902 consumed = OnTouchEvent( event );
1908 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1910 bool consumed = false;
1912 if ( !mMouseWheelEventSignalV2.Empty() )
1914 Dali::Actor handle( this );
1915 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1920 // Notification for derived classes
1921 consumed = OnMouseWheelEvent(event);
1927 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1929 return mTouchedSignalV2;
1932 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1934 return mMouseWheelEventSignalV2;
1937 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1939 return mSetSizeSignalV2;
1942 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1944 return mOnStageSignalV2;
1947 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1949 return mOffStageSignalV2;
1952 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1954 bool connected( true );
1955 Actor* actor = dynamic_cast<Actor*>(object);
1957 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1959 actor->TouchedSignal().Connect( tracker, functor );
1961 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1963 actor->MouseWheelEventSignal().Connect( tracker, functor );
1965 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1967 actor->SetSizeSignal().Connect( tracker, functor );
1969 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1971 actor->OnStageSignal().Connect( tracker, functor );
1973 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1975 actor->OffStageSignal().Connect( tracker, functor );
1979 // signalName does not match any signal
1986 Actor::Actor( DerivedType derivedType )
1991 mParentOrigin( NULL ),
1992 mAnchorPoint( NULL ),
1993 #ifdef DYNAMICS_SUPPORT
1994 mDynamicsData( NULL ),
1999 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2000 mIsRoot( ROOT_LAYER == derivedType ),
2001 mIsRenderable( RENDERABLE == derivedType ),
2002 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2003 mIsOnStage( false ),
2004 mIsDynamicsRoot(false),
2006 mLeaveRequired( false ),
2007 mKeyboardFocusable( false ),
2008 mDerivedRequiresTouch( false ),
2009 mDerivedRequiresMouseWheelEvent( false ),
2010 mOnStageSignalled( false ),
2011 mInheritRotation( true ),
2012 mInheritScale( true ),
2013 mDrawMode( DrawMode::NORMAL ),
2014 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2015 mColorMode( Node::DEFAULT_COLOR_MODE )
2019 void Actor::Initialize()
2021 mStage = Stage::GetCurrent();
2024 SceneGraph::Node* node = CreateNode();
2026 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2027 mNode = node; // Keep raw-pointer to Node
2029 if(!mDefaultPropertyLookup)
2031 mDefaultPropertyLookup = new DefaultPropertyLookup();
2033 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2035 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2046 // Remove mParent pointers from children even if we're destroying core,
2047 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2050 ActorConstIter endIter = mChildren->end();
2051 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2053 Actor& actor = GetImplementation( *iter );
2054 actor.SetParent( NULL );
2059 // Guard to allow handle destruction after Core has been destroyed
2060 if( Stage::IsInstalled() )
2064 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2065 mNode = NULL; // Node is about to be destroyed
2071 #ifdef DYNAMICS_SUPPORT
2073 delete mDynamicsData;
2076 // Cleanup optional parent origin and anchor
2077 delete mParentOrigin;
2078 delete mAnchorPoint;
2081 void Actor::ConnectToStage( Stage& stage )
2083 // This container is used instead of walking the Actor hierachy.
2084 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2085 ActorContainer connectionList;
2087 // This stage is atomic i.e. not interrupted by user callbacks
2088 RecursiveConnectToStage( stage, connectionList );
2090 // Notify applications about the newly connected actors.
2091 const ActorIter endIter = connectionList.end();
2092 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2094 Actor& actor = GetImplementation(*iter);
2095 actor.NotifyStageConnection();
2099 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2101 DALI_ASSERT_ALWAYS( !OnStage() );
2105 ConnectToSceneGraph();
2107 // Notification for internal derived classes
2108 OnStageConnectionInternal();
2110 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2111 connectionList.push_back( Dali::Actor(this) );
2113 // Recursively connect children
2116 ActorConstIter endIter = mChildren->end();
2117 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2119 Actor& actor = GetImplementation( *iter );
2120 actor.RecursiveConnectToStage( stage, connectionList );
2126 * This method is called when the Actor is connected to the Stage.
2127 * The parent must have added its Node to the scene-graph.
2128 * The child must connect its Node to the parent's Node.
2129 * This is resursive; the child calls ConnectToStage() for its children.
2131 void Actor::ConnectToSceneGraph()
2133 DALI_ASSERT_DEBUG( mNode != NULL);
2134 DALI_ASSERT_DEBUG( mParent != NULL);
2135 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2139 // Reparent Node in next Update
2140 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2145 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2149 // Effects can only be applied when the node is on-stage
2150 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2153 // Notify shader effect
2154 mShaderEffect->Connect();
2157 // Notify attachment
2160 mAttachment->Connect();
2163 #ifdef DYNAMICS_SUPPORT
2165 if( NULL != mDynamicsData )
2171 // Notification for ProxyObject::Observers
2175 void Actor::NotifyStageConnection()
2177 // Actors can be removed (in a callback), before the on-stage stage is reported.
2178 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2179 if ( OnStage() && !mOnStageSignalled )
2181 // Notification for external (CustomActor) derived classes
2182 OnStageConnectionExternal();
2184 if ( !mOnStageSignalV2.Empty() )
2186 Dali::Actor handle( this );
2187 mOnStageSignalV2.Emit( handle );
2190 // Guard against Remove during callbacks
2193 mOnStageSignalled = true; // signal required next time Actor is removed
2198 void Actor::DisconnectFromStage()
2200 // This container is used instead of walking the Actor hierachy.
2201 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2202 ActorContainer disconnectionList;
2204 // This stage is atomic i.e. not interrupted by user callbacks
2205 RecursiveDisconnectFromStage( disconnectionList );
2207 // Notify applications about the newly disconnected actors.
2208 const ActorIter endIter = disconnectionList.end();
2209 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2211 Actor& actor = GetImplementation(*iter);
2212 actor.NotifyStageDisconnection();
2216 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2218 DALI_ASSERT_ALWAYS( OnStage() );
2220 // Recursively disconnect children
2223 ActorConstIter endIter = mChildren->end();
2224 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2226 Actor& actor = GetImplementation( *iter );
2227 actor.RecursiveDisconnectFromStage( disconnectionList );
2231 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2232 disconnectionList.push_back( Dali::Actor(this) );
2234 // Notification for internal derived classes
2235 OnStageDisconnectionInternal();
2237 DisconnectFromSceneGraph();
2243 * This method is called by an actor or its parent, before a node removal message is sent.
2244 * This is recursive; the child calls DisconnectFromStage() for its children.
2246 void Actor::DisconnectFromSceneGraph()
2248 // Notification for ProxyObject::Observers
2249 OnSceneObjectRemove();
2251 // Notify shader effect
2254 mShaderEffect->Disconnect();
2257 // Notify attachment
2260 mAttachment->Disconnect();
2263 #ifdef DYNAMICS_SUPPORT
2265 if( NULL != mDynamicsData )
2267 DisconnectDynamics();
2272 void Actor::NotifyStageDisconnection()
2274 // Actors can be added (in a callback), before the off-stage state is reported.
2275 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2276 // only do this step if there is a stage, i.e. Core is not being shut down
2277 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2279 // Notification for external (CustomeActor) derived classes
2280 OnStageDisconnectionExternal();
2282 if( !mOffStageSignalV2.Empty() )
2284 Dali::Actor handle( this );
2285 mOffStageSignalV2.Emit( handle );
2288 // Guard against Add during callbacks
2291 mOnStageSignalled = false; // signal required next time Actor is added
2296 bool Actor::IsNodeConnected() const
2298 bool connected( false );
2303 if( mNode->IsRoot() || mNode->GetParent() )
2312 bool Actor::IsSceneObjectRemovable() const
2317 unsigned int Actor::GetDefaultPropertyCount() const
2319 return DEFAULT_PROPERTY_COUNT;
2322 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2324 indices.reserve( DEFAULT_PROPERTY_COUNT );
2326 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2328 indices.push_back( i );
2332 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2334 if( index < DEFAULT_PROPERTY_COUNT )
2336 return DEFAULT_PROPERTY_DETAILS[index].name;
2340 // index out of range..return empty string
2341 return String::EMPTY;
2345 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2347 Property::Index index = Property::INVALID_INDEX;
2349 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2351 // Look for name in default properties
2352 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2353 if ( mDefaultPropertyLookup->end() != result )
2355 index = result->second;
2361 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2363 if( index < DEFAULT_PROPERTY_COUNT )
2365 return DEFAULT_PROPERTY_DETAILS[index].writable;
2373 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2375 if( index < DEFAULT_PROPERTY_COUNT )
2377 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2385 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2387 if( index < DEFAULT_PROPERTY_COUNT )
2389 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2397 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2399 if( index < DEFAULT_PROPERTY_COUNT )
2401 return DEFAULT_PROPERTY_DETAILS[index].type;
2405 // index out of range...return Property::NONE
2406 return Property::NONE;
2410 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2414 case Dali::Actor::PARENT_ORIGIN:
2416 SetParentOrigin( property.Get<Vector3>() );
2420 case Dali::Actor::PARENT_ORIGIN_X:
2422 SetParentOriginX( property.Get<float>() );
2426 case Dali::Actor::PARENT_ORIGIN_Y:
2428 SetParentOriginY( property.Get<float>() );
2432 case Dali::Actor::PARENT_ORIGIN_Z:
2434 SetParentOriginZ( property.Get<float>() );
2438 case Dali::Actor::ANCHOR_POINT:
2440 SetAnchorPoint( property.Get<Vector3>() );
2444 case Dali::Actor::ANCHOR_POINT_X:
2446 SetAnchorPointX( property.Get<float>() );
2450 case Dali::Actor::ANCHOR_POINT_Y:
2452 SetAnchorPointY( property.Get<float>() );
2456 case Dali::Actor::ANCHOR_POINT_Z:
2458 SetAnchorPointZ( property.Get<float>() );
2462 case Dali::Actor::SIZE:
2464 SetSize( property.Get<Vector3>() );
2468 case Dali::Actor::SIZE_WIDTH:
2470 SetWidth( property.Get<float>() );
2474 case Dali::Actor::SIZE_HEIGHT:
2476 SetHeight( property.Get<float>() );
2480 case Dali::Actor::SIZE_DEPTH:
2482 SetDepth( property.Get<float>() );
2486 case Dali::Actor::POSITION:
2488 SetPosition( property.Get<Vector3>() );
2492 case Dali::Actor::POSITION_X:
2494 SetX( property.Get<float>() );
2498 case Dali::Actor::POSITION_Y:
2500 SetY( property.Get<float>() );
2504 case Dali::Actor::POSITION_Z:
2506 SetZ( property.Get<float>() );
2510 case Dali::Actor::ROTATION:
2512 SetRotation( property.Get<Quaternion>() );
2516 case Dali::Actor::SCALE:
2518 SetScale( property.Get<Vector3>() );
2522 case Dali::Actor::SCALE_X:
2524 SetScaleX( property.Get<float>() );
2528 case Dali::Actor::SCALE_Y:
2530 SetScaleY( property.Get<float>() );
2534 case Dali::Actor::SCALE_Z:
2536 SetScaleZ( property.Get<float>() );
2540 case Dali::Actor::VISIBLE:
2542 SetVisible( property.Get<bool>() );
2546 case Dali::Actor::COLOR:
2548 SetColor( property.Get<Vector4>() );
2552 case Dali::Actor::COLOR_RED:
2554 SetColorRed( property.Get<float>() );
2558 case Dali::Actor::COLOR_GREEN:
2560 SetColorGreen( property.Get<float>() );
2564 case Dali::Actor::COLOR_BLUE:
2566 SetColorBlue( property.Get<float>() );
2570 case Dali::Actor::COLOR_ALPHA:
2572 SetOpacity( property.Get<float>() );
2576 case Dali::Actor::NAME:
2578 SetName( property.Get<std::string>() );
2582 case Dali::Actor::SENSITIVE:
2584 SetSensitive( property.Get<bool>() );
2588 case Dali::Actor::LEAVE_REQUIRED:
2590 SetLeaveRequired( property.Get<bool>() );
2594 case Dali::Actor::INHERIT_SHADER_EFFECT:
2596 SetInheritShaderEffect( property.Get<bool>() );
2600 case Dali::Actor::INHERIT_ROTATION:
2602 SetInheritRotation( property.Get<bool>() );
2606 case Dali::Actor::INHERIT_SCALE:
2608 SetInheritScale( property.Get<bool>() );
2612 case Dali::Actor::COLOR_MODE:
2614 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2618 case Dali::Actor::POSITION_INHERITANCE:
2620 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2624 case Dali::Actor::DRAW_MODE:
2626 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2632 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2638 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2640 // TODO: This should be deprecated
2641 OnPropertySet(index, value);
2643 if(entry.IsAnimatable())
2645 // TODO: ADD MATRIX & MATRIX3 types
2647 switch ( entry.type )
2649 case Property::BOOLEAN:
2651 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2652 DALI_ASSERT_DEBUG( NULL != property );
2654 // property is being used in a separate thread; queue a message to set the property
2655 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2660 case Property::FLOAT:
2662 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2663 DALI_ASSERT_DEBUG( NULL != property );
2665 // property is being used in a separate thread; queue a message to set the property
2666 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2671 case Property::VECTOR2:
2673 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( 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<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2682 case Property::VECTOR3:
2684 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( 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<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2693 case Property::VECTOR4:
2695 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( 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<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2704 case Property::ROTATION:
2706 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( 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<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2717 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2724 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2726 Property::Value value;
2730 case Dali::Actor::PARENT_ORIGIN:
2732 value = GetCurrentParentOrigin();
2736 case Dali::Actor::PARENT_ORIGIN_X:
2738 value = GetCurrentParentOrigin().x;
2742 case Dali::Actor::PARENT_ORIGIN_Y:
2744 value = GetCurrentParentOrigin().y;
2748 case Dali::Actor::PARENT_ORIGIN_Z:
2750 value = GetCurrentParentOrigin().z;
2754 case Dali::Actor::ANCHOR_POINT:
2756 value = GetCurrentAnchorPoint();
2760 case Dali::Actor::ANCHOR_POINT_X:
2762 value = GetCurrentAnchorPoint().x;
2766 case Dali::Actor::ANCHOR_POINT_Y:
2768 value = GetCurrentAnchorPoint().y;
2772 case Dali::Actor::ANCHOR_POINT_Z:
2774 value = GetCurrentAnchorPoint().z;
2778 case Dali::Actor::SIZE:
2780 value = GetCurrentSize();
2784 case Dali::Actor::SIZE_WIDTH:
2786 value = GetCurrentSize().width;
2790 case Dali::Actor::SIZE_HEIGHT:
2792 value = GetCurrentSize().height;
2796 case Dali::Actor::SIZE_DEPTH:
2798 value = GetCurrentSize().depth;
2802 case Dali::Actor::POSITION:
2804 value = GetCurrentPosition();
2808 case Dali::Actor::POSITION_X:
2810 value = GetCurrentPosition().x;
2814 case Dali::Actor::POSITION_Y:
2816 value = GetCurrentPosition().y;
2820 case Dali::Actor::POSITION_Z:
2822 value = GetCurrentPosition().z;
2826 case Dali::Actor::WORLD_POSITION:
2828 value = GetCurrentWorldPosition();
2832 case Dali::Actor::WORLD_POSITION_X:
2834 value = GetCurrentWorldPosition().x;
2838 case Dali::Actor::WORLD_POSITION_Y:
2840 value = GetCurrentWorldPosition().y;
2844 case Dali::Actor::WORLD_POSITION_Z:
2846 value = GetCurrentWorldPosition().z;
2850 case Dali::Actor::ROTATION:
2852 value = GetCurrentRotation();
2856 case Dali::Actor::WORLD_ROTATION:
2858 value = GetCurrentWorldRotation();
2862 case Dali::Actor::SCALE:
2864 value = GetCurrentScale();
2868 case Dali::Actor::SCALE_X:
2870 value = GetCurrentScale().x;
2874 case Dali::Actor::SCALE_Y:
2876 value = GetCurrentScale().y;
2880 case Dali::Actor::SCALE_Z:
2882 value = GetCurrentScale().z;
2886 case Dali::Actor::WORLD_SCALE:
2888 value = GetCurrentWorldScale();
2892 case Dali::Actor::VISIBLE:
2894 value = IsVisible();
2898 case Dali::Actor::COLOR:
2900 value = GetCurrentColor();
2904 case Dali::Actor::COLOR_RED:
2906 value = GetCurrentColor().r;
2910 case Dali::Actor::COLOR_GREEN:
2912 value = GetCurrentColor().g;
2916 case Dali::Actor::COLOR_BLUE:
2918 value = GetCurrentColor().b;
2922 case Dali::Actor::COLOR_ALPHA:
2924 value = GetCurrentColor().a;
2928 case Dali::Actor::WORLD_COLOR:
2930 value = GetCurrentWorldColor();
2934 case Dali::Actor::WORLD_MATRIX:
2936 value = GetCurrentWorldMatrix();
2940 case Dali::Actor::NAME:
2946 case Dali::Actor::SENSITIVE:
2948 value = IsSensitive();
2952 case Dali::Actor::LEAVE_REQUIRED:
2954 value = GetLeaveRequired();
2958 case Dali::Actor::INHERIT_SHADER_EFFECT:
2960 value = GetInheritShaderEffect();
2964 case Dali::Actor::INHERIT_ROTATION:
2966 value = IsRotationInherited();
2970 case Dali::Actor::INHERIT_SCALE:
2972 value = IsScaleInherited();
2976 case Dali::Actor::COLOR_MODE:
2978 value = Scripting::GetColorMode( GetColorMode() );
2982 case Dali::Actor::POSITION_INHERITANCE:
2984 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2988 case Dali::Actor::DRAW_MODE:
2990 value = Scripting::GetDrawMode( GetDrawMode() );
2996 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3004 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3008 // mNode is being used in a separate thread; queue a message to add the property
3009 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3013 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3015 // This method should only return an object connected to the scene-graph
3016 return OnStage() ? mNode : NULL;
3019 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3021 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3023 const PropertyBase* property( NULL );
3025 // This method should only return a property of an object connected to the scene-graph
3031 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3033 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3035 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3037 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3039 else if( NULL != mNode )
3043 case Dali::Actor::SIZE:
3044 property = &mNode->mSize;
3047 case Dali::Actor::SIZE_WIDTH:
3048 property = &mNode->mSize;
3051 case Dali::Actor::SIZE_HEIGHT:
3052 property = &mNode->mSize;
3055 case Dali::Actor::SIZE_DEPTH:
3056 property = &mNode->mSize;
3059 case Dali::Actor::POSITION:
3060 property = &mNode->mPosition;
3063 case Dali::Actor::POSITION_X:
3064 property = &mNode->mPosition;
3067 case Dali::Actor::POSITION_Y:
3068 property = &mNode->mPosition;
3071 case Dali::Actor::POSITION_Z:
3072 property = &mNode->mPosition;
3075 case Dali::Actor::ROTATION:
3076 property = &mNode->mRotation;
3079 case Dali::Actor::SCALE:
3080 property = &mNode->mScale;
3083 case Dali::Actor::SCALE_X:
3084 property = &mNode->mScale;
3087 case Dali::Actor::SCALE_Y:
3088 property = &mNode->mScale;
3091 case Dali::Actor::SCALE_Z:
3092 property = &mNode->mScale;
3095 case Dali::Actor::VISIBLE:
3096 property = &mNode->mVisible;
3099 case Dali::Actor::COLOR:
3100 property = &mNode->mColor;
3103 case Dali::Actor::COLOR_RED:
3104 property = &mNode->mColor;
3107 case Dali::Actor::COLOR_GREEN:
3108 property = &mNode->mColor;
3111 case Dali::Actor::COLOR_BLUE:
3112 property = &mNode->mColor;
3115 case Dali::Actor::COLOR_ALPHA:
3116 property = &mNode->mColor;
3127 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3129 const PropertyInputImpl* property( NULL );
3131 // This method should only return a property of an object connected to the scene-graph
3137 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3139 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3141 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3143 property = entry->second.GetSceneGraphProperty();
3145 else if( NULL != mNode )
3149 case Dali::Actor::PARENT_ORIGIN:
3150 property = &mNode->mParentOrigin;
3153 case Dali::Actor::PARENT_ORIGIN_X:
3154 property = &mNode->mParentOrigin;
3157 case Dali::Actor::PARENT_ORIGIN_Y:
3158 property = &mNode->mParentOrigin;
3161 case Dali::Actor::PARENT_ORIGIN_Z:
3162 property = &mNode->mParentOrigin;
3165 case Dali::Actor::ANCHOR_POINT:
3166 property = &mNode->mAnchorPoint;
3169 case Dali::Actor::ANCHOR_POINT_X:
3170 property = &mNode->mAnchorPoint;
3173 case Dali::Actor::ANCHOR_POINT_Y:
3174 property = &mNode->mAnchorPoint;
3177 case Dali::Actor::ANCHOR_POINT_Z:
3178 property = &mNode->mAnchorPoint;
3181 case Dali::Actor::SIZE:
3182 property = &mNode->mSize;
3185 case Dali::Actor::SIZE_WIDTH:
3186 property = &mNode->mSize;
3189 case Dali::Actor::SIZE_HEIGHT:
3190 property = &mNode->mSize;
3193 case Dali::Actor::SIZE_DEPTH:
3194 property = &mNode->mSize;
3197 case Dali::Actor::POSITION:
3198 property = &mNode->mPosition;
3201 case Dali::Actor::POSITION_X:
3202 property = &mNode->mPosition;
3205 case Dali::Actor::POSITION_Y:
3206 property = &mNode->mPosition;
3209 case Dali::Actor::POSITION_Z:
3210 property = &mNode->mPosition;
3213 case Dali::Actor::WORLD_POSITION:
3214 property = &mNode->mWorldPosition;
3217 case Dali::Actor::WORLD_POSITION_X:
3218 property = &mNode->mWorldPosition;
3221 case Dali::Actor::WORLD_POSITION_Y:
3222 property = &mNode->mWorldPosition;
3225 case Dali::Actor::WORLD_POSITION_Z:
3226 property = &mNode->mWorldPosition;
3229 case Dali::Actor::ROTATION:
3230 property = &mNode->mRotation;
3233 case Dali::Actor::WORLD_ROTATION:
3234 property = &mNode->mWorldRotation;
3237 case Dali::Actor::SCALE:
3238 property = &mNode->mScale;
3241 case Dali::Actor::SCALE_X:
3242 property = &mNode->mScale;
3245 case Dali::Actor::SCALE_Y:
3246 property = &mNode->mScale;
3249 case Dali::Actor::SCALE_Z:
3250 property = &mNode->mScale;
3253 case Dali::Actor::WORLD_SCALE:
3254 property = &mNode->mWorldScale;
3257 case Dali::Actor::VISIBLE:
3258 property = &mNode->mVisible;
3261 case Dali::Actor::COLOR:
3262 property = &mNode->mColor;
3265 case Dali::Actor::COLOR_RED:
3266 property = &mNode->mColor;
3269 case Dali::Actor::COLOR_GREEN:
3270 property = &mNode->mColor;
3273 case Dali::Actor::COLOR_BLUE:
3274 property = &mNode->mColor;
3277 case Dali::Actor::COLOR_ALPHA:
3278 property = &mNode->mColor;
3281 case Dali::Actor::WORLD_COLOR:
3282 property = &mNode->mWorldColor;
3285 case Dali::Actor::WORLD_MATRIX:
3286 property = &mNode->mWorldMatrix;
3297 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3299 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3303 case Dali::Actor::PARENT_ORIGIN_X:
3304 case Dali::Actor::ANCHOR_POINT_X:
3305 case Dali::Actor::SIZE_WIDTH:
3306 case Dali::Actor::POSITION_X:
3307 case Dali::Actor::SCALE_X:
3308 case Dali::Actor::COLOR_RED:
3309 case Dali::Actor::WORLD_POSITION_X:
3315 case Dali::Actor::PARENT_ORIGIN_Y:
3316 case Dali::Actor::ANCHOR_POINT_Y:
3317 case Dali::Actor::SIZE_HEIGHT:
3318 case Dali::Actor::POSITION_Y:
3319 case Dali::Actor::SCALE_Y:
3320 case Dali::Actor::COLOR_GREEN:
3321 case Dali::Actor::WORLD_POSITION_Y:
3327 case Dali::Actor::PARENT_ORIGIN_Z:
3328 case Dali::Actor::ANCHOR_POINT_Z:
3329 case Dali::Actor::SIZE_DEPTH:
3330 case Dali::Actor::POSITION_Z:
3331 case Dali::Actor::SCALE_Z:
3332 case Dali::Actor::COLOR_BLUE:
3333 case Dali::Actor::WORLD_POSITION_Z:
3339 case Dali::Actor::COLOR_ALPHA:
3352 return componentIndex;
3355 void Actor::SetParent(Actor* parent)
3359 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3363 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3366 StagePtr stage = parent->mStage;
3368 // Instruct each actor to create a corresponding node in the scene graph
3369 ConnectToStage(*stage);
3372 else // parent being set to NULL
3374 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3378 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3381 DALI_ASSERT_ALWAYS(mNode != NULL);
3385 // Disconnect the Node & its children from the scene-graph.
3386 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3389 // Instruct each actor to discard pointers to the scene-graph
3390 DisconnectFromStage();
3395 SceneGraph::Node* Actor::CreateNode() const
3400 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3403 Actor* actor = dynamic_cast<Actor*>(object);
3407 if(Dali::Actor::ACTION_SHOW == actionName)
3409 actor->SetVisible(true);
3412 else if(Dali::Actor::ACTION_HIDE == actionName)
3414 actor->SetVisible(false);
3422 } // namespace Internal