internal void RemoveCharacterSync(PhysxCharacter physxCharacter) { _charActors.Remove(physxCharacter); }
/// <summary> /// Called by another PhysxCharacter when it collides with this one /// </summary> /// <param name="physxCharacter"></param> /// <param name="shape"></param> private void HitByOtherCharacter(PhysxCharacter physxCharacter, PhysX.Shape shape) { _collisionsLastFrame.Add(shape); }
internal void AddCharacterSync(PhysxCharacter newChar) { _charActors.Add(newChar); }
private void TerminateAvatarContacts(PhysxCharacter physxCharacter) { if (_avatarTouchCounts.IsValueCreated) { HashSet<PhysX.Shape> contactedShapeSet; if (_avatarTouchCounts.Value.TryGetValue(physxCharacter, out contactedShapeSet)) { //we need to make a copy here, because ProcessCharacterContactChange() can //result in _avatarTouchCounts being modified while we're iterating PhysX.Shape[] contactedShapes = contactedShapeSet.ToArray(); foreach (var shape in contactedShapes) { PhysxPrim myPrim; if (_shapeToPrimIndex.TryGetValue(shape, out myPrim)) { myPrim.ProcessCharacterContactChange(-1, myPrim, shape, physxCharacter); } } } } }
internal void ContactedCharacterDeleted(PhysxCharacter physxCharacter) { TerminateAvatarContacts(physxCharacter); }
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; }
/// <summary> /// Called when a change has been posted for touches between one of our prims and an avatar. We must track /// these touches by shape because the collision detection is sometimes one sided in the case of an avatar /// touching a prim /// </summary> /// <param name="change"></param> /// <param name="other"></param> private void ProcessCharacterContactChange(int change, PhysxPrim ourPrim, PhysX.Shape primShape, PhysxCharacter other) { if (IsChild && _properties.WantsCollisionNotification) { HandleTrackedCharacterContactChange(change, ourPrim, primShape, other); } else if (IsChild && !_properties.WantsCollisionNotification) { _parentPrim.ProcessCharacterContactChange(change, ourPrim, primShape, other); } else if (HasActor && (_properties.WantsCollisionNotification || _properties.ChildrenWantCollisionNotification)) { HandleTrackedCharacterContactChange(change, ourPrim, primShape, other); } }
/// <summary> /// This message is sent by the character controller when a character "touches" us by its movement /// </summary> /// <param name="shape"></param> /// <param name="character"></param> /// <param name="collisionEventUpdateType"></param> internal void OnCharacterContactChangeSync(PhysX.Shape shape, PhysxCharacter character, CollisionEventUpdateType collisionEventUpdateType) { if (_collisionGroup == CollisionGroupFlag.PhysicalPhantom) { //no collision processing for phantoms return; } PhysxPrim myPrim; if (_shapeToPrimIndex.TryGetValue(shape, out myPrim)) { myPrim.ProcessCharacterContactChange(collisionEventUpdateType == CollisionEventUpdateType.CollisionBegan ? 1 : -1, myPrim, shape, character); } }