public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			if (_manifold == null)
				return;

			SphereShape sphereA = bodyA.CollisionShape as SphereShape;
			SphereShape sphereB = bodyB.CollisionShape as SphereShape;

			Vector3 diff = bodyA.WorldTransform.Translation - bodyB.WorldTransform.Translation;
			float len = diff.Length();
			float radiusA = sphereA.Radius;
			float radiusB = sphereB.Radius;

			//if distance positive, don't generate a new contact
			if (len > (radiusA + radiusB))
				return;

			//distance (negative means penetration)
			float dist = len - (radiusA + radiusB);

			Vector3 normalOnSurfaceB = diff / len;
			//point on A (worldspace)
			Vector3 posA = bodyA.WorldTransform.Translation - radiusA * normalOnSurfaceB;
			//point on B (worldspace)
			Vector3 posB = bodyB.WorldTransform.Translation + radiusB * normalOnSurfaceB;

			// report a contact. internally this will be kept persistent, and contact reduction is done
			resultOut.SetPersistentManifold(_manifold);
			resultOut.AddContactPoint(normalOnSurfaceB, posB, dist);
		}
예제 #2
0
 public ManifoldResult(CollisionObject bodyA, CollisionObject bodyB)
 {
     _bodyA = bodyA;
     _bodyB = bodyB;
     _rootTransA = bodyA.WorldTransform;
     _rootTransB = bodyB.WorldTransform;
 }
		public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			CollisionObject convexBody = _isSwapped ? bodyB : bodyA;
			CollisionObject triBody = _isSwapped ? bodyA : bodyB;

			if (triBody.CollisionShape.IsConcave)
			{
				CollisionObject triOb = triBody;
				ConcaveShape concaveShape = triOb.CollisionShape as ConcaveShape;

				if (convexBody.CollisionShape.IsConvex)
				{
					float collisionMarginTriangle = concaveShape.Margin;

					resultOut.SetPersistentManifold(_convexTriangleCallback.Manifold);
					_convexTriangleCallback.SetTimeStepAndCounters(collisionMarginTriangle, dispatchInfo, resultOut);

					//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
					//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);

					_convexTriangleCallback.Manifold.SetBodies(convexBody, triBody);
					concaveShape.ProcessAllTriangles(_convexTriangleCallback, _convexTriangleCallback.AabbMin, _convexTriangleCallback.AabbMax);
				}
			}
		}
		public override void ProcessCollision(
			CollisionObject bodyA,
			CollisionObject bodyB,
			DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			//Begin

			CollisionObject collisionObject = _isSwapped ? bodyB : bodyB;
			CollisionObject otherObject = _isSwapped ? bodyA : bodyB;

			//Debug.Assert(collisionObject.getCollisionShape().isCompound());
			BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

			CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;

			int childrenNumber = _childCollisionAlgorithms.Count;

			for (int i = 0; i < childrenNumber; i++)
			{
				CompoundShape childShape = compoundShape.GetChildShape(i) as CompoundShape;

				Matrix orgTransform = collisionObject.WorldTransform;
				CollisionShape orgShape = collisionObject.CollisionShape;

				Matrix childTransform = compoundShape.GetChildTransform(i);
				Matrix newChildWorld = orgTransform * childTransform;

				collisionObject.WorldTransform = newChildWorld;
				collisionObject.CollisionShape = childShape;
				_childCollisionAlgorithms[i].ProcessCollision(collisionObject, otherObject, dispatchInfo, resultOut);

				collisionObject.CollisionShape = orgShape;
				collisionObject.WorldTransform = orgTransform;
			}
		}
		public CompoundCollisionAlgorithm(
			CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo,
			CollisionObject bodyA,
			CollisionObject bodyB, bool isSwapped)
			: base(collisionAlgorithmConstructionInfo)
		{
			//Begin
			_isSwapped = isSwapped;

			CollisionObject collisionObject = isSwapped ? bodyB : bodyA;
			CollisionObject otherObject = isSwapped ? bodyA : bodyB;

			BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

			CompoundShape compoundShape = collisionObject.CollisionShape as CompoundShape;
			int childrenNumber = compoundShape.ChildShapeCount;
			int index = 0;

			_childCollisionAlgorithms = new List<CollisionAlgorithm>(childrenNumber);

			for (index = 0; index < childrenNumber; index++)
			{
				CollisionShape childShape = compoundShape.GetChildShape(index);
				CollisionShape orgShape = collisionObject.CollisionShape;

				collisionObject.CollisionShape = childShape;
				_childCollisionAlgorithms[index] = collisionAlgorithmConstructionInfo.Dispatcher.FindAlgorithm(collisionObject, otherObject);
				collisionObject.CollisionShape = orgShape;
			}
		}
		public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			if (_manifold == null)
			{
				//swapped?
				_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
				_ownManifold = true;
			}
			resultOut.SetPersistentManifold(_manifold);

			ConvexShape min0 = bodyA.CollisionShape as ConvexShape;
			ConvexShape min1 = bodyB.CollisionShape as ConvexShape;

			GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();

			//TODO: if (dispatchInfo.m_useContinuous)
			_gjkPairDetector.setMinkowskiA(min0);
			_gjkPairDetector.setMinkowskiB(min1);
			input.MaximumDistanceSquared = min0.Margin + min1.Margin + PersistentManifold.ContactBreakingThreshold;
			input.MaximumDistanceSquared *= input.MaximumDistanceSquared;

			//	input.m_maximumDistanceSquared = 1e30f;

			input.TransformA = bodyA.WorldTransform;
			input.TransformB = bodyB.WorldTransform;

			_gjkPairDetector.GetClosestPoints(input, resultOut, dispatchInfo.DebugDraw);
		}
