void BulletDynamicsBody::SetMass( float mass ) { DEBUG_PRINTF("%s(%.2f)\n", __func__, mass); if( Dali::DynamicsBodyConfig::RIGID == mSettings->type ) { btRigidBody* rigidBody( btRigidBody::upcast(mBody) ); DALI_ASSERT_DEBUG( rigidBody ); btVector3 inertia(0,0,0); if( ! EqualsZero( mass ) ) { btCollisionShape* shape = mBody->getCollisionShape(); shape->calculateLocalInertia(mass, inertia); } rigidBody->setMassProps(btScalar(mass), inertia); } else if( Dali::DynamicsBodyConfig::SOFT == mSettings->type ) { btSoftBody* softBody( btSoftBody::upcast(mBody) ); DALI_ASSERT_DEBUG( softBody ); softBody->setTotalMass(mass); } }
void BulletDynamicsBody::SetTransform( const Vector3& position, const Quaternion& rotation ) { Vector3 axis; float angle( 0.0f ); rotation.ToAxisAngle( axis, angle ); if( Dali::DynamicsBodyConfig::RIGID == mSettings->type ) { btTransform& transform( mBody->getWorldTransform() ); // modify parameters transform.setIdentity(); transform.setOrigin( btVector3(position.x, position.y, position.z) ); if( axis != Vector3::ZERO ) { transform.setRotation( btQuaternion(btVector3(axis.x, axis.y, axis.z), btScalar(angle)) ); } } else if( Dali::DynamicsBodyConfig::SOFT == mSettings->type ) { btSoftBody* softBody( static_cast< btSoftBody* >( mBody ) ); btTransform transform; transform.setIdentity(); transform.setOrigin( btVector3(position.x, position.y, position.z) ); if( axis != Vector3::ZERO ) { transform.setRotation( btQuaternion(btVector3(axis.x, axis.y, axis.z), btScalar(angle)) ); } softBody->transform( transform ); } }
void BulletDynamicsBody::AddAnchor( unsigned int index, const Integration::DynamicsBody* anchorBody, bool collisions ) { DEBUG_PRINTF("%s\n", __func__); const BulletDynamicsBody* anchorDynamicsBody( static_cast< const BulletDynamicsBody* >( anchorBody ) ); btSoftBody* softBody( static_cast< btSoftBody* >( mBody ) ); btRigidBody* rigidBody( static_cast< btRigidBody* >( anchorDynamicsBody->GetBody() ) ); softBody->appendAnchor( index, rigidBody, !collisions ); }
void BulletDynamicsBody::ConserveShape( bool flag ) { if( mConserveShape != flag ) { mConserveShape = flag; btSoftBody* softBody( static_cast<btSoftBody*>(mBody) ); softBody->setPose( mConserveVolume, mConserveShape ); } }
void BulletDynamicsBody::GetSoftVertices( MeshData::VertexContainer& vertices ) const { const float worldScale( 1.0f / mWorld->GetWorldScale() ); // copy positions and normals const size_t vertexCount = vertices.size(); MeshData::Vertex* vertex( &vertices[0] ); btSoftBody* softBody( static_cast<btSoftBody*>( mBody ) ); btSoftBody::Node* node( &softBody->m_nodes[0] ); for( size_t i = 0; i < vertexCount; ++i ) { vertex->x = node->m_x.x() * worldScale; vertex->y = node->m_x.y() * worldScale; vertex->z = node->m_x.z() * worldScale; vertex->nX = node->m_n.x(); vertex->nY = node->m_n.y(); vertex->nZ = node->m_n.z(); ++vertex; ++node; } }
void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) { //just for debugging purposes //printf("triangle %d",m_triangleCount++); btCollisionAlgorithmConstructionInfo ci; ci.m_dispatcher1 = m_dispatcher; ///debug drawing of the overlapping triangles if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe)) { btVector3 color(1,1,0); const btTransform& tr = m_triBody->getWorldTransform(); m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color); m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color); m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); } btTriIndex triIndex(partId,triangleIndex,0); btHashKey<btTriIndex> triKey(triIndex.getUid()); btTriIndex* shapeIndex = m_shapeCache[triKey]; if (shapeIndex) { btCollisionShape* tm = shapeIndex->m_childShape; btAssert(tm); //copy over user pointers to temporary shape tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer()); btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform()); //btCollisionObjectWrapper triBody(0,tm, ob, btTransform::getIdentity());//ob->getWorldTransform());//?? btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform()); btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0);//m_manifoldPtr); colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut); colAlgo->~btCollisionAlgorithm(); ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); return; } //aabb filter is already applied! //btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject); // if (m_softBody->getCollisionShape()->getShapeType()== { // btVector3 other; btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); normal.normalize(); normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION; // other=(triangle[0]+triangle[1]+triangle[2])*0.333333f; // other+=normal*22.f; btVector3 pts[6] = {triangle[0]+normal, triangle[1]+normal, triangle[2]+normal, triangle[0]-normal, triangle[1]-normal, triangle[2]-normal}; btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6); // btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other); //btTriangleShape tm(triangle[0],triangle[1],triangle[2]); // tm.setMargin(m_collisionMarginTriangle); //copy over user pointers to temporary shape tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer()); btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform()); btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform());//btTransform::getIdentity());//?? btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0);//m_manifoldPtr); colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut); colAlgo->~btCollisionAlgorithm(); ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); triIndex.m_childShape = tm; m_shapeCache.insert(triKey,triIndex); } }
void BulletDynamicsBody::CreateSoftBody( const Integration::DynamicsBodySettings& bodySettings, Dali::Integration::DynamicsShape* shape, const Vector3& startPosition, const Quaternion& startRotation ) { DEBUG_PRINTF("BulletDynamicsBody::CreateSoftBody()\n" ); BulletDynamicsShape* dynamicsShape( static_cast< BulletDynamicsShape* >( shape ) ); // copy positions MeshData::VertexContainer* vertices( dynamicsShape->mVertices ); const size_t vertexCount = vertices->size(); MeshData::Vertex* vertex( &(*vertices)[0] ); MeshData::FaceIndices* faces( dynamicsShape->mFaces ); const size_t faceCount = faces->size() / 3; unsigned short* faceIndex = ( &(*faces)[0] ); const float worldScale( mWorld->GetWorldScale() ); DEBUG_PRINTF("%s verts:%d faces:%d worldScale:%.2f\n", __func__, (int)vertexCount, (int)faceCount, worldScale ); // copy vertex positions std::vector<btVector3> positions( vertexCount ); btVector3* position = &positions[0]; for( size_t i = 0; i < vertexCount; ++i ) { *position++ = btVector3( vertex->x, vertex->y, vertex->z ) * worldScale; vertex++; } btSoftBody* softBody( new btSoftBody(mWorld->GetSoftBodyWorldInfo(), vertexCount, positions.data(), NULL) ); // Add faces for( size_t i = 0; i < faceCount; ++i) { softBody->appendFace(faceIndex[0], faceIndex[1], faceIndex[2]); softBody->appendLink(faceIndex[0], faceIndex[1], NULL, true); softBody->appendLink(faceIndex[0], faceIndex[2], NULL, true); softBody->appendLink(faceIndex[1], faceIndex[2], NULL, true); faceIndex += 3; } softBody->m_cfg.kAHR = std::max(0.0f, std::min(1.0f, bodySettings.anchorHardness)); softBody->m_cfg.kVC = std::max(0.0f, bodySettings.volumeConservation); softBody->m_cfg.kMT = std::max(0.0f, std::min(1.0f, bodySettings.shapeConservation)); softBody->m_cfg.kDP = Clamp( bodySettings.linearDamping, 0.0f, 1.0f ); btSoftBody::Material* material( softBody->m_materials[0] ); material->m_kLST = bodySettings.linearStiffness; // material->m_flags &= ~btSoftBody::fMaterial::DebugDraw; // By default, inhibit debug draw for softbodies softBody->m_cfg.collisions = btSoftBody::fCollision::SDF_RS | btSoftBody::fCollision::CL_SS | 0; softBody->getCollisionShape()->setMargin(0.5f); mBody = softBody; mBody->setUserPointer(this); SetTransform( startPosition, startRotation ); }