License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / dynamics / dynamics-joint-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-joint-impl.h>
20
21 // EXTERNAL HEADERS
22
23 // INTERNAL HEADERS
24 #include <dali/integration-api/debug.h>
25 #include <dali/internal/event/common/stage-impl.h>
26 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
27 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
28 #include <dali/internal/update/dynamics/scene-graph-dynamics-body.h>
29 #include <dali/internal/update/dynamics/scene-graph-dynamics-joint.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 DynamicsJoint::DynamicsJoint(DynamicsWorldPtr world, DynamicsBodyPtr bodyA, DynamicsBodyPtr bodyB, const Vector3& offsetA, const Vector3& offsetB )
38 : mDynamicsJoint(NULL),
39   mInitialized(false),
40   mBodyA(bodyA),
41   mBodyB(bodyB),
42   mOffsetA(offsetA),
43   mOffsetB(offsetB),
44   mSpringEnabled(0),
45   mMotorEnabled(0)
46 {
47   for( unsigned int i = 0; i < RotationAxis; ++i )
48   {
49     mTranslationLowerLimit[i] = 0.0f;
50     mTranslationUpperLimit[i] = 0.0f;
51     mRotationLowerLimit[i] = 0.0f;
52     mRotationUpperLimit[i] = 0.0f;
53   }
54
55   for( unsigned int i = 0; i < MaxAxis; ++i )
56   {
57     mSpringStiffness[i] = 0.0f;
58     mSpringDamping[i] = 0.5f;
59     mSpringCenterPoint[i] = 0.0f;
60     mMotorVelocity[i] = 0.0f;
61     mMotorForce[i] = 0.0f;
62   }
63
64   mDynamicsJoint = new SceneGraph::DynamicsJoint( *(world->GetSceneObject()) );
65 }
66
67 DynamicsJoint::~DynamicsJoint()
68 {
69   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
70
71   if( Stage::IsInstalled() )
72   {
73     DeleteJointMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()) );
74   }
75 }
76
77 void DynamicsJoint::SetLinearLimit(const int axisIndex, const float lowerLimit, const float upperLimit)
78 {
79   bool valueChanged(false);
80
81   int bit(1 << 0);
82   for( unsigned int i = 0; i < RotationAxis; ++i)
83   {
84     if( (bit & axisIndex) )
85     {
86       if( fabsf(lowerLimit - mTranslationLowerLimit[i]) >= GetRangedEpsilon(lowerLimit, mTranslationLowerLimit[i]) ||
87           fabsf(upperLimit - mTranslationUpperLimit[i]) >= GetRangedEpsilon(upperLimit, mTranslationUpperLimit[i]) )
88       {
89         mTranslationLowerLimit[i] = lowerLimit;
90         mTranslationUpperLimit[i] = upperLimit;
91
92         valueChanged = true;
93       }
94     }
95     bit <<= 1;
96   }
97
98   if( valueChanged )
99   {
100     SetLimitMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), axisIndex, lowerLimit, upperLimit );
101   }
102 }
103
104 void DynamicsJoint::SetAngularLimit(const int  axisIndex, const Radian& lowerLimit, const Radian& upperLimit)
105 {
106   bool valueChanged(false);
107
108   int bit(1 << RotationAxis);
109   for( unsigned int i = 0; i < RotationAxis; ++i)
110   {
111     if( (bit & axisIndex) )
112     {
113       if( ( ! Equals( lowerLimit, mRotationLowerLimit[i] ) ) || ( ! Equals( upperLimit, mRotationUpperLimit[i] ) ) )
114       {
115         mRotationLowerLimit[i] = lowerLimit;
116         mRotationUpperLimit[i] = upperLimit;
117
118         valueChanged = true;
119       }
120     }
121     bit <<= 1;
122   }
123
124   if( valueChanged )
125   {
126     SetLimitMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), axisIndex, lowerLimit, upperLimit );
127   }
128 }
129
130 void DynamicsJoint::EnableSpring(const int axisIndex, const bool flag)
131 {
132   int valueChanged(0);
133
134   int bit(1 << 0);
135   for( unsigned int i = 0; i < MaxAxis; ++i)
136   {
137     if( (bit & axisIndex) && (flag != (mSpringEnabled & bit)) )
138     {
139       if( flag )
140       {
141         mSpringEnabled |= bit;
142       }
143       else
144       {
145         mSpringEnabled &= ~bit;
146       }
147
148       valueChanged |= bit;
149     }
150     bit <<= 1;
151   }
152
153   if( 0 != valueChanged )
154   {
155     SetEnableSpringMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), valueChanged, flag );
156   }
157 }
158
159 void DynamicsJoint::DynamicsJoint::SetSpringStiffness(const int  axisIndex, const float stiffness)
160 {
161   int valueChanged(0);
162
163   int bit(1 << 0);
164   for( unsigned int i = 0; i < MaxAxis; ++i)
165   {
166     if( (bit & axisIndex) && fabsf(stiffness - mSpringStiffness[i]) >= GetRangedEpsilon(stiffness, mSpringStiffness[i]) )
167     {
168       mSpringStiffness[i] = stiffness;
169
170       valueChanged |= bit;
171     }
172     bit <<= 1;
173   }
174
175   if( 0 != valueChanged )
176   {
177     SetSpringStiffnessMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), valueChanged, stiffness );
178   }
179 }
180
181 void DynamicsJoint::SetSpringDamping(const int axisIndex, const float damping)
182 {
183   const float clampedDamping( Clamp(damping, 0.0f, 1.0f) );
184
185   int valueChanged(0);
186
187   int bit(1 << 0);
188   for( unsigned int i = 0; i < MaxAxis; ++i)
189   {
190     if( (bit & axisIndex) && fabsf(clampedDamping - mSpringDamping[i]) >= GetRangedEpsilon(clampedDamping, mSpringDamping[i]) )
191     {
192       mSpringDamping[i] = clampedDamping;
193
194       valueChanged |= bit;
195     }
196     bit <<= 1;
197   }
198
199   if( 0 != valueChanged )
200   {
201     SetSpringDampingMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), valueChanged, clampedDamping );
202   }
203 }
204
205 void DynamicsJoint::DynamicsJoint::SetSpringCenterPoint(const int  axisIndex, const float ratio)
206 {
207   int valueChanged(0);
208
209   int bit(1 << 0);
210   for( unsigned int i = 0; i < MaxAxis; ++i)
211   {
212     if( (bit & axisIndex) && fabsf(ratio - mSpringCenterPoint[i]) >= GetRangedEpsilon(ratio, mSpringCenterPoint[i]) )
213     {
214       mSpringCenterPoint[i] = ratio;
215
216       valueChanged |= bit;
217     }
218     bit <<= 1;
219   }
220
221   if( 0 != valueChanged )
222   {
223     SetSpringCenterPointMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), valueChanged, ratio );
224   }
225 }
226
227 void DynamicsJoint::EnableMotor(const int  axisIndex, const bool flag)
228 {
229   bool valueChanged(false);
230
231   int bit(1 << 0);
232   for( unsigned int i = 0; i < MaxAxis; ++i)
233   {
234     if( (bit & axisIndex) && (flag != (mMotorEnabled & bit)) )
235     {
236       if( flag )
237       {
238         mMotorEnabled |= bit;
239       }
240       else
241       {
242         mMotorEnabled &= ~bit;
243       }
244       valueChanged = true;
245     }
246     bit <<= 1;
247   }
248
249   if( valueChanged )
250   {
251     SetEnableMotorMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), axisIndex, flag );
252   }
253 }
254
255 void DynamicsJoint::SetMotorVelocity(const int  axisIndex, const float velocity)
256 {
257   bool valueChanged(false);
258
259   int bit(1 << 0);
260   for( unsigned int i = 0; i < MaxAxis; ++i)
261   {
262     if( (bit & axisIndex) && fabsf(velocity - mMotorVelocity[i]) >= GetRangedEpsilon(velocity, mMotorVelocity[i]) )
263     {
264       mMotorVelocity[i] = velocity;
265
266       valueChanged = true;
267     }
268     bit <<= 1;
269   }
270
271   if( valueChanged )
272   {
273     SetMotorVelocityMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), axisIndex, velocity );
274   }
275 }
276
277 void DynamicsJoint::SetMotorForce(const int  axisIndex, const float force)
278 {
279   bool valueChanged(false);
280
281   int bit(1 << 0);
282   for( unsigned int i = 0; i < MaxAxis; ++i)
283   {
284     if( (bit & axisIndex) && fabsf(force - mMotorForce[i]) >= GetRangedEpsilon(force, mMotorForce[i]) )
285     {
286       mMotorForce[i] = force;
287
288       valueChanged = true;
289     }
290     bit <<= 1;
291   }
292
293   if( valueChanged )
294   {
295     SetMotorForceMessage( Stage::GetCurrent()->GetUpdateInterface(), *(GetSceneObject()), axisIndex, force );
296   }
297 }
298
299 ActorPtr DynamicsJoint::GetActor( const bool first ) const
300 {
301   DynamicsBodyPtr body( first ? mBodyA : mBodyB );
302
303   return Stage::GetCurrent()->GetDynamicsWorld()->GetMappedActor( body->GetSceneObject() );
304 }
305
306 void DynamicsJoint::Connect(Stage& stage)
307 {
308   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
309
310   if( !mInitialized )
311   {
312     InitializeDynamicsJointMessage( stage.GetUpdateInterface(), *mDynamicsJoint, *(mBodyA->GetSceneObject()), *(mBodyB->GetSceneObject()), mOffsetA, mOffsetB );
313     mInitialized = true;
314   }
315
316   ConnectJointMessage( stage.GetUpdateInterface(), *(GetSceneObject()) );
317 }
318
319 void DynamicsJoint::Disconnect(Stage& stage)
320 {
321   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
322
323   if( stage.IsInstalled() )
324   {
325     DisconnectJointMessage( stage.GetUpdateInterface(), *(GetSceneObject()) );
326   }
327 }
328
329 SceneGraph::DynamicsJoint* DynamicsJoint::GetSceneObject() const
330 {
331   return mDynamicsJoint;
332 }
333
334 } // namespace Internal
335
336 } // namespace Dali