Ejemplo n.º 1
0
		internal override double calculateTimeOfImpact( btCollisionObject col0, btCollisionObject col1, btDispatcherInfo dispatchInfo, btManifoldResult resultOut )
		{
			//(void)resultOut;
			//(void)dispatchInfo;
			///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold

			///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
			///col0.m_worldTransform,
			double resultFraction = btScalar.BT_ONE;

			btVector3 tmp;
			col0.m_interpolationWorldTransform.m_origin.Sub( ref col0.m_worldTransform.m_origin, out tmp );
			double squareMot0 = ( tmp ).length2();
			col1.m_interpolationWorldTransform.m_origin.Sub( ref col1.m_worldTransform.m_origin, out tmp );
			double squareMot1 = ( tmp ).length2();

			if( squareMot0 < col0.getCcdSquareMotionThreshold() &&
				squareMot1 < col1.getCcdSquareMotionThreshold() )
				return resultFraction;

			if( disableCcd )
				return btScalar.BT_ONE;


			//An adhoc way of testing the Continuous Collision Detection algorithms
			//One object is approximated as a sphere, to simplify things
			//Starting in penetration should report no time of impact
			//For proper CCD, better accuracy and handling of 'allowed' penetration should be added
			//also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)


			/// Convex0 against sphere for Convex1
			{
				btConvexShape convex0 = (btConvexShape)col0.getCollisionShape();

				using( btSphereShape sphere1 = BulletGlobals.SphereShapePool.Get() )
				{
					sphere1.Initialize( col1.getCcdSweptSphereRadius() ); //todo: allow non-zero sphere sizes, for better approximation
					btConvexCast.CastResult result = BulletGlobals.CastResultPool.Get();
					btVoronoiSimplexSolver voronoiSimplex = BulletGlobals.VoronoiSimplexSolverPool.Get();
					//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
					///Simplification, one object is simplified as a sphere
					btGjkConvexCast ccd1 = BulletGlobals.GjkConvexCastPool.Get();
					ccd1.Initialize( convex0, sphere1, voronoiSimplex );
					//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
					if( ccd1.calcTimeOfImpact( ref col0.m_worldTransform, ref col0.m_interpolationWorldTransform,
							ref col1.m_worldTransform, ref col1.m_interpolationWorldTransform, result ) )
					{

						//store result.m_fraction in both bodies

						if( col0.getHitFraction() > result.m_fraction )
							col0.setHitFraction( result.m_fraction );

						if( col1.getHitFraction() > result.m_fraction )
							col1.setHitFraction( result.m_fraction );

						if( resultFraction > result.m_fraction )
							resultFraction = result.m_fraction;

					}
					BulletGlobals.GjkConvexCastPool.Free( ccd1 );
				}
			}

			/// Sphere (for convex0) against Convex1
			{
				btConvexShape convex1 = (btConvexShape)( col1.getCollisionShape() );

				using( btSphereShape sphere0 = BulletGlobals.SphereShapePool.Get() )
				{
					sphere0.Initialize( col0.getCcdSweptSphereRadius() ); //todo: allow non-zero sphere sizes, for better approximation
					btConvexCast.CastResult result = BulletGlobals.CastResultPool.Get();
					btVoronoiSimplexSolver voronoiSimplex = BulletGlobals.VoronoiSimplexSolverPool.Get();
					//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
					///Simplification, one object is simplified as a sphere
					btGjkConvexCast ccd1 = BulletGlobals.GjkConvexCastPool.Get();
					ccd1.Initialize( sphere0, convex1, voronoiSimplex );
					//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
					if( ccd1.calcTimeOfImpact( ref col0.m_worldTransform, ref col0.m_interpolationWorldTransform,
								ref col1.m_worldTransform, ref col1.m_interpolationWorldTransform, result ) )
					{
						//store result.m_fraction in both bodies

						if( col0.getHitFraction() > result.m_fraction )
							col0.setHitFraction( result.m_fraction );

						if( col1.getHitFraction() > result.m_fraction )
							col1.setHitFraction( result.m_fraction );

						if( resultFraction > result.m_fraction )
							resultFraction = result.m_fraction;
					}
					BulletGlobals.GjkConvexCastPool.Free( ccd1 );
				}
			}
			return resultFraction;

		}