예제 #1
0
        private void HandleTrackedCharacterContactChange(int change, PhysxPrim ourPrim, PhysX.Shape primShape, PhysxCharacter other)
        {
            HashSet<PhysX.Shape> collidingShapes;
            if (!_avatarTouchCounts.Value.TryGetValue(other, out collidingShapes))
            {
                if (change < 0)
                {
                    //we have no record of colliding with this object. therefore removing a 
                    //collision leaves no change to state
                    return;
                }

                collidingShapes = new HashSet<PhysX.Shape>();
                _avatarTouchCounts.Value[other] = collidingShapes;
            }

            if (change > 0 && !collidingShapes.Add(primShape))
            {
                //we're already colliding with this object. no change in state
                return;
            }
            else if (change < 0 && !collidingShapes.Remove(primShape))
            {
                //we weren't colliding with this object. no change in state
                return;
            }

            int newTotal = collidingShapes.Count;

            //m_log.DebugFormat("Char Contact Change: This: {0}, Other: {1}, Chg: {2}, Tot: {3}", this.SOPName, other.SOPName, change, collidingShapes.Count);

            if (newTotal == 0 && change < 0)
            {
                //we've lost all contact with this prim, notify of collision_end
                ourPrim.SendCollisionUpdate(new CollisionEventUpdate { OtherColliderLocalId = other.LocalID, Type = CollisionEventUpdateType.CharacterCollisionEnded });
                _avatarTouchCounts.Value.Remove(other);

                return;
            }

            if (newTotal == 1 && change > 0)
            {
                //we have begun colliding with a new object
                ourPrim.SendCollisionUpdate(new CollisionEventUpdate { OtherColliderLocalId = other.LocalID, Type = CollisionEventUpdateType.CharacterCollisionBegan });
            }

            return;
        }
예제 #2
0
        private void ProcessContactChangeLocally(int change, PhysxPrim ourPrim, PhysxPrim other)
        {
            int current;
            if (!_touchCounts.Value.TryGetValue(other, out current))
            {
                current = 0;
            }

            int newTotal = Math.Max(current + change, 0);

            if (newTotal == 0 && current == 0)
            {
                //no change
                return;
            }

            //m_log.DebugFormat("Contact Change: This: {0}, Other: {1}, Chg: {2}, Tot: {3}", this.SOPName, other.SOPName, change, newTotal);

            if (newTotal == 0 && change < 0)
            {
                //we've lost all contact with this prim, notify of collision_end
                //NOTE: We supply the other collider's UUID here just in case the prim has been deleted
                ourPrim.SendCollisionUpdate(new CollisionEventUpdate { OtherColliderLocalId = other._localId, OtherColliderUUID = other._uuid, Type = CollisionEventUpdateType.CollisionEnded });
                _touchCounts.Value.Remove(other);
                other.OnDeleted -= new Action<PhysxPrim>(other_OnDeleted);
                _primsBeingWatchedForDeletes.Value.Remove(other);

                return;
            }

            if (newTotal == 1 && change > 0)
            {
                //we have begun colliding with a new object
                ourPrim.SendCollisionUpdate(new CollisionEventUpdate { OtherColliderLocalId = other._localId, Type = CollisionEventUpdateType.CollisionBegan });
                other.OnDeleted += new Action<PhysxPrim>(other_OnDeleted);
                _primsBeingWatchedForDeletes.Value.Add(other);
            }

            _touchCounts.Value[other] = newTotal;

            return;
        }