Ejemplo n.º 1
0
            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_);
                            }
                        }
                    }
                }
            }
Ejemplo n.º 2
0
        /// <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);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /// <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);
            }
        }
Ejemplo n.º 4
0
        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);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <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
        }
Ejemplo n.º 7
0
        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
Ejemplo n.º 8
0
        /// <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
        }