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/common/message.h>
51 #include <dali/integration-api/debug.h>
53 #ifdef DYNAMICS_SUPPORT
54 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
60 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::AnimatableProperty;
62 using Dali::Internal::SceneGraph::PropertyBase;
63 using Dali::Internal::SceneGraph::Shader;
70 const Property::Index Actor::PARENT_ORIGIN = 0;
71 const Property::Index Actor::PARENT_ORIGIN_X = 1;
72 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
73 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
74 const Property::Index Actor::ANCHOR_POINT = 4;
75 const Property::Index Actor::ANCHOR_POINT_X = 5;
76 const Property::Index Actor::ANCHOR_POINT_Y = 6;
77 const Property::Index Actor::ANCHOR_POINT_Z = 7;
78 const Property::Index Actor::SIZE = 8;
79 const Property::Index Actor::SIZE_WIDTH = 9;
80 const Property::Index Actor::SIZE_HEIGHT = 10;
81 const Property::Index Actor::SIZE_DEPTH = 11;
82 const Property::Index Actor::POSITION = 12;
83 const Property::Index Actor::POSITION_X = 13;
84 const Property::Index Actor::POSITION_Y = 14;
85 const Property::Index Actor::POSITION_Z = 15;
86 const Property::Index Actor::WORLD_POSITION = 16;
87 const Property::Index Actor::WORLD_POSITION_X = 17;
88 const Property::Index Actor::WORLD_POSITION_Y = 18;
89 const Property::Index Actor::WORLD_POSITION_Z = 19;
90 const Property::Index Actor::ROTATION = 20;
91 const Property::Index Actor::WORLD_ROTATION = 21;
92 const Property::Index Actor::SCALE = 22;
93 const Property::Index Actor::SCALE_X = 23;
94 const Property::Index Actor::SCALE_Y = 24;
95 const Property::Index Actor::SCALE_Z = 25;
96 const Property::Index Actor::WORLD_SCALE = 26;
97 const Property::Index Actor::VISIBLE = 27;
98 const Property::Index Actor::COLOR = 28;
99 const Property::Index Actor::COLOR_RED = 29;
100 const Property::Index Actor::COLOR_GREEN = 30;
101 const Property::Index Actor::COLOR_BLUE = 31;
102 const Property::Index Actor::COLOR_ALPHA = 32;
103 const Property::Index Actor::WORLD_COLOR = 33;
104 const Property::Index Actor::WORLD_MATRIX = 34;
105 const Property::Index Actor::NAME = 35;
106 const Property::Index Actor::SENSITIVE = 36;
107 const Property::Index Actor::LEAVE_REQUIRED = 37;
108 const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
109 const Property::Index Actor::INHERIT_ROTATION = 39;
110 const Property::Index Actor::INHERIT_SCALE = 40;
111 const Property::Index Actor::COLOR_MODE = 41;
112 const Property::Index Actor::POSITION_INHERITANCE = 42;
113 const Property::Index Actor::DRAW_MODE = 43;
115 namespace // unnamed namespace
119 * We want to discourage the use of property strings (minimize string comparisons),
120 * particularly for the default properties.
122 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
124 // Name Type writable animatable constraint-input
125 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
126 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
127 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
128 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
129 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
130 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
131 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
132 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
133 { "size", Property::VECTOR3, true, true, true }, // SIZE
134 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
135 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
136 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
137 { "position", Property::VECTOR3, true, true, true }, // POSITION
138 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
139 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
140 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
141 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
142 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
143 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
144 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
145 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
146 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
147 { "scale", Property::VECTOR3, true, true, true }, // SCALE
148 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
149 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
150 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
151 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
152 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
153 { "color", Property::VECTOR4, true, true, true }, // COLOR
154 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
155 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
156 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
157 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
158 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
159 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
160 { "name", Property::STRING, true, false, false }, // NAME
161 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
162 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
163 { "inherit-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
164 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
165 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
166 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
167 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
168 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
170 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
172 } // unnamed namespace
177 unsigned int Actor::mActorCounter = 0;
178 ActorContainer Actor::mNullChildren;
180 #ifdef DYNAMICS_SUPPORT
182 // Encapsulate actor related dynamics data
185 DynamicsData( Actor* slotOwner )
186 : slotDelegate( slotOwner )
190 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
191 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
193 DynamicsBodyPtr body;
194 JointContainer joints;
195 ReferencedJointContainer referencedJoints;
197 SlotDelegate< Actor > slotDelegate;
200 #endif // DYNAMICS_SUPPORT
205 using namespace Dali;
207 BaseHandle CreateActor()
209 return Dali::Actor::New();
212 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
214 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
215 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
216 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
217 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
219 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
220 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
224 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
226 ActorPtr Actor::New()
228 ActorPtr actor( new Actor( BASIC ) );
230 // Second-phase construction
236 const std::string& Actor::GetName() const
241 void Actor::SetName(const std::string& name)
247 // ATTENTION: string for debug purposes is not thread safe.
248 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
252 unsigned int Actor::GetId() const
257 void Actor::Attach( ActorAttachment& attachment )
259 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
263 attachment.Connect();
266 mAttachment = ActorAttachmentPtr(&attachment);
269 ActorAttachmentPtr Actor::GetAttachment()
274 bool Actor::OnStage() const
279 Dali::Layer Actor::GetLayer()
283 // Short-circuit for Layer derived actors
286 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
289 // Find the immediate Layer parent
290 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
292 if( parent->IsLayer() )
294 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
301 void Actor::Add(Actor& child)
303 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
304 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
308 mChildren = new ActorContainer;
311 Actor* const oldParent( child.mParent );
313 // child might already be ours
314 if( this != oldParent )
316 // if we already have parent, unparent us first
319 oldParent->Remove( child ); // This causes OnChildRemove callback
322 // Guard against Add() during previous OnChildRemove callback
323 if ( !child.mParent )
325 // Do this first, since user callbacks from within SetParent() may need to remove child
326 mChildren->push_back(Dali::Actor(&child));
328 // SetParent asserts that child can be added
329 child.SetParent(this);
331 // Notification for derived classes
337 void Actor::Remove(Actor& child)
339 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
349 // Find the child in mChildren, and unparent it
350 ActorIter end = mChildren->end();
351 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
353 Actor& actor = GetImplementation(*iter);
355 if( &actor == &child )
357 // Keep handle for OnChildRemove notification
358 removed = Dali::Actor( &actor );
360 // Do this first, since user callbacks from within SetParent() may need to add the child
361 mChildren->erase(iter);
363 DALI_ASSERT_DEBUG( actor.GetParent() == this );
364 actor.SetParent( NULL );
372 // Notification for derived classes
373 OnChildRemove( GetImplementation(removed) );
377 void Actor::Unparent()
381 mParent->Remove( *this );
385 unsigned int Actor::GetChildCount() const
387 return ( NULL != mChildren ) ? mChildren->size() : 0;
390 Dali::Actor Actor::GetChildAt(unsigned int index) const
392 DALI_ASSERT_ALWAYS( index < GetChildCount() );
394 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
397 ActorContainer Actor::GetChildren()
399 if( NULL != mChildren )
404 // return copy of mNullChildren
405 return mNullChildren;
408 const ActorContainer& Actor::GetChildren() const
410 if( NULL != mChildren )
415 // return const reference to mNullChildren
416 return mNullChildren;
419 ActorPtr Actor::FindChildByName(const std::string& actorName)
422 if (actorName == mName)
428 ActorIter end = mChildren->end();
429 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
431 child = GetImplementation(*iter).FindChildByName(actorName);
442 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
444 Dali::Actor child = DoGetChildByAlias(actorAlias);
446 // If not found then search by name.
449 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
452 child = Dali::Actor(child_ptr.Get());
459 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
461 Dali::Actor child = GetChildByAlias(actorAlias);
463 if (!child && mChildren )
465 ActorIter end = mChildren->end();
466 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
468 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
480 ActorPtr Actor::FindChildById(const unsigned int id)
489 ActorIter end = mChildren->end();
490 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
492 child = GetImplementation(*iter).FindChildById(id);
503 void Actor::SetParentOrigin( const Vector3& origin )
507 // mNode is being used in a separate thread; queue a message to set the value & base value
508 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
511 // Cache for event-thread access
514 // not allocated, check if different from default
515 if( ParentOrigin::DEFAULT != origin )
517 mParentOrigin = new Vector3( origin );
522 // check if different from current costs more than just set
523 *mParentOrigin = origin;
527 void Actor::SetParentOriginX( float x )
529 const Vector3& current = GetCurrentParentOrigin();
531 SetParentOrigin( Vector3( x, current.y, current.z ) );
534 void Actor::SetParentOriginY( float y )
536 const Vector3& current = GetCurrentParentOrigin();
538 SetParentOrigin( Vector3( current.x, y, current.z ) );
541 void Actor::SetParentOriginZ( float z )
543 const Vector3& current = GetCurrentParentOrigin();
545 SetParentOrigin( Vector3( current.x, current.y, z ) );
548 const Vector3& Actor::GetCurrentParentOrigin() const
550 // Cached for event-thread access
551 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
554 void Actor::SetAnchorPoint(const Vector3& anchor)
558 // mNode is being used in a separate thread; queue a message to set the value & base value
559 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
562 // Cache for event-thread access
565 // not allocated, check if different from default
566 if( AnchorPoint::DEFAULT != anchor )
568 mAnchorPoint = new Vector3( anchor );
573 // check if different from current costs more than just set
574 *mAnchorPoint = anchor;
578 void Actor::SetAnchorPointX( float x )
580 const Vector3& current = GetCurrentAnchorPoint();
582 SetAnchorPoint( Vector3( x, current.y, current.z ) );
585 void Actor::SetAnchorPointY( float y )
587 const Vector3& current = GetCurrentAnchorPoint();
589 SetAnchorPoint( Vector3( current.x, y, current.z ) );
592 void Actor::SetAnchorPointZ( float z )
594 const Vector3& current = GetCurrentAnchorPoint();
596 SetAnchorPoint( Vector3( current.x, current.y, z ) );
599 const Vector3& Actor::GetCurrentAnchorPoint() const
601 // Cached for event-thread access
602 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
605 void Actor::SetPosition(float x, float y)
607 SetPosition(Vector3(x, y, 0.0f));
610 void Actor::SetPosition(float x, float y, float z)
612 SetPosition(Vector3(x, y, z));
615 void Actor::SetPosition(const Vector3& position)
619 // mNode is being used in a separate thread; queue a message to set the value & base value
620 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
624 void Actor::SetX(float x)
628 // mNode is being used in a separate thread; queue a message to set the value & base value
629 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
633 void Actor::SetY(float y)
637 // mNode is being used in a separate thread; queue a message to set the value & base value
638 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
642 void Actor::SetZ(float z)
646 // mNode is being used in a separate thread; queue a message to set the value & base value
647 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
651 void Actor::MoveBy(const Vector3& distance)
655 // mNode is being used in a separate thread; queue a message to set the value & base value
656 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
660 const Vector3& Actor::GetCurrentPosition() const
664 // mNode is being used in a separate thread; copy the value from the previous update
665 return mNode->GetPosition(mStage->GetEventBufferIndex());
668 return Vector3::ZERO;
671 const Vector3& Actor::GetCurrentWorldPosition() const
675 // mNode is being used in a separate thread; copy the value from the previous update
676 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
679 return Vector3::ZERO;
682 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
684 // this flag is not animatable so keep the value
685 mPositionInheritanceMode = mode;
688 // mNode is being used in a separate thread; queue a message to set the value
689 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
693 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
695 // Cached for event-thread access
696 return mPositionInheritanceMode;
699 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
701 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
702 normalizedAxis.Normalize();
704 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
706 SetRotation(rotation);
709 void Actor::SetRotation(const Quaternion& rotation)
713 // mNode is being used in a separate thread; queue a message to set the value & base value
714 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
718 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
722 // mNode is being used in a separate thread; queue a message to set the value & base value
723 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
727 void Actor::RotateBy(const Quaternion& relativeRotation)
731 // mNode is being used in a separate thread; queue a message to set the value & base value
732 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
736 const Quaternion& Actor::GetCurrentRotation() const
740 // mNode is being used in a separate thread; copy the value from the previous update
741 return mNode->GetRotation(mStage->GetEventBufferIndex());
744 return Quaternion::IDENTITY;
747 const Quaternion& Actor::GetCurrentWorldRotation() const
751 // mNode is being used in a separate thread; copy the value from the previous update
752 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
755 return Quaternion::IDENTITY;
758 void Actor::SetScale(float scale)
760 SetScale(Vector3(scale, scale, scale));
763 void Actor::SetScale(float x, float y, float z)
765 SetScale(Vector3(x, y, z));
768 void Actor::SetScale(const Vector3& scale)
772 // mNode is being used in a separate thread; queue a message to set the value & base value
773 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
777 void Actor::SetScaleX( float x )
781 // mNode is being used in a separate thread; queue a message to set the value & base value
782 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
786 void Actor::SetScaleY( float y )
790 // mNode is being used in a separate thread; queue a message to set the value & base value
791 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
795 void Actor::SetScaleZ( float z )
799 // mNode is being used in a separate thread; queue a message to set the value & base value
800 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
804 void Actor::SetInitialVolume(const Vector3& volume)
808 // mNode is being used in a separate thread; queue a message to set the value
809 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
813 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
817 // mNode is being used in a separate thread; queue a message to set the value
818 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
822 bool Actor::GetTransmitGeometryScaling() const
826 // mNode is being used in a separate thread; copy the value from the previous update
827 return mNode->GetTransmitGeometryScaling();
833 void Actor::ScaleBy(const Vector3& relativeScale)
837 // mNode is being used in a separate thread; queue a message to set the value & base value
838 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
842 const Vector3& Actor::GetCurrentScale() const
846 // mNode is being used in a separate thread; copy the value from the previous update
847 return mNode->GetScale(mStage->GetEventBufferIndex());
853 const Vector3& Actor::GetCurrentWorldScale() const
857 // mNode is being used in a separate thread; copy the value from the previous update
858 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
864 void Actor::SetInheritScale( bool inherit )
866 // non animateable so keep local copy
867 mInheritScale = inherit;
870 // mNode is being used in a separate thread; queue a message to set the value
871 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
875 bool Actor::IsScaleInherited() const
877 return mInheritScale;
880 Matrix Actor::GetCurrentWorldMatrix() const
884 // World matrix is no longer updated unless there is something observing the node.
885 // Need to calculate it from node's world position, rotation and scale:
886 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
887 Matrix worldMatrix(false);
888 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
889 mNode->GetWorldRotation( updateBufferIndex ),
890 mNode->GetWorldPosition( updateBufferIndex ) );
894 return Matrix::IDENTITY;
897 void Actor::SetVisible(bool visible)
901 // mNode is being used in a separate thread; queue a message to set the value & base value
902 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
906 bool Actor::IsVisible() const
910 // mNode is being used in a separate thread; copy the value from the previous update
911 return mNode->IsVisible( mStage->GetEventBufferIndex() );
917 void Actor::SetOpacity(float opacity)
921 // mNode is being used in a separate thread; queue a message to set the value & base value
922 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
926 void Actor::OpacityBy(float relativeOpacity)
930 // mNode is being used in a separate thread; queue a message to set the value & base value
931 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
935 float Actor::GetCurrentOpacity() const
939 // mNode is being used in a separate thread; copy the value from the previous update
940 return mNode->GetOpacity(mStage->GetEventBufferIndex());
946 const Vector4& Actor::GetCurrentWorldColor() const
950 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
956 void Actor::SetColor(const Vector4& color)
960 // mNode is being used in a separate thread; queue a message to set the value & base value
961 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
965 void Actor::SetColorRed( float red )
969 // mNode is being used in a separate thread; queue a message to set the value & base value
970 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
974 void Actor::SetColorGreen( float green )
978 // mNode is being used in a separate thread; queue a message to set the value & base value
979 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
983 void Actor::SetColorBlue( float blue )
987 // mNode is being used in a separate thread; queue a message to set the value & base value
988 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
992 void Actor::ColorBy(const Vector4& relativeColor)
996 // mNode is being used in a separate thread; queue a message to set the value & base value
997 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1001 const Vector4& Actor::GetCurrentColor() const
1005 // mNode is being used in a separate thread; copy the value from the previous update
1006 return mNode->GetColor(mStage->GetEventBufferIndex());
1009 return Color::WHITE;
1012 void Actor::SetInheritRotation(bool inherit)
1014 // non animateable so keep local copy
1015 mInheritRotation = inherit;
1018 // mNode is being used in a separate thread; queue a message to set the value
1019 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1023 bool Actor::IsRotationInherited() const
1025 return mInheritRotation;
1028 void Actor::SetColorMode(ColorMode colorMode)
1030 // non animateable so keep local copy
1031 mColorMode = colorMode;
1034 // mNode is being used in a separate thread; queue a message to set the value
1035 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1039 ColorMode Actor::GetColorMode() const
1041 // we have cached copy
1045 void Actor::SetSize(float width, float height)
1047 SetSize( Vector2( width, height ) );
1050 void Actor::SetSize(float width, float height, float depth)
1052 SetSize( Vector3( width, height, depth ) );
1055 void Actor::SetSize(const Vector2& size)
1057 Vector3 volume( size );
1058 volume.z = std::min( size.width, size.height );
1062 void Actor::SetSize(const Vector3& size)
1066 // mNode is being used in a separate thread; queue a message to set the value & base value
1067 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1069 // Notification for derived classes
1072 // Emit signal for application developer
1074 if( !mSetSizeSignalV2.Empty() )
1076 Dali::Actor handle( this );
1077 mSetSizeSignalV2.Emit( handle, size );
1082 void Actor::SetWidth( float width )
1086 // mNode is being used in a separate thread; queue a message to set the value & base value
1087 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1091 void Actor::SetHeight( float height )
1095 // mNode is being used in a separate thread; queue a message to set the value & base value
1096 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1100 void Actor::SetDepth( float depth )
1104 // mNode is being used in a separate thread; queue a message to set the value & base value
1105 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1109 const Vector3& Actor::GetCurrentSize() const
1113 // mNode is being used in a separate thread; copy the value from the previous update
1114 return mNode->GetSize( mStage->GetEventBufferIndex() );
1117 return Vector3::ZERO;
1120 void Actor::SetInheritShaderEffect(bool inherit)
1124 // mNode is being used in a separate thread; queue a message to set the value
1125 SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1129 bool Actor::GetInheritShaderEffect() const
1133 // mNode is being used in a separate thread; copy the value from the previous update
1134 return mNode->GetInheritShader();
1140 void Actor::SetShaderEffect(ShaderEffect& effect)
1146 mShaderEffect->Disconnect();
1149 mShaderEffect = ShaderEffectPtr(&effect);
1151 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
1155 // mNode is being used in a separate thread; queue a message to apply shader
1156 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
1159 mShaderEffect->Connect();
1163 mShaderEffect = ShaderEffectPtr(&effect);
1165 // Effects can only be applied when the Node is connected to scene-graph
1168 ShaderEffectPtr Actor::GetShaderEffect() const
1170 return mShaderEffect;
1173 void Actor::RemoveShaderEffect()
1179 // mNode is being used in a separate thread; queue a message to remove shader
1180 RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
1183 // Notify shader effect
1186 mShaderEffect->Disconnect();
1190 mShaderEffect.Reset();
1193 #ifdef DYNAMICS_SUPPORT
1195 //--------------- Dynamics ---------------
1197 void Actor::DisableDynamics()
1199 if( NULL != mDynamicsData )
1201 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1203 // ensure dynamics object are disconnected from scene
1204 DisconnectDynamics();
1206 // delete joint owned by this actor
1207 while( !mDynamicsData->joints.empty() )
1209 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1212 // delete other joints referencing this actor
1213 while( !mDynamicsData->referencedJoints.empty() )
1215 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1216 ActorPtr jointOwner( joint->GetActor( true ) );
1219 jointOwner->RemoveDynamicsJoint( joint );
1223 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1226 // delete the DynamicsBody object
1227 mDynamicsData->body.Reset();
1229 // Discard Dynamics data structure
1230 delete mDynamicsData;
1231 mDynamicsData = NULL;
1235 DynamicsBodyPtr Actor::GetDynamicsBody() const
1237 DynamicsBodyPtr body;
1239 if( NULL != mDynamicsData )
1241 body = mDynamicsData->body;
1247 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1249 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1251 if( NULL == mDynamicsData )
1253 mDynamicsData = new DynamicsData( this );
1256 if( !mDynamicsData->body )
1258 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1262 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1265 if( mParent == world->GetRootActor().Get() )
1267 mDynamicsData->body->Connect(*mStage);
1273 return mDynamicsData->body;
1276 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1278 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1279 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1282 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1284 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1285 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1287 DynamicsJointPtr joint;
1289 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1293 if( NULL != mDynamicsData )
1295 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1297 if( mDynamicsData->joints.end() != it )
1299 // use existing joint
1305 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1306 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1310 bodyA = EnableDynamics( new DynamicsBodyConfig );
1315 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1318 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1319 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1321 if( OnStage() && attachedActor->OnStage() )
1323 joint->Connect(*mStage);
1326 attachedActor->ReferenceJoint( joint );
1328 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1329 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1336 const int Actor::GetNumberOfJoints() const
1338 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1341 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1343 DynamicsJointPtr joint;
1345 if( NULL != mDynamicsData )
1347 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1349 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1351 for( int i = 0; i < index; ++i )
1363 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1365 DynamicsJointPtr joint;
1367 if( NULL != mDynamicsData )
1369 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1371 if( mDynamicsData->joints.end() != it )
1373 // use existing joint
1381 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1383 if( NULL != mDynamicsData )
1385 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1386 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1388 for( ; it != endIt; ++it )
1390 if( it->second == joint.Get() )
1392 ActorPtr attachedActor( it->first );
1394 if( OnStage() && attachedActor && attachedActor->OnStage() )
1396 joint->Disconnect(*mStage);
1401 attachedActor->ReleaseJoint( joint );
1402 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1403 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1406 mDynamicsData->joints.erase(it);
1413 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1415 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1417 if( NULL != mDynamicsData )
1419 mDynamicsData->referencedJoints.push_back(joint);
1423 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1425 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1427 if( NULL != mDynamicsData )
1429 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1431 if( it != mDynamicsData->referencedJoints.end() )
1433 mDynamicsData->referencedJoints.erase( it );
1438 void Actor::SetDynamicsRoot(bool flag)
1440 if( mIsDynamicsRoot != flag )
1442 mIsDynamicsRoot = flag;
1444 if( OnStage() && mChildren )
1446 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1447 ActorIter end = mChildren->end();
1448 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1450 Actor& child = GetImplementation(*iter);
1452 if( child.GetDynamicsBody() )
1454 if( mIsDynamicsRoot )
1456 child.ConnectDynamics();
1460 child.DisconnectDynamics();
1468 bool Actor::IsDynamicsRoot() const
1470 return mIsDynamicsRoot;
1473 void Actor::AttachedActorOnStage( Dali::Actor actor )
1475 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1479 ActorPtr attachedActor( &GetImplementation(actor) );
1481 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1482 if( NULL != mDynamicsData )
1484 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1485 if( mDynamicsData->joints.end() != it )
1487 DynamicsJointPtr joint( it->second );
1488 joint->Connect(*mStage);
1494 void Actor::AttachedActorOffStage( Dali::Actor actor )
1496 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1500 ActorPtr attachedActor( &GetImplementation(actor) );
1502 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1503 if( NULL != mDynamicsData )
1505 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1506 if( mDynamicsData->joints.end() != it )
1508 DynamicsJointPtr joint( it->second );
1509 joint->Disconnect(*mStage);
1515 void Actor::ConnectDynamics()
1517 if( NULL != mDynamicsData && mDynamicsData->body )
1519 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1521 mDynamicsData->body->Connect(*mStage);
1523 // Connect all joints where attachedActor is also on stage
1524 if( !mDynamicsData->joints.empty() )
1526 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1527 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1529 for( ; it != endIt; ++it )
1531 Actor* attachedActor( it->first );
1532 if( NULL != attachedActor && attachedActor->OnStage() )
1534 DynamicsJointPtr joint( it->second );
1536 joint->Connect(*mStage);
1544 void Actor::DisconnectDynamics()
1546 if( NULL != mDynamicsData && mDynamicsData->body )
1550 mDynamicsData->body->Disconnect(*mStage);
1552 // Disconnect all joints
1553 if( !mDynamicsData->joints.empty() )
1555 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1556 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1558 for( ; it != endIt; ++it )
1560 DynamicsJointPtr joint( it->second );
1562 joint->Disconnect(*mStage);
1569 #endif // DYNAMICS_SUPPORT
1571 void Actor::SetOverlay(bool enable)
1573 // Setting STENCIL will override OVERLAY
1574 if( DrawMode::STENCIL != mDrawMode )
1576 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1580 bool Actor::IsOverlay() const
1582 return ( DrawMode::OVERLAY == mDrawMode );
1585 void Actor::SetDrawMode( DrawMode::Type drawMode )
1587 // this flag is not animatable so keep the value
1588 mDrawMode = drawMode;
1591 // mNode is being used in a separate thread; queue a message to set the value
1592 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1596 DrawMode::Type Actor::GetDrawMode() const
1601 bool Actor::ScreenToLocal( float& localX,
1604 float screenY ) const
1606 // only valid when on-stage
1609 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1611 Vector2 converted( screenX, screenY );
1613 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1614 const int taskCount = taskList.GetTaskCount();
1615 for( int i = taskCount - 1; i >= 0; --i )
1617 Dali::RenderTask task = taskList.GetTask( i );
1618 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1620 // found a task where this conversion was ok so return
1628 bool Actor::ScreenToLocal( RenderTask& renderTask,
1632 float screenY ) const
1634 bool retval = false;
1635 // only valid when on-stage
1638 CameraActor* camera = renderTask.GetCameraActor();
1642 renderTask.GetViewport( viewport );
1644 // need to translate coordinates to render tasks coordinate space
1645 Vector2 converted( screenX, screenY );
1646 if( renderTask.TranslateCoordinates( converted ) )
1648 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1655 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1656 const Matrix& projectionMatrix,
1657 const Viewport& viewport,
1661 float screenY ) const
1663 // Early-out if mNode is NULL
1669 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1671 // Calculate the ModelView matrix
1672 Matrix modelView(false/*don't init*/);
1673 // need to use the components as world matrix is only updated for actors that need it
1674 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1675 Matrix::Multiply(modelView, modelView, viewMatrix);
1677 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1678 Matrix invertedMvp(false/*don't init*/);
1679 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1680 bool success = invertedMvp.Invert();
1682 // Convert to GL coordinates
1683 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1688 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1695 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1701 if (XyPlaneIntersect(nearPos, farPos, local))
1703 Vector3 size = GetCurrentSize();
1704 localX = local.x + size.x * 0.5f;
1705 localY = local.y + size.y * 0.5f;
1716 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1719 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1721 Mathematical Formulation
1723 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1725 ( p - c ) dot ( p - c ) = r^2
1727 Given a ray with a point of origin 'o', and a direction vector 'd':
1729 ray(t) = o + td, t >= 0
1731 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1733 (o + td - c ) dot ( o + td - c ) = r^2
1735 To solve for t we first expand the above into a more recognisable quadratic equation form
1737 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1746 B = 2( o - c ) dot d
1747 C = ( o - c ) dot ( o - c ) - r^2
1749 which can be solved using a standard quadratic formula.
1751 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1753 Practical Simplification
1755 In a renderer, we often differentiate between world space and object space. In the object space
1756 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1757 into object space, the mathematical solution presented above can be simplified significantly.
1759 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1763 and we can find the t at which the (transformed) ray intersects the sphere by
1765 ( o + td ) dot ( o + td ) = r^2
1767 According to the reasoning above, we expand the above quadratic equation into the general form
1771 which now has coefficients:
1778 // Early out if mNode is NULL
1784 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1786 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1787 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1788 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1789 rayOrigin.y - translation.y,
1790 rayOrigin.z - translation.z);
1792 // Compute the radius is not needed, square radius it's enough.
1793 const Vector3& size( mNode->GetSize( bufferIndex ) );
1795 // Scale the sphere.
1796 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1798 const float width = size.width * scale.width;
1799 const float height = size.height * scale.height;
1801 float squareSphereRadius = 0.5f * ( width * width + height * height );
1803 float a = rayDir.Dot( rayDir ); // a
1804 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1805 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1807 return ( b2*b2 - a*c ) >= 0.f;
1810 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1817 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1819 // Transforms the ray to the local reference system.
1821 // Calculate the inverse of Model matrix
1822 Matrix invModelMatrix(false/*don't init*/);
1823 // need to use the components as world matrix is only updated for actors that need it
1824 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1826 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1827 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1829 // Test with the actor's XY plane (Normal = 0 0 1 1).
1831 float a = -rayOriginLocal.z;
1832 float b = rayDirLocal.z;
1834 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1836 // Ray travels distance * rayDirLocal to intersect with plane.
1839 const Vector3& size = mNode->GetSize( bufferIndex );
1841 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1842 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1844 // Test with the actor's geometry.
1845 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1852 void Actor::SetLeaveRequired(bool required)
1854 mLeaveRequired = required;
1857 bool Actor::GetLeaveRequired() const
1859 return mLeaveRequired;
1862 void Actor::SetKeyboardFocusable( bool focusable )
1864 mKeyboardFocusable = focusable;
1867 bool Actor::IsKeyboardFocusable() const
1869 return mKeyboardFocusable;
1872 bool Actor::GetTouchRequired() const
1874 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1877 bool Actor::GetMouseWheelEventRequired() const
1879 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1882 bool Actor::IsHittable() const
1884 return IsSensitive() &&
1886 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1890 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1892 bool consumed = false;
1894 if ( !mTouchedSignalV2.Empty() )
1896 Dali::Actor handle( this );
1897 consumed = mTouchedSignalV2.Emit( handle, event );
1902 // Notification for derived classes
1903 consumed = OnTouchEvent( event );
1909 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1911 bool consumed = false;
1913 if ( !mMouseWheelEventSignalV2.Empty() )
1915 Dali::Actor handle( this );
1916 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1921 // Notification for derived classes
1922 consumed = OnMouseWheelEvent(event);
1928 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1930 return mTouchedSignalV2;
1933 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1935 return mMouseWheelEventSignalV2;
1938 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1940 return mSetSizeSignalV2;
1943 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1945 return mOnStageSignalV2;
1948 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1950 return mOffStageSignalV2;
1953 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1955 bool connected( true );
1956 Actor* actor = dynamic_cast<Actor*>(object);
1958 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1960 actor->TouchedSignal().Connect( tracker, functor );
1962 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1964 actor->MouseWheelEventSignal().Connect( tracker, functor );
1966 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1968 actor->SetSizeSignal().Connect( tracker, functor );
1970 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1972 actor->OnStageSignal().Connect( tracker, functor );
1974 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1976 actor->OffStageSignal().Connect( tracker, functor );
1980 // signalName does not match any signal
1987 Actor::Actor( DerivedType derivedType )
1992 mParentOrigin( NULL ),
1993 mAnchorPoint( NULL ),
1994 #ifdef DYNAMICS_SUPPORT
1995 mDynamicsData( NULL ),
2000 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
2001 mIsRoot( ROOT_LAYER == derivedType ),
2002 mIsRenderable( RENDERABLE == derivedType ),
2003 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
2004 mIsOnStage( false ),
2005 mIsDynamicsRoot(false),
2007 mLeaveRequired( false ),
2008 mKeyboardFocusable( false ),
2009 mDerivedRequiresTouch( false ),
2010 mDerivedRequiresMouseWheelEvent( false ),
2011 mOnStageSignalled( false ),
2012 mInheritRotation( true ),
2013 mInheritScale( true ),
2014 mDrawMode( DrawMode::NORMAL ),
2015 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
2016 mColorMode( Node::DEFAULT_COLOR_MODE )
2020 void Actor::Initialize()
2022 mStage = Stage::GetCurrent();
2025 SceneGraph::Node* node = CreateNode();
2027 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2028 mNode = node; // Keep raw-pointer to Node
2030 if(!mDefaultPropertyLookup)
2032 mDefaultPropertyLookup = new DefaultPropertyLookup();
2034 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2036 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2047 // Remove mParent pointers from children even if we're destroying core,
2048 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2051 ActorConstIter endIter = mChildren->end();
2052 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2054 Actor& actor = GetImplementation( *iter );
2055 actor.SetParent( NULL );
2060 // Guard to allow handle destruction after Core has been destroyed
2061 if( Stage::IsInstalled() )
2065 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2066 mNode = NULL; // Node is about to be destroyed
2072 #ifdef DYNAMICS_SUPPORT
2074 delete mDynamicsData;
2077 // Cleanup optional parent origin and anchor
2078 delete mParentOrigin;
2079 delete mAnchorPoint;
2082 void Actor::ConnectToStage( Stage& stage )
2084 // This container is used instead of walking the Actor hierachy.
2085 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2086 ActorContainer connectionList;
2088 // This stage is atomic i.e. not interrupted by user callbacks
2089 RecursiveConnectToStage( stage, connectionList );
2091 // Notify applications about the newly connected actors.
2092 const ActorIter endIter = connectionList.end();
2093 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2095 Actor& actor = GetImplementation(*iter);
2096 actor.NotifyStageConnection();
2100 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2102 DALI_ASSERT_ALWAYS( !OnStage() );
2106 ConnectToSceneGraph();
2108 // Notification for internal derived classes
2109 OnStageConnectionInternal();
2111 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2112 connectionList.push_back( Dali::Actor(this) );
2114 // Recursively connect children
2117 ActorConstIter endIter = mChildren->end();
2118 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2120 Actor& actor = GetImplementation( *iter );
2121 actor.RecursiveConnectToStage( stage, connectionList );
2127 * This method is called when the Actor is connected to the Stage.
2128 * The parent must have added its Node to the scene-graph.
2129 * The child must connect its Node to the parent's Node.
2130 * This is resursive; the child calls ConnectToStage() for its children.
2132 void Actor::ConnectToSceneGraph()
2134 DALI_ASSERT_DEBUG( mNode != NULL);
2135 DALI_ASSERT_DEBUG( mParent != NULL);
2136 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2140 // Reparent Node in next Update
2141 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2146 const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
2150 // Effects can only be applied when the node is on-stage
2151 ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
2154 // Notify shader effect
2155 mShaderEffect->Connect();
2158 // Notify attachment
2161 mAttachment->Connect();
2164 #ifdef DYNAMICS_SUPPORT
2166 if( NULL != mDynamicsData )
2172 // Notification for ProxyObject::Observers
2176 void Actor::NotifyStageConnection()
2178 // Actors can be removed (in a callback), before the on-stage stage is reported.
2179 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2180 if ( OnStage() && !mOnStageSignalled )
2182 // Notification for external (CustomActor) derived classes
2183 OnStageConnectionExternal();
2185 if ( !mOnStageSignalV2.Empty() )
2187 Dali::Actor handle( this );
2188 mOnStageSignalV2.Emit( handle );
2191 // Guard against Remove during callbacks
2194 mOnStageSignalled = true; // signal required next time Actor is removed
2199 void Actor::DisconnectFromStage()
2201 // This container is used instead of walking the Actor hierachy.
2202 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2203 ActorContainer disconnectionList;
2205 // This stage is atomic i.e. not interrupted by user callbacks
2206 RecursiveDisconnectFromStage( disconnectionList );
2208 // Notify applications about the newly disconnected actors.
2209 const ActorIter endIter = disconnectionList.end();
2210 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2212 Actor& actor = GetImplementation(*iter);
2213 actor.NotifyStageDisconnection();
2217 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2219 DALI_ASSERT_ALWAYS( OnStage() );
2221 // Recursively disconnect children
2224 ActorConstIter endIter = mChildren->end();
2225 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2227 Actor& actor = GetImplementation( *iter );
2228 actor.RecursiveDisconnectFromStage( disconnectionList );
2232 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2233 disconnectionList.push_back( Dali::Actor(this) );
2235 // Notification for internal derived classes
2236 OnStageDisconnectionInternal();
2238 DisconnectFromSceneGraph();
2244 * This method is called by an actor or its parent, before a node removal message is sent.
2245 * This is recursive; the child calls DisconnectFromStage() for its children.
2247 void Actor::DisconnectFromSceneGraph()
2249 // Notification for ProxyObject::Observers
2250 OnSceneObjectRemove();
2252 // Notify shader effect
2255 mShaderEffect->Disconnect();
2258 // Notify attachment
2261 mAttachment->Disconnect();
2264 #ifdef DYNAMICS_SUPPORT
2266 if( NULL != mDynamicsData )
2268 DisconnectDynamics();
2273 void Actor::NotifyStageDisconnection()
2275 // Actors can be added (in a callback), before the off-stage state is reported.
2276 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2277 // only do this step if there is a stage, i.e. Core is not being shut down
2278 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2280 // Notification for external (CustomeActor) derived classes
2281 OnStageDisconnectionExternal();
2283 if( !mOffStageSignalV2.Empty() )
2285 Dali::Actor handle( this );
2286 mOffStageSignalV2.Emit( handle );
2289 // Guard against Add during callbacks
2292 mOnStageSignalled = false; // signal required next time Actor is added
2297 bool Actor::IsNodeConnected() const
2299 bool connected( false );
2304 if( mNode->IsRoot() || mNode->GetParent() )
2313 bool Actor::IsSceneObjectRemovable() const
2318 unsigned int Actor::GetDefaultPropertyCount() const
2320 return DEFAULT_PROPERTY_COUNT;
2323 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2325 indices.reserve( DEFAULT_PROPERTY_COUNT );
2327 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2329 indices.push_back( i );
2333 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2335 if( index < DEFAULT_PROPERTY_COUNT )
2337 return DEFAULT_PROPERTY_DETAILS[index].name;
2341 // index out of range..return empty string
2342 return String::EMPTY;
2346 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2348 Property::Index index = Property::INVALID_INDEX;
2350 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2352 // Look for name in default properties
2353 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2354 if ( mDefaultPropertyLookup->end() != result )
2356 index = result->second;
2362 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2364 if( index < DEFAULT_PROPERTY_COUNT )
2366 return DEFAULT_PROPERTY_DETAILS[index].writable;
2374 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2376 if( index < DEFAULT_PROPERTY_COUNT )
2378 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2386 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2388 if( index < DEFAULT_PROPERTY_COUNT )
2390 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2398 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2400 if( index < DEFAULT_PROPERTY_COUNT )
2402 return DEFAULT_PROPERTY_DETAILS[index].type;
2406 // index out of range...return Property::NONE
2407 return Property::NONE;
2411 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2415 case Dali::Actor::PARENT_ORIGIN:
2417 SetParentOrigin( property.Get<Vector3>() );
2421 case Dali::Actor::PARENT_ORIGIN_X:
2423 SetParentOriginX( property.Get<float>() );
2427 case Dali::Actor::PARENT_ORIGIN_Y:
2429 SetParentOriginY( property.Get<float>() );
2433 case Dali::Actor::PARENT_ORIGIN_Z:
2435 SetParentOriginZ( property.Get<float>() );
2439 case Dali::Actor::ANCHOR_POINT:
2441 SetAnchorPoint( property.Get<Vector3>() );
2445 case Dali::Actor::ANCHOR_POINT_X:
2447 SetAnchorPointX( property.Get<float>() );
2451 case Dali::Actor::ANCHOR_POINT_Y:
2453 SetAnchorPointY( property.Get<float>() );
2457 case Dali::Actor::ANCHOR_POINT_Z:
2459 SetAnchorPointZ( property.Get<float>() );
2463 case Dali::Actor::SIZE:
2465 SetSize( property.Get<Vector3>() );
2469 case Dali::Actor::SIZE_WIDTH:
2471 SetWidth( property.Get<float>() );
2475 case Dali::Actor::SIZE_HEIGHT:
2477 SetHeight( property.Get<float>() );
2481 case Dali::Actor::SIZE_DEPTH:
2483 SetDepth( property.Get<float>() );
2487 case Dali::Actor::POSITION:
2489 SetPosition( property.Get<Vector3>() );
2493 case Dali::Actor::POSITION_X:
2495 SetX( property.Get<float>() );
2499 case Dali::Actor::POSITION_Y:
2501 SetY( property.Get<float>() );
2505 case Dali::Actor::POSITION_Z:
2507 SetZ( property.Get<float>() );
2511 case Dali::Actor::ROTATION:
2513 SetRotation( property.Get<Quaternion>() );
2517 case Dali::Actor::SCALE:
2519 SetScale( property.Get<Vector3>() );
2523 case Dali::Actor::SCALE_X:
2525 SetScaleX( property.Get<float>() );
2529 case Dali::Actor::SCALE_Y:
2531 SetScaleY( property.Get<float>() );
2535 case Dali::Actor::SCALE_Z:
2537 SetScaleZ( property.Get<float>() );
2541 case Dali::Actor::VISIBLE:
2543 SetVisible( property.Get<bool>() );
2547 case Dali::Actor::COLOR:
2549 SetColor( property.Get<Vector4>() );
2553 case Dali::Actor::COLOR_RED:
2555 SetColorRed( property.Get<float>() );
2559 case Dali::Actor::COLOR_GREEN:
2561 SetColorGreen( property.Get<float>() );
2565 case Dali::Actor::COLOR_BLUE:
2567 SetColorBlue( property.Get<float>() );
2571 case Dali::Actor::COLOR_ALPHA:
2573 SetOpacity( property.Get<float>() );
2577 case Dali::Actor::NAME:
2579 SetName( property.Get<std::string>() );
2583 case Dali::Actor::SENSITIVE:
2585 SetSensitive( property.Get<bool>() );
2589 case Dali::Actor::LEAVE_REQUIRED:
2591 SetLeaveRequired( property.Get<bool>() );
2595 case Dali::Actor::INHERIT_SHADER_EFFECT:
2597 SetInheritShaderEffect( property.Get<bool>() );
2601 case Dali::Actor::INHERIT_ROTATION:
2603 SetInheritRotation( property.Get<bool>() );
2607 case Dali::Actor::INHERIT_SCALE:
2609 SetInheritScale( property.Get<bool>() );
2613 case Dali::Actor::COLOR_MODE:
2615 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2619 case Dali::Actor::POSITION_INHERITANCE:
2621 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2625 case Dali::Actor::DRAW_MODE:
2627 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2633 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2639 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2641 // TODO: This should be deprecated
2642 OnPropertySet(index, value);
2644 if(entry.IsAnimatable())
2646 // TODO: ADD MATRIX & MATRIX3 types
2648 switch ( entry.type )
2650 case Property::BOOLEAN:
2652 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2653 DALI_ASSERT_DEBUG( NULL != property );
2655 // property is being used in a separate thread; queue a message to set the property
2656 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2661 case Property::FLOAT:
2663 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2664 DALI_ASSERT_DEBUG( NULL != property );
2666 // property is being used in a separate thread; queue a message to set the property
2667 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2672 case Property::VECTOR2:
2674 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2675 DALI_ASSERT_DEBUG( NULL != property );
2677 // property is being used in a separate thread; queue a message to set the property
2678 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2683 case Property::VECTOR3:
2685 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2686 DALI_ASSERT_DEBUG( NULL != property );
2688 // property is being used in a separate thread; queue a message to set the property
2689 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2694 case Property::VECTOR4:
2696 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2697 DALI_ASSERT_DEBUG( NULL != property );
2699 // property is being used in a separate thread; queue a message to set the property
2700 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2705 case Property::ROTATION:
2707 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2708 DALI_ASSERT_DEBUG( NULL != property );
2710 // property is being used in a separate thread; queue a message to set the property
2711 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2718 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2725 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2727 Property::Value value;
2731 case Dali::Actor::PARENT_ORIGIN:
2733 value = GetCurrentParentOrigin();
2737 case Dali::Actor::PARENT_ORIGIN_X:
2739 value = GetCurrentParentOrigin().x;
2743 case Dali::Actor::PARENT_ORIGIN_Y:
2745 value = GetCurrentParentOrigin().y;
2749 case Dali::Actor::PARENT_ORIGIN_Z:
2751 value = GetCurrentParentOrigin().z;
2755 case Dali::Actor::ANCHOR_POINT:
2757 value = GetCurrentAnchorPoint();
2761 case Dali::Actor::ANCHOR_POINT_X:
2763 value = GetCurrentAnchorPoint().x;
2767 case Dali::Actor::ANCHOR_POINT_Y:
2769 value = GetCurrentAnchorPoint().y;
2773 case Dali::Actor::ANCHOR_POINT_Z:
2775 value = GetCurrentAnchorPoint().z;
2779 case Dali::Actor::SIZE:
2781 value = GetCurrentSize();
2785 case Dali::Actor::SIZE_WIDTH:
2787 value = GetCurrentSize().width;
2791 case Dali::Actor::SIZE_HEIGHT:
2793 value = GetCurrentSize().height;
2797 case Dali::Actor::SIZE_DEPTH:
2799 value = GetCurrentSize().depth;
2803 case Dali::Actor::POSITION:
2805 value = GetCurrentPosition();
2809 case Dali::Actor::POSITION_X:
2811 value = GetCurrentPosition().x;
2815 case Dali::Actor::POSITION_Y:
2817 value = GetCurrentPosition().y;
2821 case Dali::Actor::POSITION_Z:
2823 value = GetCurrentPosition().z;
2827 case Dali::Actor::WORLD_POSITION:
2829 value = GetCurrentWorldPosition();
2833 case Dali::Actor::WORLD_POSITION_X:
2835 value = GetCurrentWorldPosition().x;
2839 case Dali::Actor::WORLD_POSITION_Y:
2841 value = GetCurrentWorldPosition().y;
2845 case Dali::Actor::WORLD_POSITION_Z:
2847 value = GetCurrentWorldPosition().z;
2851 case Dali::Actor::ROTATION:
2853 value = GetCurrentRotation();
2857 case Dali::Actor::WORLD_ROTATION:
2859 value = GetCurrentWorldRotation();
2863 case Dali::Actor::SCALE:
2865 value = GetCurrentScale();
2869 case Dali::Actor::SCALE_X:
2871 value = GetCurrentScale().x;
2875 case Dali::Actor::SCALE_Y:
2877 value = GetCurrentScale().y;
2881 case Dali::Actor::SCALE_Z:
2883 value = GetCurrentScale().z;
2887 case Dali::Actor::WORLD_SCALE:
2889 value = GetCurrentWorldScale();
2893 case Dali::Actor::VISIBLE:
2895 value = IsVisible();
2899 case Dali::Actor::COLOR:
2901 value = GetCurrentColor();
2905 case Dali::Actor::COLOR_RED:
2907 value = GetCurrentColor().r;
2911 case Dali::Actor::COLOR_GREEN:
2913 value = GetCurrentColor().g;
2917 case Dali::Actor::COLOR_BLUE:
2919 value = GetCurrentColor().b;
2923 case Dali::Actor::COLOR_ALPHA:
2925 value = GetCurrentColor().a;
2929 case Dali::Actor::WORLD_COLOR:
2931 value = GetCurrentWorldColor();
2935 case Dali::Actor::WORLD_MATRIX:
2937 value = GetCurrentWorldMatrix();
2941 case Dali::Actor::NAME:
2947 case Dali::Actor::SENSITIVE:
2949 value = IsSensitive();
2953 case Dali::Actor::LEAVE_REQUIRED:
2955 value = GetLeaveRequired();
2959 case Dali::Actor::INHERIT_SHADER_EFFECT:
2961 value = GetInheritShaderEffect();
2965 case Dali::Actor::INHERIT_ROTATION:
2967 value = IsRotationInherited();
2971 case Dali::Actor::INHERIT_SCALE:
2973 value = IsScaleInherited();
2977 case Dali::Actor::COLOR_MODE:
2979 value = Scripting::GetColorMode( GetColorMode() );
2983 case Dali::Actor::POSITION_INHERITANCE:
2985 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2989 case Dali::Actor::DRAW_MODE:
2991 value = Scripting::GetDrawMode( GetDrawMode() );
2997 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
3005 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
3009 // mNode is being used in a separate thread; queue a message to add the property
3010 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
3014 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
3016 // This method should only return an object connected to the scene-graph
3017 return OnStage() ? mNode : NULL;
3020 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
3022 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
3024 const PropertyBase* property( NULL );
3026 // This method should only return a property of an object connected to the scene-graph
3032 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
3034 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3036 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3038 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3040 else if( NULL != mNode )
3044 case Dali::Actor::SIZE:
3045 property = &mNode->mSize;
3048 case Dali::Actor::SIZE_WIDTH:
3049 property = &mNode->mSize;
3052 case Dali::Actor::SIZE_HEIGHT:
3053 property = &mNode->mSize;
3056 case Dali::Actor::SIZE_DEPTH:
3057 property = &mNode->mSize;
3060 case Dali::Actor::POSITION:
3061 property = &mNode->mPosition;
3064 case Dali::Actor::POSITION_X:
3065 property = &mNode->mPosition;
3068 case Dali::Actor::POSITION_Y:
3069 property = &mNode->mPosition;
3072 case Dali::Actor::POSITION_Z:
3073 property = &mNode->mPosition;
3076 case Dali::Actor::ROTATION:
3077 property = &mNode->mRotation;
3080 case Dali::Actor::SCALE:
3081 property = &mNode->mScale;
3084 case Dali::Actor::SCALE_X:
3085 property = &mNode->mScale;
3088 case Dali::Actor::SCALE_Y:
3089 property = &mNode->mScale;
3092 case Dali::Actor::SCALE_Z:
3093 property = &mNode->mScale;
3096 case Dali::Actor::VISIBLE:
3097 property = &mNode->mVisible;
3100 case Dali::Actor::COLOR:
3101 property = &mNode->mColor;
3104 case Dali::Actor::COLOR_RED:
3105 property = &mNode->mColor;
3108 case Dali::Actor::COLOR_GREEN:
3109 property = &mNode->mColor;
3112 case Dali::Actor::COLOR_BLUE:
3113 property = &mNode->mColor;
3116 case Dali::Actor::COLOR_ALPHA:
3117 property = &mNode->mColor;
3128 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3130 const PropertyInputImpl* property( NULL );
3132 // This method should only return a property of an object connected to the scene-graph
3138 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3140 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3142 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3144 property = entry->second.GetSceneGraphProperty();
3146 else if( NULL != mNode )
3150 case Dali::Actor::PARENT_ORIGIN:
3151 property = &mNode->mParentOrigin;
3154 case Dali::Actor::PARENT_ORIGIN_X:
3155 property = &mNode->mParentOrigin;
3158 case Dali::Actor::PARENT_ORIGIN_Y:
3159 property = &mNode->mParentOrigin;
3162 case Dali::Actor::PARENT_ORIGIN_Z:
3163 property = &mNode->mParentOrigin;
3166 case Dali::Actor::ANCHOR_POINT:
3167 property = &mNode->mAnchorPoint;
3170 case Dali::Actor::ANCHOR_POINT_X:
3171 property = &mNode->mAnchorPoint;
3174 case Dali::Actor::ANCHOR_POINT_Y:
3175 property = &mNode->mAnchorPoint;
3178 case Dali::Actor::ANCHOR_POINT_Z:
3179 property = &mNode->mAnchorPoint;
3182 case Dali::Actor::SIZE:
3183 property = &mNode->mSize;
3186 case Dali::Actor::SIZE_WIDTH:
3187 property = &mNode->mSize;
3190 case Dali::Actor::SIZE_HEIGHT:
3191 property = &mNode->mSize;
3194 case Dali::Actor::SIZE_DEPTH:
3195 property = &mNode->mSize;
3198 case Dali::Actor::POSITION:
3199 property = &mNode->mPosition;
3202 case Dali::Actor::POSITION_X:
3203 property = &mNode->mPosition;
3206 case Dali::Actor::POSITION_Y:
3207 property = &mNode->mPosition;
3210 case Dali::Actor::POSITION_Z:
3211 property = &mNode->mPosition;
3214 case Dali::Actor::WORLD_POSITION:
3215 property = &mNode->mWorldPosition;
3218 case Dali::Actor::WORLD_POSITION_X:
3219 property = &mNode->mWorldPosition;
3222 case Dali::Actor::WORLD_POSITION_Y:
3223 property = &mNode->mWorldPosition;
3226 case Dali::Actor::WORLD_POSITION_Z:
3227 property = &mNode->mWorldPosition;
3230 case Dali::Actor::ROTATION:
3231 property = &mNode->mRotation;
3234 case Dali::Actor::WORLD_ROTATION:
3235 property = &mNode->mWorldRotation;
3238 case Dali::Actor::SCALE:
3239 property = &mNode->mScale;
3242 case Dali::Actor::SCALE_X:
3243 property = &mNode->mScale;
3246 case Dali::Actor::SCALE_Y:
3247 property = &mNode->mScale;
3250 case Dali::Actor::SCALE_Z:
3251 property = &mNode->mScale;
3254 case Dali::Actor::WORLD_SCALE:
3255 property = &mNode->mWorldScale;
3258 case Dali::Actor::VISIBLE:
3259 property = &mNode->mVisible;
3262 case Dali::Actor::COLOR:
3263 property = &mNode->mColor;
3266 case Dali::Actor::COLOR_RED:
3267 property = &mNode->mColor;
3270 case Dali::Actor::COLOR_GREEN:
3271 property = &mNode->mColor;
3274 case Dali::Actor::COLOR_BLUE:
3275 property = &mNode->mColor;
3278 case Dali::Actor::COLOR_ALPHA:
3279 property = &mNode->mColor;
3282 case Dali::Actor::WORLD_COLOR:
3283 property = &mNode->mWorldColor;
3286 case Dali::Actor::WORLD_MATRIX:
3287 property = &mNode->mWorldMatrix;
3298 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3300 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3304 case Dali::Actor::PARENT_ORIGIN_X:
3305 case Dali::Actor::ANCHOR_POINT_X:
3306 case Dali::Actor::SIZE_WIDTH:
3307 case Dali::Actor::POSITION_X:
3308 case Dali::Actor::SCALE_X:
3309 case Dali::Actor::COLOR_RED:
3310 case Dali::Actor::WORLD_POSITION_X:
3316 case Dali::Actor::PARENT_ORIGIN_Y:
3317 case Dali::Actor::ANCHOR_POINT_Y:
3318 case Dali::Actor::SIZE_HEIGHT:
3319 case Dali::Actor::POSITION_Y:
3320 case Dali::Actor::SCALE_Y:
3321 case Dali::Actor::COLOR_GREEN:
3322 case Dali::Actor::WORLD_POSITION_Y:
3328 case Dali::Actor::PARENT_ORIGIN_Z:
3329 case Dali::Actor::ANCHOR_POINT_Z:
3330 case Dali::Actor::SIZE_DEPTH:
3331 case Dali::Actor::POSITION_Z:
3332 case Dali::Actor::SCALE_Z:
3333 case Dali::Actor::COLOR_BLUE:
3334 case Dali::Actor::WORLD_POSITION_Z:
3340 case Dali::Actor::COLOR_ALPHA:
3353 return componentIndex;
3356 void Actor::SetParent(Actor* parent)
3360 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3364 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3367 StagePtr stage = parent->mStage;
3369 // Instruct each actor to create a corresponding node in the scene graph
3370 ConnectToStage(*stage);
3373 else // parent being set to NULL
3375 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3379 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3382 DALI_ASSERT_ALWAYS(mNode != NULL);
3386 // Disconnect the Node & its children from the scene-graph.
3387 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3390 // Instruct each actor to discard pointers to the scene-graph
3391 DisconnectFromStage();
3396 SceneGraph::Node* Actor::CreateNode() const
3401 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3404 Actor* actor = dynamic_cast<Actor*>(object);
3408 if(Dali::Actor::ACTION_SHOW == actionName)
3410 actor->SetVisible(true);
3413 else if(Dali::Actor::ACTION_HIDE == actionName)
3415 actor->SetVisible(false);
3423 } // namespace Internal