예제 #1
0
 internal void RemoveCharacterSync(PhysxCharacter physxCharacter)
 {
     _charActors.Remove(physxCharacter);
 }
예제 #2
0
 /// <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);
 }
예제 #3
0
 internal void AddCharacterSync(PhysxCharacter newChar)
 {
     _charActors.Add(newChar);
 }
예제 #4
0
        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);
                        }
                    }
                }
            }
        }
예제 #5
0
 internal void ContactedCharacterDeleted(PhysxCharacter physxCharacter)
 {
     TerminateAvatarContacts(physxCharacter);
 }
예제 #6
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;
        }
예제 #7
0
 /// <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);
     }
 }
예제 #8
0
        /// <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);
            }
        }