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/update/dynamics/scene-graph-dynamics-body.h>
22 #include <dali/integration-api/dynamics/dynamics-body-intf.h>
23 #include <dali/integration-api/dynamics/dynamics-body-settings.h>
24 #include <dali/integration-api/dynamics/dynamics-factory-intf.h>
25 #include <dali/integration-api/dynamics/dynamics-shape-intf.h>
26 #include <dali/internal/update/dynamics/scene-graph-dynamics-shape.h>
27 #include <dali/internal/update/dynamics/scene-graph-dynamics-mesh-shape.h>
28 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
29 #include <dali/internal/update/modeling/scene-graph-mesh.h>
30 #include <dali/internal/update/modeling/internal-mesh-data.h>
31 #include <dali/internal/update/nodes/node.h>
42 DynamicsBody::DynamicsBody(DynamicsWorld& world, Node& node )
49 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
52 DynamicsBody::~DynamicsBody()
54 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__ );
60 void DynamicsBody::Initialize( Integration::DynamicsBodySettings* settings, DynamicsShape* shape )
62 DALI_ASSERT_DEBUG( shape && "NULL shape passed into DynamicsBody" );
64 mBody = mWorld.GetDynamicsFactory().CreateDynamicsBody();
66 if( Dali::DynamicsBodyConfig::SOFT == settings->type )
68 Mesh* mesh( static_cast<DynamicsMeshShape&>(*shape).GetMesh() );
69 DALI_ASSERT_DEBUG( mesh );
75 GetNodePositionAndRotation( position, rotation );
76 mBody->Initialize( *settings, shape->GetShape(), mWorld.GetDynamicsWorld(), position, rotation );
80 void DynamicsBody::SetMass(const float mass)
82 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - mass:%.2f\n", __PRETTY_FUNCTION__, mass);
84 mBody->SetMass( mass );
87 void DynamicsBody::SetElasticity(const float elasticity)
89 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - elasticity:%.1f\n", __PRETTY_FUNCTION__, elasticity);
91 mBody->SetElasticity( elasticity );
94 void DynamicsBody::SetLinearVelocity(const Vector3& velocity)
96 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (velocity:%f %f %f)\n", __PRETTY_FUNCTION__, velocity.x, velocity.y, velocity.z);
98 mBody->SetLinearVelocity( velocity / mWorld.GetWorldScale() );
99 mLinearVelocity[ mWorld.GetBufferIndex() ] = velocity;
102 Vector3 DynamicsBody::GetLinearVelocity( BufferIndex bufferIndex ) const
104 const Vector3& velocity( mLinearVelocity[ bufferIndex ] );
106 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (velocity:%f %f %f)\n", __PRETTY_FUNCTION__,
107 velocity.x, velocity.y, velocity.z);
112 void DynamicsBody::SetAngularVelocity(const Vector3& velocity)
114 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (velocity:%f %f %f)\n", __PRETTY_FUNCTION__, velocity.x, velocity.y, velocity.z);
116 mBody->SetAngularVelocity( velocity );
118 mAngularVelocity[ mWorld.GetBufferIndex() ] = velocity;
121 Vector3 DynamicsBody::GetAngularVelocity( BufferIndex bufferIndex ) const
123 const Vector3& velocity( mAngularVelocity[ bufferIndex ] );
125 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (velocity:%f %f %f)\n", __PRETTY_FUNCTION__,
126 velocity.x, velocity.y, velocity.z);
131 void DynamicsBody::SetKinematic(const bool flag)
133 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - %s\n", __PRETTY_FUNCTION__, flag ? "true" : "false" );
135 mBody->SetKinematic( flag );
138 bool DynamicsBody::IsKinematic() const
140 return mBody->IsKinematic();
143 void DynamicsBody::SetSleepEnabled( const bool flag)
145 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - %s\n", __PRETTY_FUNCTION__, flag ? "true" : "false" );
147 mBody->SetSleepEnabled( flag );
150 void DynamicsBody::WakeUp()
152 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
157 void DynamicsBody::AddAnchor( const unsigned int index, const DynamicsBody* anchorBody, const bool collisions )
159 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (index: %d)\n", __PRETTY_FUNCTION__, index);
160 DALI_ASSERT_DEBUG( NULL != mBody );
161 DALI_ASSERT_DEBUG( Dali::DynamicsBodyConfig::SOFT == mBody->GetType() );
162 DALI_ASSERT_DEBUG( NULL != anchorBody && NULL != anchorBody->mBody );
163 DALI_ASSERT_DEBUG( Dali::DynamicsBodyConfig::RIGID == anchorBody->GetType() );
165 mBody->AddAnchor( index, anchorBody->GetBody(), collisions );
168 void DynamicsBody::ConserveVolume( const bool flag )
170 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (%s)\n", __PRETTY_FUNCTION__, flag ? "yes" : "no" );
172 mBody->ConserveVolume( flag );
175 void DynamicsBody::ConserveShape( const bool flag )
177 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (%s)\n", __PRETTY_FUNCTION__, flag ? "yes" : "no" );
179 mBody->ConserveShape( flag );
182 short int DynamicsBody::GetCollisionGroup() const
184 return mBody->GetCollisionGroup();
187 void DynamicsBody::SetCollisionGroup( const short int collisionGroup )
189 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (0x%04X)\n", __PRETTY_FUNCTION__, collisionGroup );
190 mBody->SetCollisionGroup( collisionGroup );
193 short int DynamicsBody::GetCollisionMask() const
195 return mBody->GetCollisionMask();
198 void DynamicsBody::SetCollisionMask( const short int collisionMask )
200 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s - (0x%04X)\n", __PRETTY_FUNCTION__, collisionMask );
201 mBody->SetCollisionMask( collisionMask );
204 int DynamicsBody::GetType() const
206 return mBody->GetType();
209 Integration::DynamicsBody* DynamicsBody::GetBody() const
214 void DynamicsBody::Connect()
216 int bodyType( mBody->GetType() );
217 if( Dali::DynamicsBodyConfig::RIGID == bodyType )
221 else if( Dali::DynamicsBodyConfig::SOFT == bodyType )
224 * Soft body vertices get local transformation applied twice due to
225 * physics engine directly transforming all the points in a soft body's mesh
226 * then the vertices getting the transformation applied again in the shader
228 mNode.SetInhibitLocalTransform(true);
233 mWorld.AddBody(*this);
236 void DynamicsBody::Disconnect()
238 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::General, "%s (body: %p)\n", __PRETTY_FUNCTION__, mBody);
240 if( Dali::DynamicsBodyConfig::SOFT == GetType() )
243 * Soft body vertices get local transformation applied twice due to
244 * physics engine directly transforming all the points in a soft body's mesh
245 * then the vertices getting the transformation applied again in the shader
247 mNode.SetInhibitLocalTransform(false);
250 mWorld.RemoveBody(*this);
253 void DynamicsBody::Delete()
255 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::General, "%s (body: %p)\n", __PRETTY_FUNCTION__, mBody);
257 mWorld.DeleteBody(*this);
260 void DynamicsBody::SetMotionState()
262 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
265 void DynamicsBody::GetNodePositionAndRotation(Vector3& position, Quaternion& rotation)
267 const BufferIndex bufferIndex = mWorld.GetBufferIndex();
268 position = mNode.GetPosition(bufferIndex) / mWorld.GetWorldScale();
269 rotation = mNode.GetRotation(bufferIndex);
272 void DynamicsBody::SetNodePositionAndRotation(const Vector3& position, const Quaternion& rotation)
274 const Vector3 scaledPosition(position * mWorld.GetWorldScale());
276 const BufferIndex bufferIndex( mWorld.GetBufferIndex() );
277 mNode.BakePosition(bufferIndex, scaledPosition);
278 mNode.BakeOrientation(bufferIndex, rotation);
280 if( Dali::DynamicsBodyConfig::RIGID == mBody->GetType() )
282 mLinearVelocity[bufferIndex] = mBody->GetLinearVelocity();
283 mAngularVelocity[bufferIndex] = mBody->GetAngularVelocity();
287 void DynamicsBody::RefreshDynamics()
289 // get node's world position and rotation
292 GetNodePositionAndRotation(position, rotation);
294 mBody->SetTransform( position, rotation );
297 bool DynamicsBody::RefreshNode(BufferIndex updateBufferIndex)
299 // get updated parameters
300 if( Dali::DynamicsBodyConfig::SOFT == mBody->GetType() )
302 RefreshMesh(updateBufferIndex);
306 if( !mBody->IsKinematic() )
308 // get updated parameters
311 mBody->GetTransform( position, rotation );
312 SetNodePositionAndRotation( position, rotation );
316 // TODO: Add activation state change notification
317 // interrogate dynamics body for it's activation state
318 bool activationState( mBody->IsActive() );
320 return activationState;
323 void DynamicsBody::RefreshMesh(BufferIndex updateBufferIndex)
325 Internal::MeshData& meshData( mMesh->GetMeshData( Mesh::UPDATE_THREAD ) );
327 mBody->GetSoftVertices( meshData.GetVertices() );
329 mMesh->MeshDataUpdated( updateBufferIndex, Mesh::UPDATE_THREAD, NULL );
332 } // namespace SceneGraph
334 } // namespace Internal