예제 #7
0
 public ConvexConvexAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
     : base(collisionAlgorithmConstructionInfo)
 {
     _gjkPairDetector = new GjkPairDetector(null, null, simplexSolver, penetrationDepthSolver);
     _ownManifold = false;
     _manifold = manifold;
     _lowLevelOfDetail = false;
 }
		public BridgeTriangleRaycastCallback(Vector3 from, Vector3 to,
								CollisionWorld.RayResultCallback resultCallback, CollisionObject collisionObject, TriangleMeshShape triangleMesh)
			: base(from, to)
		{
			_resultCallback = resultCallback;
			_collisionObject = collisionObject;
			_triangleMesh = triangleMesh;
		}
예제 #9
0
		public ConvexTriangleCallback(IDispatcher dispatcher, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
		{
			_dispatcher = dispatcher;
			_dispatchInfo = null;
			_convexBody = isSwapped ? bodyB : bodyA;
			_triBody = isSwapped ? bodyA : bodyB;

			// create the manifold from the dispatcher 'manifold pool'
			_manifold = _dispatcher.GetNewManifold(_convexBody, _triBody);
			ClearCache();
		}
		public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			CollisionObject convexbody = _isSwapped ? bodyB : bodyA;
			CollisionObject triBody = _isSwapped ? bodyA : bodyB;


			//quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)

			//only perform CCD above a certain threshold, this prevents blocking on the long run
			//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
			float squareMot0 = (convexbody.InterpolationWorldTransform.Translation - convexbody.WorldTransform.Translation).LengthSquared();
			if (squareMot0 < convexbody.CcdSquareMotionThreshold)
			{
				return 1;
			}

            Matrix triInv = MathHelper.InvertMatrix(triBody.WorldTransform);
			Matrix convexFromLocal = triInv * convexbody.WorldTransform;
			Matrix convexToLocal = triInv * convexbody.InterpolationWorldTransform;

			if (triBody.CollisionShape.IsConcave)
			{
				Vector3 rayAabbMin = convexFromLocal.Translation;
				MathHelper.SetMin(ref rayAabbMin, convexToLocal.Translation);
				Vector3 rayAabbMax = convexFromLocal.Translation;
				MathHelper.SetMax(ref rayAabbMax, convexToLocal.Translation);
				float ccdRadius0 = convexbody.CcdSweptSphereRadius;
				rayAabbMin -= new Vector3(ccdRadius0, ccdRadius0, ccdRadius0);
				rayAabbMax += new Vector3(ccdRadius0, ccdRadius0, ccdRadius0);

				float curHitFraction = 1f; //is this available?
				LocalTriangleSphereCastCallback raycastCallback = new LocalTriangleSphereCastCallback(convexFromLocal, convexToLocal,
					convexbody.CcdSweptSphereRadius, curHitFraction);

				raycastCallback.HitFraction = convexbody.HitFraction;

				CollisionObject concavebody = triBody;

				ConcaveShape triangleMesh = concavebody.CollisionShape as ConcaveShape;

				if (triangleMesh != null)
				{
					triangleMesh.ProcessAllTriangles(raycastCallback, rayAabbMin, rayAabbMax);
				}

				if (raycastCallback.HitFraction < convexbody.HitFraction)
				{
					convexbody.HitFraction = raycastCallback.HitFraction;
					return raycastCallback.HitFraction;
				}
			}

			return 1;
		}
		public SphereSphereCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
			: base(collisionAlgorithmConstructionInfo)
		{
			_ownManifold = false;
			_manifold = manifold;

			if (_manifold == null)
			{
				_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
				_ownManifold = true;
			}
		}
		public SphereBoxCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject collisionObjectA, CollisionObject collisionObjectB, bool isSwapped)
			: base(collisionAlgorithmConstructionInfo)
		{
			_ownManifold = false;
			_manifold = manifold;
			_isSwapped = isSwapped;

			CollisionObject sphereObject = _isSwapped ? collisionObjectB : collisionObjectA;
			CollisionObject boxObject = _isSwapped ? collisionObjectA : collisionObjectB;

			if (_manifold == null && Dispatcher.NeedsCollision(sphereObject, boxObject))
			{
				_manifold = Dispatcher.GetNewManifold(sphereObject, boxObject);
				_ownManifold = true;
			}
		}
		public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			if (_manifold == null)
				return;

			SphereShape sphere = bodyA.CollisionShape as SphereShape;
			TriangleShape triangle = bodyB.CollisionShape as TriangleShape;

			/// report a contact. internally this will be kept persistent, and contact reduction is done
			resultOut.SetPersistentManifold(_manifold);
			SphereTriangleDetector detector = new SphereTriangleDetector(sphere, triangle);

			DiscreteCollisionDetectorInterface.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
			input.MaximumDistanceSquared = 1e30f;//todo: tighter bounds
			input.TransformA = bodyA.WorldTransform;
			input.TransformB = bodyB.WorldTransform;

			detector.GetClosestPoints(input, resultOut, null);
		}
