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; }
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; }