/// <summary> /// Set /// </summary> /// <param name="sys"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> internal void Set(CollisionSystem sys, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { sys_ = sys; collisionFunctor_ = collisionFunctor; collisionPredicate_ = collisionPredicate; if (collisionPredicate_ == null) { collisionPredicate_ = this; } collTolerance_ = collTolerance; }
/// <summary> /// DetectCollisions /// </summary> /// <param name="body"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> public override void DetectCollisions(JigLibX.Physics.Body body, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { if (!body.IsActive) { return; } CollDetectInfo info = new CollDetectInfo(); info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) { return; } active_.Clear(); testing_.Clear(); Extract(info.Skin0.WorldBoundingBox.Min, info.Skin0.WorldBoundingBox.Max, active_); for (int j = 0, m = info.Skin0.NumPrimitives; j != m; ++j) { testing_.Add(info.Skin0.GetPrimitiveNewWorld(j)); } int nBodyPrims = testing_.Count; for (int i = 0, n = active_.Count; i != n; ++i) { info.Skin1 = active_[i]; if (info.Skin0 != info.Skin1 && (collisionPredicate == null || collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1))) { int nPrim1 = info.Skin1.NumPrimitives; second_.Clear(); for (int k = 0; k != nPrim1; ++k) { second_.Add(info.Skin1.GetPrimitiveNewWorld(k)); } for (info.IndexPrim0 = 0; info.IndexPrim0 != nBodyPrims; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 != nPrim1; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) { f.CollDetect(info, collTolerance, collisionFunctor); } } } } } }
/// <summary> /// As DetectCollisions but detects for all bodies, testing each pair /// only once /// </summary> /// <param name="bodies"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> public abstract void DetectAllCollisions(List <Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance);
/// <summary> /// Detects all collisions between the body and all the registered /// collision skins (which should have already had their /// positions/bounding volumes etc updated). For each potential /// pair of skins then the predicate (if it exists) will be called /// to see whether or not to continue. If the skins are closer /// than collTolerance (+ve value means report objects that aren't /// quite colliding) then the functor will get called. /// You can't just loop over all your bodies calling this, because /// that will double-detect collisions. Use DetectAllCollisions for /// that. /// </summary> public abstract void DetectCollisions(Body body, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance);
/// <summary> /// As DetectCollisions but detects for all bodies, testing each pair /// only once /// </summary> /// <param name="bodies"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> public abstract void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance);
public override void DetectAllCollisions(List <JigLibX.Physics.Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { skinTester_.Set(this, collisionFunctor, collisionPredicate, collTolerance); MaybeSort(); // I know that each skin for the bodies is already in my list of skins. // Thus, I can do collision between all skins, culling out non-active bodies. int nSkins = skins_.Count; active_.Clear(); // sweep the sorted list for potential overlaps for (int i = 0; i != nSkins; ++i) { AddToActive(skins_[i], skinTester_); } }
public override void DetectAllCollisions(List <Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { var numBodies = bodies.Count; var info = new CollDetectInfo(); for (var iBody = 0; iBody < numBodies; ++iBody) { var body = bodies[iBody]; if (!body.IsActive) { continue; } info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) { continue; } tempGridLists.Clear(); GetListsToCheck(tempGridLists, info.Skin0); for (var iList = tempGridLists.Count; iList-- != 0;) { var entry = tempGridLists[iList]; for (entry = entry.Next; entry != null; entry = entry.Next) { info.Skin1 = entry.Skin; if (info.Skin1 == info.Skin0) { continue; } if (info.Skin1 == null) { continue; } var skinSleeping = true; if (info.Skin1.Owner != null && info.Skin1.Owner.IsActive) { skinSleeping = false; } if (skinSleeping == false && info.Skin1.ID < info.Skin0.ID) { continue; } if (collisionPredicate != null && !collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1)) { continue; } if (BoundingBoxHelper.OverlapTest(ref info.Skin1.WorldBoundingBox, ref info.Skin0.WorldBoundingBox, collTolerance)) { if (CheckCollidables(info.Skin0, info.Skin1)) { var bodyPrimitives = info.Skin0.NumPrimitives; var primitves = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1) { var f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); f?.CollDetect(info, collTolerance, collisionFunctor); } } } } } } } }
public override void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { int numBodies = bodies.Count; CollDetectInfo info = new CollDetectInfo(); for (int iBody = 0; iBody < numBodies; ++iBody) { Body body = bodies[iBody]; if (!body.IsActive) continue; info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) continue; tempGridLists.Clear(); GetListsToCheck(tempGridLists, info.Skin0); for (int iList = tempGridLists.Count; iList-- != 0; ) { // first one is a placeholder; GridEntry entry = tempGridLists[iList]; for (entry = entry.Next; entry != null; entry = entry.Next) { info.Skin1 = entry.Skin; if (info.Skin1 == info.Skin0) continue; // CHANGE if (info.Skin1 == null) continue; bool skinSleeping = true; if ((info.Skin1.Owner != null) && (info.Skin1.Owner.IsActive)) skinSleeping = false; // only do one per pair if ((skinSleeping == false) && (info.Skin1.ID < info.Skin0.ID)) continue; if ((collisionPredicate != null) && (!collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1))) continue; // basic bbox test if (BoundingBoxHelper.OverlapTest(ref info.Skin1.WorldBoundingBox, ref info.Skin0.WorldBoundingBox, collTolerance)) { if (CheckCollidables(info.Skin0, info.Skin1)) { int bodyPrimitives = info.Skin0.NumPrimitives; int primitves = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) f.CollDetect(info, collTolerance, collisionFunctor); } } } // check collidables } // overlapt test }// loop over entries } // loop over lists } // loop over bodies }
/// <summary> /// DetectAllCollisions /// </summary> /// <param name="bodies"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> public override void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { int numSkins = skins.Count; int numBodies = bodies.Count; CollDetectInfo info = new CollDetectInfo(); for (int ibody = 0; ibody < numBodies; ++ibody) { Body body = bodies[ibody]; if(!body.IsActive) continue; info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) continue; for (int skin = 0; skin < numSkins; ++skin) { info.Skin1 = skins[skin]; if (info.Skin0 == info.Skin1) continue; // CHANGE if (info.Skin1 == null) continue; bool skinSleeping = true; if (info.Skin1.Owner != null && info.Skin1.Owner.IsActive) skinSleeping = false; if ((skinSleeping == false) && (info.Skin1.ID < info.Skin0.ID)) continue; if((collisionPredicate != null) && collisionPredicate.ConsiderSkinPair(info.Skin0,info.Skin1) == false) continue; // basic bbox test if(BoundingBoxHelper.OverlapTest(ref info.Skin0.WorldBoundingBox, ref info.Skin1.WorldBoundingBox,collTolerance)) { if (CheckCollidables(info.Skin0,info.Skin1)) { int bodyPrimitives = info.Skin0.NumPrimitives; int primitves = info.Skin1.NumPrimitives; for(info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) f.CollDetect(info, collTolerance, collisionFunctor); } } } } // overlapt test } // loop over skins } // loop over bodies }
public override void DetectCollisions(Body body, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { if (!body.IsActive) { return; } CollDetectInfo info = new CollDetectInfo(); info.Skin0 = body.CollisionSkin; //?! if (info.Skin0 == null) { return; } int bodyPrimitves = info.Skin0.NumPrimitives; int numSkins = skins.Count; for (int skin = 0; skin < numSkins; ++skin) { info.Skin1 = skins[skin]; if ((info.Skin0 != info.Skin1) && CheckCollidables(info.Skin0, info.Skin1)) { int primitives = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitves; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitives; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) { f.CollDetect(info, collTolerance, collisionFunctor); } } } } } }
public override void DetectAllCollisions(List <Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { int numSkins = skins.Count; int numBodies = bodies.Count; CollDetectInfo info = new CollDetectInfo(); for (int ibody = 0; ibody < numBodies; ++ibody) { Body body = bodies[ibody]; if (!body.IsActive) { continue; } info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) { continue; } for (int skin = 0; skin < numSkins; ++skin) { info.Skin1 = skins[skin]; if (info.Skin0 == info.Skin1) { continue; } // CHANGE if (info.Skin1 == null) { continue; } bool skinSleeping = true; if (info.Skin1.Owner != null && info.Skin1.Owner.IsActive) { skinSleeping = false; } if ((skinSleeping == false) && (info.Skin1.ID < info.Skin0.ID)) { continue; } if ((collisionPredicate != null) && collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1) == false) { continue; } // basic bbox test if (BoundingBoxHelper.OverlapTest(ref info.Skin0.WorldBoundingBox, ref info.Skin1.WorldBoundingBox, collTolerance)) { if (CheckCollidables(info.Skin0, info.Skin1)) { int bodyPrimitives = info.Skin0.NumPrimitives; int primitves = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) { f.CollDetect(info, collTolerance, collisionFunctor); } } } } } // overlapt test } // loop over skins } // loop over bodies } // void
public override void DetectAllCollisions(List <Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { var numSkins = skins.Count; var numBodies = bodies.Count; var info = new CollDetectInfo(); for (var ibody = 0; ibody < numBodies; ++ibody) { var body = bodies[ibody]; if (!body.IsActive) { continue; } info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) { continue; } for (var skin = 0; skin < numSkins; ++skin) { info.Skin1 = skins[skin]; if (info.Skin0 == info.Skin1) { continue; } if (info.Skin1 == null) { continue; } var skinSleeping = true; if (info.Skin1.Owner != null && info.Skin1.Owner.IsActive) { skinSleeping = false; } if (skinSleeping == false && info.Skin1.ID < info.Skin0.ID) { continue; } if (collisionPredicate != null && collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1) == false) { continue; } if (BoundingBoxHelper.OverlapTest(ref info.Skin0.WorldBoundingBox, ref info.Skin1.WorldBoundingBox, collTolerance)) { if (CheckCollidables(info.Skin0, info.Skin1)) { var bodyPrimitives = info.Skin0.NumPrimitives; var primitves = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1) { var f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); f?.CollDetect(info, collTolerance, collisionFunctor); } } } } } } }
/// <summary> /// DetectAllCollisions /// </summary> /// <param name="bodies"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> public override void DetectAllCollisions(List <Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { int numBodies = bodies.Count; CollDetectInfo info = new CollDetectInfo(); for (int iBody = 0; iBody < numBodies; ++iBody) { Body body = bodies[iBody]; if (!body.IsActive) { continue; } info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) { continue; } tempGridLists.Clear(); GetListsToCheck(tempGridLists, info.Skin0); for (int iList = tempGridLists.Count; iList-- != 0;) { // first one is a placeholder; GridEntry entry = tempGridLists[iList]; for (entry = entry.Next; entry != null; entry = entry.Next) { info.Skin1 = entry.Skin; if (info.Skin1 == info.Skin0) { continue; } // CHANGE if (info.Skin1 == null) { continue; } bool skinSleeping = true; if ((info.Skin1.Owner != null) && (info.Skin1.Owner.IsActive)) { skinSleeping = false; } // only do one per pair if ((skinSleeping == false) && (info.Skin1.ID < info.Skin0.ID)) { continue; } if ((collisionPredicate != null) && (!collisionPredicate.ConsiderSkinPair(info.Skin0, info.Skin1))) { continue; } // basic bbox test if (BoundingBoxHelper.OverlapTest(ref info.Skin1.WorldBoundingBox, ref info.Skin0.WorldBoundingBox, collTolerance)) { if (CheckCollidables(info.Skin0, info.Skin1)) { int bodyPrimitives = info.Skin0.NumPrimitives; int primitves = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitves; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) { f.CollDetect(info, collTolerance, collisionFunctor); } } } } // check collidables } // overlapt test } // loop over entries } // loop over lists } // loop over bodies }
/// <summary> /// DetectAllCollisions /// </summary> /// <param name="bodies"></param> /// <param name="collisionFunctor"></param> /// <param name="collisionPredicate"></param> /// <param name="collTolerance"></param> public override void DetectAllCollisions(List <JigLibX.Physics.Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { skinTester_.Set(this, collisionFunctor, collisionPredicate, collTolerance); MaybeSort(); // I know that each skin for the bodies is already in my list of skins. // Thus, I can do collision between all skins, culling out non-active bodies. int nSkins = skins_.Count; active_.Clear(); #if WINDOWS_PHONE for (int i = 0; i != nSkins; ++i) { AddToActive(skins_[i], skinTester_); } #else // BEN-OPTIMISATION: unsafe, remove array boundary checks. unsafe { for (int i = 0; i != nSkins; ++i) { AddToActive(skins_[i], skinTester_); } } #endif }
public override void DetectCollisions(Body body, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { if (!body.IsActive) return; CollDetectInfo info = new CollDetectInfo(); info.Skin0 = body.CollisionSkin; if (info.Skin0 == null) return; int bodyPrimitives = info.Skin0.NumPrimitives; int numSkins = skins.Count; for (int skin = 0; skin < numSkins; ++skin) { info.Skin1 = skins[skin]; if ((info.Skin0 != info.Skin1) && CheckCollidables(info.Skin0, info.Skin1)) { int primitives = info.Skin1.NumPrimitives; for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitives; ++info.IndexPrim0) { for (info.IndexPrim1 = 0; info.IndexPrim1 < primitives; ++info.IndexPrim1) { DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type, info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type); if (f != null) f.CollDetect(info, collTolerance, collisionFunctor); } } } } }
public override void DetectAllCollisions(List <Physics.Body> bodies, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance) { skinTester_.Set(this, collisionFunctor, collisionPredicate, collTolerance); MaybeSort(); var nSkins = skins_.Count; active_.Clear(); unsafe { for (var i = 0; i != nSkins; ++i) { AddToActive(skins_[i], skinTester_); } } }