InitialCollisionDetected event & EntityA/B

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Phippu
Posts: 24
Joined: Fri Jun 03, 2011 3:39 pm

InitialCollisionDetected event & EntityA/B

Post by Phippu » Sat Aug 10, 2013 4:33 pm

I have a little bit stupid but simple question. I have a box where I check the CollisionInformation.Events.InitialCollisionDetected event. I' am now interested in getting the other entity that is colliding with the box from that event. Of course I can do that by using pair.EntityB. My question is: is the box allways EntityA or might it be possible that the box could be EntityB as well (now I' am just looking up entityB for the other entity)?

Thx a lot!

Norbo
Site Admin
Posts: 4588
Joined: Tue Jul 04, 2006 4:45 am

Re: InitialCollisionDetected event & EntityA/B

Post by Norbo » Sat Aug 10, 2013 5:46 pm

The box could be either EntityA or EntityB. You can either test to see which it is, or you can use the 'sender' and 'other' parameters to the event. The sender will always be associated with the box, and the other will be associated with whatever the box is colliding with.

Those parameters are of type Collidable (or some child, in the case of sender). Entities use EntityCollidables, a subclass of Collidable, as their collision proxies. So, if you want to know what entity is associated with the sender, cast the sender to an EntityCollidable if it isn't already one and check its Entity property. The same can be done with the 'other' collidable.

GiveUpGames
Posts: 9
Joined: Thu Jul 25, 2013 11:20 pm

Re: InitialCollisionDetected event & EntityA/B

Post by GiveUpGames » Fri Aug 16, 2013 1:46 pm

I've included Bepu into my game engine, and this is how i did it.......

Code: Select all

        void PhysicsSkin_callbackFn(EntityCollidable sender, Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
        {
             // whatever standard logic applied to both entities to see if i should care about them 
            TestEntityForAttack(pair.EntityA);
            TestEntityForAttack(pair.EntityB);
        }
Now, another thing i did, which is slightly more than you asked, is take advantage of the TAG property, and created a standard method of "tagging" entities.....

I created this class:

Code: Select all

    public class PhysicsEntityTag
    {
        public int CollisionType { get; set; }
        public string Name { get; set; }
        public string ID { get; set; }
        public object Owner { get; set; }
        public bool IsEmpty()
        {
            return (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(ID) && Owner == null && CollisionType == 0);
        }
    }
An instance of that class is assigned to the Entity's TAG property. On the collision event, i use that to check stuff. If i use the "int CollisionType" (above) in a specialized way, i can avoid doing a lot of object casting. Like if i know all NPC's are 4,5 or 6, then i can just check CollisionType on the collision event, and quickly avoid any casts if it's NOT one of those.

Then i made some extension methods (at the bottom of this post). If i put an Entity in the "world" that is supposed to represent the HERO of the game, it would look like:

Code: Select all

// "this" is the HERO
// "SetEntityTag" is the extension method

this.Entity.SetEntityTag(new PhysicsEntityTag()
            {
                CollisionType = 420,
                ID = "oiuasi129129123lkj",
                Name = "Mr. Hero Man",
                Owner = this
            });

So my testing code might look like this........

Code: Select all

// onCollisionEvent

public void TestEntityForAttack(Entity e)
{
            var tag = e.GetEntityTag();

            if (tag != null && tag.CollisionType == 5)
            {
                // since i checked the collisionType, i'm going to be 'daring' and cast
                // the Owner to what i assume it will be. Obviously this means i have to 
                // make sure i assign CollisionTypes properly. 
                ((IEnemy)tag.Owner).RecieveAttack(Vector3.Zero, AttackDamage);
                
            }
}


Oh yeah, and those extension methods. So there, if you want to use it, you have all the code now.

Code: Select all

    public static class EntityExtensions
    {
        public static PhysicsEntityTag GetEntityTag(this Entity entity)
        {

            if (entity == null)
                return new PhysicsEntityTag();
                
            if (entity.Tag == null || !(entity.Tag is PhysicsEntityTag))
            {
                entity.Tag = new PhysicsEntityTag();
            }

            return (PhysicsEntityTag)entity.Tag;

        }

        public static void SetTagOwner(this Entity entity, object owner)
        {
            var tag = entity.GetEntityTag();
            tag.Owner = owner;
        }

        public static void SetCollisionType(this Entity entity, int collisionType)
        {
            var tag = entity.GetEntityTag();
            tag.CollisionType = collisionType;
        }

        public static void SetEntityTag(this Entity entity, PhysicsEntityTag tag)
        {
            if (entity == null)
                throw new Exception("Entity is null. Set Entity tag after Entity has been created");
    
            entity.Tag = tag;
        }
    }

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests