License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / dynamics / dynamics-body-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
20
21 // EXTERNAL HEADERS
22
23 // PUBLIC HEADERS
24 #include <dali/public-api/math/math-utils.h>
25
26 // INTERNAL HEADERS
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/dynamics/dynamics-body-settings.h>
29 #include <dali/internal/event/actors/actor-impl.h>
30 #include <dali/internal/event/common/stage-impl.h>
31 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
32 #include <dali/internal/event/dynamics/dynamics-shape-impl.h>
33 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
34 #include <dali/internal/update/dynamics/scene-graph-dynamics-body.h>
35 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 DynamicsBody::DynamicsBody(const std::string& name, DynamicsBodyConfigPtr config, Actor& actor, SceneGraph::Node& node )
44 : mDynamicsBody(NULL),
45   mName(name),
46   mMass(0.0f),
47   mElasticity(0.0f),
48   mKinematic(false),
49   mSleepEnabled(true),
50   mActor(actor)
51 {
52   DALI_ASSERT_DEBUG(config);
53
54   StagePtr stage( Stage::GetCurrent() );
55
56   DynamicsWorldPtr world( stage->GetDynamicsWorld() );
57
58   mDynamicsBody = new SceneGraph::DynamicsBody( *(world->GetSceneObject()), node );
59
60   mShape = config->GetShape();
61
62   Integration::DynamicsBodySettings* settings( new Integration::DynamicsBodySettings(*config->GetSettings()) ); // copy settings
63   SceneGraph::DynamicsShape* sceneShape( mShape->GetSceneObject() );
64   InitializeDynamicsBodyMessage( stage->GetUpdateInterface(), *mDynamicsBody, settings, *sceneShape );
65
66   SetMass( config->GetMass() );
67   SetElasticity( config->GetElasticity() );
68
69   short int collisionGroup( config->GetCollisionGroup() );
70   short int collisionMask( config->GetCollisionMask() );
71   if( !config->IsCollisionFilterSet() )
72   {
73     if( EqualsZero( config->GetMass() ) )
74     {
75       // static body and default collision filter has not been overwritten
76       collisionGroup = Dali::DynamicsBodyConfig::COLLISION_FILTER_STATIC;
77       collisionMask = Dali::DynamicsBodyConfig::COLLISION_FILTER_ALL ^ Dali::DynamicsBodyConfig::COLLISION_FILTER_STATIC;
78     }
79   }
80
81   SetCollisionGroupMessage( stage->GetUpdateInterface(), *mDynamicsBody, collisionGroup );
82   SetCollisionMaskMessage( stage->GetUpdateInterface(), *mDynamicsBody, collisionMask );
83
84   world->MapActor(mDynamicsBody, actor);
85 }
86
87 DynamicsBody::~DynamicsBody()
88 {
89   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - %s\n", __PRETTY_FUNCTION__, mName.c_str());
90
91   if( Stage::IsInstalled() )
92   {
93     DeleteBodyMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()) );
94
95     DynamicsWorldPtr world( Stage::GetCurrent()->GetDynamicsWorld() );
96
97     if( world )
98     {
99       world->UnmapActor(mDynamicsBody);
100     }
101   }
102
103   mShape.Reset();
104 }
105
106 const std::string& DynamicsBody::GetName() const
107 {
108   return mName;
109 }
110
111 float DynamicsBody::GetMass() const
112 {
113   if( IsKinematic() )
114   {
115     return 0.0f;
116   }
117
118   return mMass;
119 }
120
121 void DynamicsBody::SetMass(const float mass)
122 {
123   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - Mass:%f\n", __PRETTY_FUNCTION__, mass);
124
125   if( fabsf(mMass - mass) >= GetRangedEpsilon(mMass, mass) )
126   {
127     mMass = mass;
128     if( !IsKinematic() )
129     {
130       SetMassMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), mMass );
131     }
132   }
133 }
134
135 float DynamicsBody::GetElasticity() const
136 {
137   return mElasticity;
138 }
139
140 void DynamicsBody::SetElasticity(const float elasticity)
141 {
142   if( fabsf(mElasticity - elasticity) >= GetRangedEpsilon(mElasticity, elasticity) )
143   {
144     mElasticity = elasticity;
145     SetElasticityMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), mElasticity );
146   }
147 }
148
149 void DynamicsBody::SetLinearVelocity(const Vector3& velocity)
150 {
151   SetLinearVelocityMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), velocity );
152 }
153
154 Vector3 DynamicsBody::GetCurrentLinearVelocity() const
155 {
156   return GetSceneObject()->GetLinearVelocity( Stage::GetCurrent()->GetEventBufferIndex() );
157 }
158
159 void DynamicsBody::SetAngularVelocity(const Vector3& velocity)
160 {
161   SetAngularVelocityMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), velocity );
162 }
163
164 Vector3 DynamicsBody::GetCurrentAngularVelocity() const
165 {
166   return GetSceneObject()->GetAngularVelocity( Stage::GetCurrent()->GetEventBufferIndex() );
167 }
168
169 void DynamicsBody::SetKinematic( const bool flag )
170 {
171   if( mKinematic != flag )
172   {
173     // kinematic objects have zero mass
174     if( flag && ( ! EqualsZero( mMass ) ) )
175     {
176       SetMassMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), 0.0f );
177     }
178
179     mKinematic = flag;
180     SetKinematicMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), flag );
181
182     if( !flag && ( ! EqualsZero( mMass ) ) )
183     {
184       SetMassMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), mMass );
185     }
186
187     if( !flag )
188     {
189       SetSleepEnabledMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), mSleepEnabled );
190     }
191   }
192 }
193
194 bool DynamicsBody::IsKinematic() const
195 {
196   return mKinematic;
197 }
198
199 void DynamicsBody::SetSleepEnabled( const bool flag )
200 {
201   if( mSleepEnabled != flag )
202   {
203     mSleepEnabled = flag;
204
205     if( !IsKinematic() )
206     {
207       SetSleepEnabledMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), flag );
208     }
209   }
210 }
211
212 bool DynamicsBody::GetSleepEnabled() const
213 {
214   return mSleepEnabled;
215 }
216
217 void DynamicsBody::WakeUp()
218 {
219   WakeUpMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()) );
220 }
221
222 void DynamicsBody::AddAnchor(const unsigned int index, DynamicsBodyPtr body, const bool collisions)
223 {
224   AddAnchorMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), index, *(body->GetSceneObject()), collisions );
225 }
226
227 void DynamicsBody::ConserveVolume(const bool flag)
228 {
229   ConserveVolumeMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), flag );
230 }
231
232 void DynamicsBody::ConserveShape(const bool flag)
233 {
234   ConserveShapeMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), flag );
235 }
236
237 Actor& DynamicsBody::GetActor() const
238 {
239   return mActor;
240 }
241
242 void DynamicsBody::Connect(Stage& stage)
243 {
244   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - %s\n", __PRETTY_FUNCTION__, mName.c_str());
245
246   ConnectMessage( stage.GetUpdateInterface(), *(GetSceneObject()) );
247 }
248
249 void DynamicsBody::Disconnect(Stage& stage)
250 {
251   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - %s\n", __PRETTY_FUNCTION__, mName.c_str());
252
253   if( stage.IsInstalled() )
254   {
255     DisconnectMessage( stage.GetUpdateInterface(), *(GetSceneObject()) );
256   }
257 }
258
259
260 } // namespace Internal
261
262 } // namespace Dali