예제 #14
0
        public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            CollisionObject collisionObject = _isSwapped ? bodyB : bodyA;
            CollisionObject otherObject = _isSwapped ? bodyA : bodyB;

            BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

            CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;

            float hitFraction = 1.0f;

            for (int i = 0; i < _childCollisionAlgorithms.Count; i++)
            {
                CollisionShape childShape = compoundShape.GetChildShape(i);

                Matrix orgTransform = collisionObject.WorldTransform;
                CollisionShape orgShape = collisionObject.CollisionShape;

                Matrix childTransform = compoundShape.GetChildTransform(i);
                Matrix newChildWorld = orgTransform * childTransform;
                collisionObject.WorldTransform = newChildWorld;

                collisionObject.CollisionShape = childShape;
                float frac = _childCollisionAlgorithms[i].CalculateTimeOfImpact(
                    collisionObject, otherObject, dispatchInfo, resultOut
                );

                if (frac < hitFraction)
                {
                    hitFraction = frac;
                }

                collisionObject.CollisionShape = orgShape;
                collisionObject.WorldTransform = orgTransform;
            }

            return hitFraction;
        }
예제 #15
0
		public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB, PersistentManifold sharedManifold)
		{
			CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo = new CollisionAlgorithmConstructionInfo();
			collisionAlgorithmConstructionInfo.Dispatcher = this;
			collisionAlgorithmConstructionInfo.Manifold = sharedManifold;
			CollisionAlgorithm collisionAlgorithm = _doubleDispatch[(int)bodyA.CollisionShape.ShapeType, (int)bodyB.CollisionShape.ShapeType].CreateCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB);
			return collisionAlgorithm;
		}
예제 #16
0
		public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB)
		{
			return FindAlgorithm(bodyA, bodyB, null);
		}
예제 #17
0
			public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
			{
				return new EmptyAlgorithm(collisionAlgorithmConstructionInfo);
			}
예제 #18
0
		public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			return 1f;
		}
예제 #19
0
		public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { }
예제 #20
0
        public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
        {
            RigidBody rb;
            BulletXCharacter bxcA = null;
            BulletXPrim bxpA = null;
            Type t = bodyA.GetType();
            if (t == typeof (RigidBody))
            {
                rb = (RigidBody) bodyA;
                relatedScene._characters.TryGetValue(rb, out bxcA);
                relatedScene._prims.TryGetValue(rb, out bxpA);
            }
//             String nameA;
//             if (bxcA != null)
//                 nameA = bxcA._name;
//             else if (bxpA != null)
//                 nameA = bxpA._name;
//             else
//                 nameA = "null";



            BulletXCharacter bxcB = null;
            BulletXPrim bxpB = null;
            t = bodyB.GetType();
            if (t == typeof (RigidBody))
            {
                rb = (RigidBody) bodyB;
                relatedScene._characters.TryGetValue(rb, out bxcB);
                relatedScene._prims.TryGetValue(rb, out bxpB);
            }

//             String nameB;
//             if (bxcB != null)
//                 nameB = bxcB._name;
//             else if (bxpB != null)
//                 nameB = bxpB._name;
//             else
            //                 nameB = "null";
            bool needsCollision;// = base.NeedsCollision(bodyA, bodyB);
            int c1 = 3;
            int c2 = 3;

            ////////////////////////////////////////////////////////
            //BulletX Mesh Collisions
            //added by Jed zhu
            //data: May 07,2005
            ////////////////////////////////////////////////////////
            #region BulletXMeshCollisions Fields


            if (bxcA != null && bxpB != null)
                c1 = Collision(bxcA, bxpB);
            if (bxpA != null && bxcB != null)
                c2 = Collision(bxcB, bxpA);
            if (c1 < 2)
                needsCollision = (c1 > 0) ? true : false;
            else if (c2 < 2)
                needsCollision = (c2 > 0) ? true : false;
            else
                needsCollision = base.NeedsCollision(bodyA, bodyB);


            #endregion


            //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
                                   //needsCollision);


            return needsCollision;
        }
		public float GetSphereDistance(CollisionObject boxObject, out Vector3 pointOnBox, out Vector3 pointOnSphere, Vector3 sphereCenter, float radius)
		{
			pointOnBox = new Vector3();
			pointOnSphere = new Vector3();

			float margins;
			Vector3[] bounds = new Vector3[2];
			BoxShape boxShape = boxObject.CollisionShape as BoxShape;

			bounds[0] = -boxShape.HalfExtents;
			bounds[1] = boxShape.HalfExtents;

			margins = boxShape.Margin; //also add sphereShape margin?

			Matrix m44T = boxObject.WorldTransform;

			Vector3[] boundsVec = new Vector3[2];
			float penetration;

			boundsVec[0] = bounds[0];
			boundsVec[1] = bounds[1];

			Vector3 marginsVec = new Vector3(margins, margins, margins);

			// add margins
			bounds[0] += marginsVec;
			bounds[1] -= marginsVec;

			/////////////////////////////////////////////////

			Vector3 tmp, prel, normal, v3P;
			Vector3[] n = new Vector3[6];
			float sep = 10000000.0f, sepThis;

			n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
			n[1] = new Vector3(0.0f, -1.0f, 0.0f);
			n[2] = new Vector3(0.0f, 0.0f, -1.0f);
			n[3] = new Vector3(1.0f, 0.0f, 0.0f);
			n[4] = new Vector3(0.0f, 1.0f, 0.0f);
			n[5] = new Vector3(0.0f, 0.0f, 1.0f);

			// convert  point in local space
			prel = MathHelper.InvXForm(m44T, sphereCenter);

			bool found = false;

			v3P = prel;

			for (int i = 0; i < 6; i++)
			{
				int j = i < 3 ? 0 : 1;
				if ((sepThis = (Vector3.Dot(v3P - bounds[j], n[i]))) > 0.0f)
				{
					v3P = v3P - n[i] * sepThis;
					found = true;
				}
			}

			//

			if (found)
			{
				bounds[0] = boundsVec[0];
				bounds[1] = boundsVec[1];

				normal = Vector3.Normalize(prel - v3P);
				pointOnBox = v3P + normal * margins;
				pointOnSphere = prel - normal * radius;

				if ((Vector3.Dot(pointOnSphere - pointOnBox, normal)) > 0.0f)
				{
					return 1.0f;
				}

				// transform back in world space
				tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
				pointOnBox = tmp;
				tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
				pointOnSphere = tmp;
				float seps2 = (pointOnBox - pointOnSphere).LengthSquared();

				//if this fails, fallback into deeper penetration case, below
				if (seps2 > MathHelper.Epsilon)
				{
					sep = -(float)Math.Sqrt(seps2);
					normal = (pointOnBox - pointOnSphere);
					normal *= 1f / sep;
				}
				return sep;
			}

			//////////////////////////////////////////////////
			// Deep penetration case

			penetration = GetSpherePenetration(boxObject, ref pointOnBox, ref pointOnSphere, sphereCenter, radius, bounds[0], bounds[1]);

			bounds[0] = boundsVec[0];
			bounds[1] = boundsVec[1];

			if (penetration <= 0.0f)
				return (penetration - margins);
			else
				return 1.0f;
		}
			public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
			{
				if (!IsSwapped)
					return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
				else
					return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
			}
		public override float CalculateTimeOfImpact(CollisionObject collisionObjectA, CollisionObject collisionObjectB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			//not yet
			return 1;
		}
		public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
		{
			if (_manifold == null)
				return;

			CollisionObject sphereObject = _isSwapped ? bodyB : bodyA;
			CollisionObject boxObject = _isSwapped ? bodyA : bodyB;

			SphereShape sphereA = sphereObject.CollisionShape as SphereShape;

			Vector3 pOnBox, pOnSphere;
			Vector3 sphereCenter = sphereObject.WorldTransform.Translation;
			float radius = sphereA.Radius;

			float dist = GetSphereDistance(boxObject, out pOnBox, out pOnSphere, sphereCenter, radius);

			if (dist < MathHelper.Epsilon)
			{
				Vector3 normalOnSurfaceB = Vector3.Normalize(pOnBox - pOnSphere);

				// report a contact. internally this will be kept persistent, and contact reduction is done
				resultOut.SetPersistentManifold(_manifold);
				resultOut.AddContactPoint(normalOnSurfaceB, pOnBox, dist);
			}
		}
