Beispiel #1
0
        private void ContactProcess(object sender, Game.Newt.v1.NewtonDynamics1.Api.CContactProcessEventArgs e)
        {
            #region Get Keys

            string key = _currentCollidingKey;
            if (key == null)
            {
                throw new ApplicationException("ContactProcess was called before ContactBegin");
            }
            else if (!_collisionListeners.ContainsKey(key))
            {
                throw new ApplicationException("There is no listener for this material pair, but how did this callback get set up???: " + key);
            }

            #endregion

            // See if I should duck out early
            CollisionEventProps eventProps = _collisionListeners[key];
            if (eventProps.HasRaisedContactEvent || eventProps.HasContactCancelled)       // if they cancelled in the begin event, but for some reason this process event still fires, I don't want them to see it
            {
                if (eventProps.HasContactCancelled)
                {
                    e.AllowCollision = false;
                }
                return;
            }

            // Remember that I've raised the event to the outside (so they only get informed once)
            eventProps.HasRaisedContactEvent = true;

            // Validate
            if (eventProps.CollisionBody1 == null || eventProps.CollisionBody2 == null)
            {
                throw new ApplicationException("Received a collision contact event without the start event");
            }

            if (eventProps.CollisionEnd != null)
            {
                // Raise an event to the outside
                CollisionEndEventArgs args = new CollisionEndEventArgs(e.Material, e.Contact, eventProps.Material1, eventProps.Material2);
                args.Body1 = eventProps.CollisionBody1;
                args.Body2 = eventProps.CollisionBody2;

                eventProps.CollisionEnd(this, args);

                e.AllowCollision = args.AllowCollision;
            }

            if (!e.AllowCollision)
            {
                eventProps.HasContactCancelled = true;
            }
        }
Beispiel #2
0
        private void ContactBegin(object sender, Game.Newt.v1.NewtonDynamics1.Api.CContactBeginEventArgs e)
        {
            #region Get Keys

            // Get the entry for this material pair
            string key = GetMaterialComboHash(e.Body0.MaterialGroupID, e.Body1.MaterialGroupID);
            if (!_collisionListeners.ContainsKey(key))
            {
                throw new ApplicationException("There is no listener for this material pair, but how did this callback get set up???: " + key);
            }

            // Just to complicate things, the contact process callback doesn't give me bodies, and e.Material is different, so I have store the key,
            // and trust everything is called in order
            _currentCollidingKey = key;

            #endregion

            // Reset for this current collision between these two bodies
            CollisionEventProps eventProps = _collisionListeners[key];
            eventProps.CollisionBody1        = e.Body0.UserData;
            eventProps.CollisionBody2        = e.Body1.UserData;
            eventProps.Material1             = _materials[e.Body0.MaterialGroupID];
            eventProps.Material2             = _materials[e.Body1.MaterialGroupID];
            eventProps.HasRaisedContactEvent = false;
            eventProps.HasContactCancelled   = false;

            if (eventProps.CollisionStart != null)
            {
                // Raise an event to the outside
                CollisionStartEventArgs args = new CollisionStartEventArgs();
                args.Body1 = e.Body0.UserData;
                args.Body2 = e.Body1.UserData;

                eventProps.CollisionStart(this, args);

                // Tell the caller what the user decided
                e.AllowCollision = args.AllowCollision;

                // This shouldn't matter, because the ContactProcess shouldn't be called if they cancelled, but I'm just being safe
                if (!args.AllowCollision)
                {
                    eventProps.HasContactCancelled = true;
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// This lets the consumer get notified when two bodies of the material type are colliding
        /// NOTE:  Currently, only one listener per matieral pair is supported
        /// </summary>
        public void SetCollisionCallback(int material1, int material2, CollisionStartHandler collisionStart, CollisionEndHandler collisionEnd)
        {
            string key = GetMaterialComboHash(material1, material2);

            if (_collisionListeners.ContainsKey(key))
            {
                // Newton 2.0 has a much better collision event system (when listening to the ContactProcess event, all I have is the material, not
                // bodies, so I have to keep track of bodies by material to make it easier on the consumer.  This is all based on the fact that I receive
                // all contact events in order for the current collision of two bodies, then I'll get a different ContactBegin/ContactProcess set for another
                // two bodies)
                throw new ApplicationException("Currently, only one event listener is allowed for each material pair -- upgrade to newton 2");
            }

            // Store the delegates for this material pair
            CollisionEventProps eventProps = new CollisionEventProps();

            eventProps.CollisionStart = collisionStart;
            eventProps.CollisionEnd   = collisionEnd;
            _collisionListeners.Add(key, eventProps);

            // Set up a callback for this material pair
            //NOTE:  The callback goes to my event listener.  I then make the args easier for the consumer, and call the delegates that were passed in
            _materialHelper.SetCollisionCallback(_materials[material1], _materials[material2], null, ContactBegin, ContactProcess, null);
        }
        /// <summary>
        /// This lets the consumer get notified when two bodies of the material type are colliding
        /// NOTE:  Currently, only one listener per matieral pair is supported
        /// </summary>
        public void SetCollisionCallback(int material1, int material2, CollisionStartHandler collisionStart, CollisionEndHandler collisionEnd)
        {
            string key = GetMaterialComboHash(material1, material2);
            if (_collisionListeners.ContainsKey(key))
            {
                // Newton 2.0 has a much better collision event system (when listening to the ContactProcess event, all I have is the material, not
                // bodies, so I have to keep track of bodies by material to make it easier on the consumer.  This is all based on the fact that I receive
                // all contact events in order for the current collision of two bodies, then I'll get a different ContactBegin/ContactProcess set for another
                // two bodies)
                throw new ApplicationException("Currently, only one event listener is allowed for each material pair -- upgrade to newton 2");
            }

            // Store the delegates for this material pair
            CollisionEventProps eventProps = new CollisionEventProps();
            eventProps.CollisionStart = collisionStart;
            eventProps.CollisionEnd = collisionEnd;
            _collisionListeners.Add(key, eventProps);

            // Set up a callback for this material pair
            //NOTE:  The callback goes to my event listener.  I then make the args easier for the consumer, and call the delegates that were passed in
            _materialHelper.SetCollisionCallback(_materials[material1], _materials[material2], null, ContactBegin, ContactProcess, null);
        }