예제 #1
0
void BulletDynamicsBody::CreateRigidBody( const Integration::DynamicsBodySettings& bodySettings, Dali::Integration::DynamicsShape* shape,
                                          const Vector3& startPosition, const Quaternion& startRotation )
{
  DEBUG_PRINTF("%s\n", __func__ );

  Vector3 axis;
  float angle( 0.0f );
  startRotation.ToAxisAngle( axis, angle );

  btVector3 inertia( 0.0f ,0.0f ,0.0f );
  btCollisionShape* collisionShape( ((BulletDynamicsShape*)shape)->GetShape() );
  if( ! EqualsZero( bodySettings.mass ) )
  {
    collisionShape->calculateLocalInertia(bodySettings.mass, inertia);
  }

  btRigidBody::btRigidBodyConstructionInfo constructionInfo(bodySettings.mass, NULL, collisionShape, inertia);
  constructionInfo.m_restitution = bodySettings.elasticity;
  constructionInfo.m_linearDamping = bodySettings.linearDamping;
  constructionInfo.m_angularDamping = bodySettings.angularDamping;
  constructionInfo.m_friction = bodySettings.friction;
  constructionInfo.m_linearSleepingThreshold = bodySettings.linearSleepVelocity;
  constructionInfo.m_angularSleepingThreshold = bodySettings.angularSleepVelocity;
  constructionInfo.m_startWorldTransform.setOrigin(btVector3(startPosition.x, startPosition.y, startPosition.z));
  if( axis != Vector3::ZERO )
  {
    constructionInfo.m_startWorldTransform.setRotation( btQuaternion(btVector3(axis.x, axis.y, axis.z), btScalar(angle)) );
  }

  mBody = new btRigidBody( constructionInfo );
  mBody->setUserPointer(this);
}
void btFluidHfBuoyantConvexShape::generateShape(btScalar collisionRadius, btScalar volumeEstimationRadius)
{
	m_voxelPositions.resize(0);
	
	btVoronoiSimplexSolver simplexSolver;
	btTransform voxelTransform = btTransform::getIdentity();
	
	btVector3 aabbMin, aabbMax;
	getAabb( btTransform::getIdentity(), aabbMin, aabbMax );	//AABB of the convex shape
	
	//Generate voxels for collision
	{
		btSphereShape collisionShape(collisionRadius);
	
		const btScalar collisionDiameter = btScalar(2.0) * collisionRadius;
		btVector3 numVoxels = (aabbMax - aabbMin) / collisionDiameter;
		for(int i = 0; i < ceil( numVoxels.x() ); i++)
		{
			for(int j = 0; j < ceil( numVoxels.y() ); j++)
			{
				for(int k = 0; k < ceil( numVoxels.z() ); k++)
				{
					btVector3 voxelPosition = aabbMin + btVector3(i * collisionDiameter, j * collisionDiameter, k * collisionDiameter);
					voxelTransform.setOrigin(voxelPosition);

					if( intersect(&simplexSolver, btTransform::getIdentity(), voxelTransform, m_convexShape, &collisionShape) ) 
						m_voxelPositions.push_back(voxelPosition);
				}
			}
		}
		
		const bool CENTER_VOXELS_AABB_ON_ORIGIN = true;
		if(CENTER_VOXELS_AABB_ON_ORIGIN)
		{
			btVector3 diameter(collisionDiameter, collisionDiameter, collisionDiameter);
		
			btVector3 voxelAabbMin(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); 
			btVector3 voxelAabbMax(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT);
			for(int i = 0; i < m_voxelPositions.size(); ++i)
			{
				voxelAabbMin.setMin(m_voxelPositions[i] - diameter);
				voxelAabbMax.setMax(m_voxelPositions[i] + diameter);
			}
		
			btVector3 offset = (voxelAabbMax - voxelAabbMin)*btScalar(0.5) - voxelAabbMax;
		
			for(int i = 0; i < m_voxelPositions.size(); ++i) m_voxelPositions[i] += offset;
		}
	}
	
	//Estimate volume with smaller spheres
	btScalar estimatedVolume;
	{
		btSphereShape volumeEstimationShape(volumeEstimationRadius);	
		
		int numCollidingVoxels = 0;
		const btScalar estimationDiameter = btScalar(2.0) * volumeEstimationRadius;
		btVector3 numEstimationVoxels = (aabbMax - aabbMin) / estimationDiameter;
		
		for(int i = 0; i < ceil( numEstimationVoxels.x() ); i++)
		{
			for(int j = 0; j < ceil( numEstimationVoxels.y() ); j++)
			{
				for(int k = 0; k < ceil( numEstimationVoxels.z() ); k++)
				{
					btVector3 voxelPosition = aabbMin + btVector3(i * estimationDiameter, j * estimationDiameter, k * estimationDiameter);
					voxelTransform.setOrigin(voxelPosition);

					if( intersect(&simplexSolver, btTransform::getIdentity(), voxelTransform, m_convexShape, &volumeEstimationShape) ) 
						++numCollidingVoxels;
				}
			}
		}
		

		
		//Although the voxels are spherical, it is better to use the volume of a cube
		//for volume estimation. Since convex shapes are completely solid and the voxels
		//are generated by moving along a cubic lattice, using the volume of a sphere
		//would result in gaps. Comparing the volume of a cube with edge length 2(8 m^3) 
		//and the volume of a sphere with diameter 2(~4 m^3), the estimated volume would
		//be off by about 1/2.
		btScalar volumePerEstimationVoxel = btPow( estimationDiameter, btScalar(3.0) );
		//btScalar volumePerEstimationVoxel =  btScalar(4.0/3.0) * SIMD_PI * btPow( volumeEstimationRadius, btScalar(3.0) );
		
		estimatedVolume = static_cast<btScalar>(numCollidingVoxels) * volumePerEstimationVoxel;
	}
	
	m_volumePerVoxel = estimatedVolume / static_cast<btScalar>( getNumVoxels() );
	m_totalVolume = estimatedVolume;
	
	m_collisionRadius = collisionRadius;
}