예제 #25
0
        public override float CalculateTimeOfImpact(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            //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,
            float resultFraction = 1f;

            float squareMotA = (colA.InterpolationWorldTransform.Translation - colA.WorldTransform.Translation).LengthSquared();
            float squareMotB = (colB.InterpolationWorldTransform.Translation - colB.WorldTransform.Translation).LengthSquared();

            if (squareMotA < colA.CcdSquareMotionThreshold &&
                squareMotB < colB.CcdSquareMotionThreshold)
                return resultFraction;

            if (DisableCcd)
                return 1f;

            //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
            {
                ConvexShape convexA = colA.CollisionShape as ConvexShape;

                SphereShape sphereB = new SphereShape(colB.CcdSweptSphereRadius); //todo: allow non-zero sphere sizes, for better approximation
                CastResult result = new CastResult();
                VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
                //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
                //Simplification, one object is simplified as a sphere
                GjkConvexCast ccdB = new GjkConvexCast(convexA, sphereB, voronoiSimplex);
                //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
                if (ccdB.CalcTimeOfImpact(colA.WorldTransform, colA.InterpolationWorldTransform,
                    colB.WorldTransform, colB.InterpolationWorldTransform, result))
                {
                    //store result.m_fraction in both bodies
                    if (colA.HitFraction > result.Fraction)
                        colA.HitFraction = result.Fraction;

                    if (colB.HitFraction > result.Fraction)
                        colB.HitFraction = result.Fraction;

                    if (resultFraction > result.Fraction)
                        resultFraction = result.Fraction;
                }
            }

            // Sphere (for convex0) against Convex1
            {
                ConvexShape convexB = colB.CollisionShape as ConvexShape;

                SphereShape sphereA = new SphereShape(colA.CcdSweptSphereRadius); //todo: allow non-zero sphere sizes, for better approximation
                CastResult result = new CastResult();
                VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
                //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
                ///Simplification, one object is simplified as a sphere
                GjkConvexCast ccdB = new GjkConvexCast(sphereA, convexB, voronoiSimplex);
                //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
                if (ccdB.CalcTimeOfImpact(colA.WorldTransform, colA.InterpolationWorldTransform,
                    colB.WorldTransform, colB.InterpolationWorldTransform, result))
                {
                    //store result.m_fraction in both bodies
                    if (colA.HitFraction > result.Fraction)
                        colA.HitFraction = result.Fraction;

                    if (colB.HitFraction > result.Fraction)
                        colB.HitFraction = result.Fraction;

                    if (resultFraction > result.Fraction)
                        resultFraction = result.Fraction;
                }
            }
            return resultFraction;
        }
