internal void TestSkin(CollisionSkin b, CollisionSkin s) { System.Diagnostics.Debug.Assert(b.Owner != null); System.Diagnostics.Debug.Assert(b.Owner.IsActive); if (!collisionPredicate_.ConsiderSkinPair(b, s)) { return; } info_.Skin0 = b; info_.Skin1 = s; int nSkin0 = info_.Skin0.NumPrimitives; int nSkin1 = info_.Skin1.NumPrimitives; for (info_.IndexPrim0 = 0; info_.IndexPrim0 != nSkin0; ++info_.IndexPrim0) { for (info_.IndexPrim1 = 0; info_.IndexPrim1 != nSkin1; ++info_.IndexPrim1) { if (CheckCollidables(info_.Skin0, info_.Skin1)) { DetectFunctor f = sys_.GetCollDetectFunctor(info_.Skin0.GetPrimitiveNewWorld(info_.IndexPrim0).Type, info_.Skin1.GetPrimitiveNewWorld(info_.IndexPrim1).Type); if (f != null) { f.CollDetect(info_, collTolerance_, collisionFunctor_); } } } } }
/// <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> /// type0/1 could be from tCollisionSkinType or they could be /// larger values. The collision detection table will get extended /// as necessary. You only need to register the function once /// (i.e. not for type0, type1 then type1, type 0). /// </summary> /// <param name="f"></param> public void RegisterCollDetectFunctor(DetectFunctor f) { int key01 = f.Type0 << 16 | f.Type1; int key10 = f.Type1 << 16 | f.Type0; if (!detectionFunctors.ContainsKey(key01)) { detectionFunctors.Add(key01, f); } if (!detectionFunctors.ContainsKey(key10)) { detectionFunctors.Add(key10, f); } }
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); } } } } } }
/// <summary> /// type0/1 could be from tCollisionSkinType or they could be /// larger values. The collision detection table will get extended /// as necessary. You only need to register the function once /// (i.e. not for type0, type1 then type1, type 0). /// </summary> /// <param name="f"></param> public void RegisterCollDetectFunctor(DetectFunctor f) { int key01 = f.Type0 << 16 | f.Type1; int key10 = f.Type1 << 16 | f.Type0; if (!detectionFunctors.ContainsKey(key01)) detectionFunctors.Add(key01,f); if (!detectionFunctors.ContainsKey(key10)) detectionFunctors.Add(key10,f); }
public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == Type1) { CollisionSkin skinSwap = info.Skin0; info.Skin0 = info.Skin1; info.Skin1 = skinSwap; int primSwap = info.IndexPrim0; info.IndexPrim0 = info.IndexPrim1; info.IndexPrim1 = primSwap; } var oldCapsule = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Capsule; var newCapsule = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Capsule; var oldHeightmap = info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1) as CubeHeightmapCollisionShape; var newHeightmap = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as CubeHeightmapCollisionShape; Vector3[] oldPoints = new Vector3[2]; Vector3[] newPoints = new Vector3[2]; oldPoints[0] = oldCapsule.Position; oldPoints[1] = oldCapsule.GetEnd(); newPoints[0] = newCapsule.Position; newPoints[1] = newCapsule.GetEnd(); if (capsuleBoxDetectFunctor == null) { capsuleBoxDetectFunctor = PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.GetCollDetectFunctor( (int) PrimitiveType.Capsule, (int) PrimitiveType.Box); } oldHeightmap.GetMapPositions(oldPoints, oldMapPositions); newHeightmap.GetMapPositions(newPoints, newMapPositions); // TODO: needed ? foreach (var oldMapPosition in oldMapPositions) { if (!newMapPositions.Contains(oldMapPosition)) { newMapPositions.Add(oldMapPosition); } } bool sameHeight = true; float prevHeight = newHeightmap.GetHeight(newMapPositions[0]); for (int i = 1; i < newMapPositions.Count; i++) { if (prevHeight != newHeightmap.GetHeight(newMapPositions[i])) { sameHeight = false; break; } } #region As plane if (sameHeight) { virtualPlaneSkin.SetMaterialProperties(0, info.Skin1.GetMaterialProperties(info.IndexPrim1)); var vcdi = new CollDetectInfo() { Skin0 = info.Skin0, Skin1 = virtualPlaneSkin, IndexPrim0 = info.IndexPrim0, IndexPrim1 = 0 }; virtualCollisionFunctor.CollisionFunctorEntity = collisionFunctor; virtualCollisionFunctor.CollDetectInfoEntity = info; var oldPlane = virtualPlaneSkin.GetPrimitiveOldWorld(0) as JPlane; var newPlane = virtualPlaneSkin.GetPrimitiveNewWorld(0) as JPlane; oldHeightmap.PrepareVirtualPlane(newMapPositions[0], oldPlane); newHeightmap.PrepareVirtualPlane(newMapPositions[0], newPlane); if (capsulePlaneDetectFunctor == null) { var collisionSystem = PhysicsSystem.CurrentPhysicsSystem.CollisionSystem; capsulePlaneDetectFunctor = collisionSystem.GetCollDetectFunctor( (int) PrimitiveType.Capsule, (int) PrimitiveType.Plane); } virtualCollisionFunctor.CollisionFunctorEntity = collisionFunctor; virtualCollisionFunctor.CollDetectInfoEntity = info; capsulePlaneDetectFunctor.CollDetect(vcdi, collTolerance, virtualCollisionFunctor); return; } #endregion #region As boxes virtualBoxSkin.SetMaterialProperties(0, info.Skin1.GetMaterialProperties(info.IndexPrim1)); CollDetectInfo virtualCollDetectInfo = new CollDetectInfo() { Skin0 = info.Skin0, Skin1 = virtualBoxSkin, IndexPrim0 = info.IndexPrim0, IndexPrim1 = 0 }; virtualCollisionFunctor.CollisionFunctorEntity = collisionFunctor; virtualCollisionFunctor.CollDetectInfoEntity = info; foreach (var newMapPosition in newMapPositions) { var oldPrimitive = virtualBoxSkin.GetPrimitiveOldWorld(0) as Box; var newPrimitive = virtualBoxSkin.GetPrimitiveNewWorld(0) as Box; oldHeightmap.PrepareVirtualBox(newMapPosition, oldPrimitive); newHeightmap.PrepareVirtualBox(newMapPosition, newPrimitive); capsuleBoxDetectFunctor.CollDetect(virtualCollDetectInfo, collTolerance, virtualCollisionFunctor); } #endregion }
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
/// <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 }