예제 #26
0
 public virtual CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1)
 {
     return null;
 }
예제 #27
0
		/*public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1)
		{
			return internalFindAlgorithm(body0, body1, null);
		}

		public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1, PersistentManifold sharedManifold)
		{
			m_count++;

			CollisionAlgorithmConstructionInfo ci = new CollisionAlgorithmConstructionInfo();
			ci.m_dispatcher = this;

			if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConvex())
			{
				return new ConvexConvexAlgorithm(sharedManifold, ci, body0, body1);
			}

			if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConcave())
			{
				return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, false);
			}

			if (body1.getCollisionShape().isConvex() && body0.getCollisionShape().isConcave())
			{
				return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, true);
			}

			if (body0.getCollisionShape().isCompound())
			{
				return new CompoundCollisionAlgorithm(ci, body0, body1, false);
			}
			else
			{
				if (body1.getCollisionShape().isCompound())
				{
					return new CompoundCollisionAlgorithm(ci, body0, body1, true);
				}
			}

			//failed to find an algorithm
			return new EmptyAlgorithm(ci);
		}*/

		public virtual bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
		{
			if (bodyA == null || bodyB == null)
				throw new BulletException();

			bool needsCollision = true;

			//broadphase filtering already deals with this
			/*if ((body0.isStaticObject() || body0.isKinematicObject()) &&
				(body1.isStaticObject() || body1.isKinematicObject()))
			{
				printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
			}*/

			if ((!bodyA.IsActive) && (!bodyB.IsActive))
				needsCollision = false;

			return needsCollision;
		}
예제 #28
0
		public virtual bool NeedsResponse(CollisionObject bodyA, CollisionObject bodyB)
		{
			//here you can do filtering
			bool hasResponse = bodyA.HasContactResponse && bodyB.HasContactResponse;
			hasResponse = hasResponse && (!bodyA.IsStaticOrKinematicObject || !bodyB.IsStaticOrKinematicObject);
			return hasResponse;
		}
			public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
			{
				return new SphereTriangleCollisionAlgorithm(collisionAlgorithmConstructionInfo.Manifold, collisionAlgorithmConstructionInfo, bodyA, bodyB, IsSwapped);
			}
		public float GetSpherePenetration(CollisionObject boxObject, ref Vector3 pointOnBox, ref Vector3 pointOnSphere, Vector3 sphereCenter, float radius, Vector3 aabbMin, Vector3 aabbMax)
		{
			Vector3[] bounds = new Vector3[2];

			bounds[0] = aabbMin;
			bounds[1] = aabbMax;

			Vector3 p0 = new Vector3(), tmp, prel, normal = new Vector3();
			Vector3[] n = new Vector3[6];
			float sep = -10000000.0f, sepThis;

			n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
			n[1] = new Vector3(0.0f, -1.0f, 0.0f);
			n[2] = new Vector3(0.0f, 0.0f, -1.0f);
			n[3] = new Vector3(1.0f, 0.0f, 0.0f);
			n[4] = new Vector3(0.0f, 1.0f, 0.0f);
			n[5] = new Vector3(0.0f, 0.0f, 1.0f);

			Matrix m44T = boxObject.WorldTransform;

			// convert point in local space
			prel = MathHelper.InvXForm(m44T, sphereCenter);

			///////////

			for (int i = 0; i < 6; i++)
			{
				int j = i < 3 ? 0 : 1;
				if ((sepThis = (Vector3.Dot(prel - bounds[j], n[i])) - radius) > 0.0f) return 1.0f;
				if (sepThis > sep)
				{
					p0 = bounds[j];
					normal = n[i];
					sep = sepThis;
				}
			}

			pointOnBox = prel - normal * (Vector3.Dot(normal, (prel - p0)));
			pointOnSphere = pointOnBox + normal * sep;

			// transform back in world space
			tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
			pointOnBox = tmp;
			tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
			pointOnSphere = tmp;
			normal = Vector3.Normalize(pointOnBox - pointOnSphere);

			return sep;
		}
예제 #31
0
 public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB)
 {
     return(FindAlgorithm(bodyA, bodyB, null));
 }