public void PhysicsCollision(EventArgs e) { // single threaded here if (e == null) return; CollisionEventUpdate a = (CollisionEventUpdate) e; Dictionary<uint, ContactPoint> collissionswith = a.GetCollisionEvents(); List<uint> thisHitColliders = new List<uint>(); List<uint> startedColliders = new List<uint>(); ContactPoint startedCollider = new ContactPoint(); // calculate things that started colliding this time // and build up list of colliders this time foreach (uint localID in collissionswith.Keys) { thisHitColliders.Add(localID); if (!m_lastColliders.Contains(localID)) { startedCollider = collissionswith[localID]; startedColliders.Add(localID); } //MainConsole.Instance.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); } // calculate things that ended colliding List<uint> endedColliders = m_lastColliders.Where(localID => !thisHitColliders.Contains(localID)).ToList(); //add the items that started colliding this time to the last colliders list. m_lastColliders.AddRange(startedColliders); // remove things that ended colliding from the last colliders list foreach (uint localID in endedColliders) m_lastColliders.Remove(localID); if (m_parentGroup == null) return; if (m_parentGroup.IsDeleted) return; const string SoundGlassCollision = "6a45ba0b-5775-4ea8-8513-26008a17f873"; const string SoundMetalCollision = "9e5c1297-6eed-40c0-825a-d9bcd86e3193"; const string SoundStoneCollision = "9538f37c-456e-4047-81be-6435045608d4"; const string SoundFleshCollision = "dce5fdd4-afe4-4ea1-822f-dd52cac46b08"; const string SoundPlasticCollision = "0e24a717-b97e-4b77-9c94-b59a5a88b2da"; const string SoundRubberCollision = "153c8bf7-fb89-4d89-b263-47e58b1b4774"; const string SoundWoodCollision = "063c97d3-033a-4e9b-98d8-05c8074922cb"; // play the sound. if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) { SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, 0, 0); } else if (startedColliders.Count > 0) { switch (startedCollider.Type) { case ActorTypes.Agent: break; // Agents will play the sound so we don't case ActorTypes.Ground: SendSound(SoundWoodCollision, 1, true, 0, 0); break; //Always play the click or thump sound when hitting ground case ActorTypes.Prim: switch (Material) { case (int) OpenMetaverse.Material.Flesh: SendSound(SoundFleshCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Glass: SendSound(SoundGlassCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Metal: SendSound(SoundMetalCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Plastic: SendSound(SoundPlasticCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Rubber: SendSound(SoundRubberCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Stone: SendSound(SoundStoneCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Wood: SendSound(SoundWoodCollision, 1, true, 0, 0); break; } break; //Play based on material type in prim2prim collisions default: break; //Unclear of what this object is, no sounds } } if (CollisionSprite != UUID.Zero && CollisionSoundVolume > 0.0f) // The collision volume isn't a mistake, its an SL feature/bug { // TODO: make a sprite! } if (((AggregateScriptEvents & scriptEvents.collision) != 0) || ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || (CollisionSound != UUID.Zero) || PassCollisions != 2) { if ((AggregateScriptEvents & scriptEvents.collision_start) != 0 || (AggregateScriptEvents & scriptEvents.collision) != 0) { // do event notification if (startedColliders.Count > 0) { ColliderArgs StartCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in startedColliders) { if (localId != 0) { // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null) { if (av.LocalId == localId) { if ( m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } } } } } } } if (colliding.Count > 0) { StartCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; //Always send to the prim it is occuring to m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(this, StartCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart( this.ParentGroup.RootPart, StartCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.collision_start) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart( this.ParentGroup.RootPart, StartCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.collision) != 0) { if (m_lastColliders.Count > 0) { ColliderArgs CollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in m_lastColliders) { if (localId != 0) { if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } } } } } } if (colliding.Count > 0) { CollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptColliding(this, CollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptColliding(this.ParentGroup.RootPart, CollidingMessage); } else if (((this.ScriptEvents & scriptEvents.collision) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptColliding( this.ParentGroup.RootPart, CollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.collision_end) != 0) { if (endedColliders.Count > 0) { ColliderArgs EndCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in endedColliders) { if (localId != 0) { // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null) { if (av.LocalId == localId) { if ( m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } } } } } } } if (colliding.Count > 0) { EndCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(this, EndCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd( this.ParentGroup.RootPart, EndCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.collision_end) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd( this.ParentGroup.RootPart, EndCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0 || (AggregateScriptEvents & scriptEvents.land_collision) != 0) { if (startedColliders.Count > 0) { ColliderArgs LandStartCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = m_parentGroup.RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandStartCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(this, LandStartCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart( this.ParentGroup.RootPart, LandStartCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.land_collision_start) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart( this.ParentGroup.RootPart, LandStartCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.land_collision) != 0) { if (m_lastColliders.Count > 0) { ColliderArgs LandCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in m_lastColliders) { if (localId == 0) { //Hope that all is left is ground! DetectedObject detobj = new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = m_parentGroup.RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }; colliding.Add(detobj); } } if (colliding.Count > 0) { LandCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptLandColliding(this, LandCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptLandColliding( this.ParentGroup.RootPart, LandCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.land_collision) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptLandColliding( this.ParentGroup.RootPart, LandCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) { if (endedColliders.Count > 0) { ColliderArgs LandEndCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = m_parentGroup.RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandEndCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(this, LandEndCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd( this.ParentGroup.RootPart, LandEndCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.land_collision_end) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd( this.ParentGroup.RootPart, LandEndCollidingMessage); } } } } } } }
public void land_collision_start(ISceneChildEntity part, ColliderArgs col) { List<DetectParams> det = new List<DetectParams>(); foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams { Position = new LSL_Types.Vector3( detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z), Key = detobj.keyUUID })) { d.Populate(part.ParentEntity.Scene); d.LinkNum = part.LinkNum; det.Add(d); } if (det.Count != 0) { ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); //if (datas == null || datas.Length == 0) return; } string functionName = "land_collision_start"; object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)}; foreach (ScriptData ID in datas) { m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); } } }
public void TriggerScriptLandCollidingStart(ISceneChildEntity part, ColliderArgs colliders) { ScriptColliding handlerLandCollidingStart = OnScriptLandColliderStart; if (handlerLandCollidingStart != null) { foreach (ScriptColliding d in handlerLandCollidingStart.GetInvocationList()) { try { d(part, colliders); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[EVENT MANAGER]: Delegate for TriggerScriptLandCollidingStart failed - continuing. {0} {1}", e, e.StackTrace); } } } }
public void collision_end(ISceneChildEntity part, ColliderArgs col) { // Add to queue for all scripts in ObjectID object List<DetectParams> det = new List<DetectParams>(); foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID})) { d.Populate(part.ParentEntity.Scene); d.LinkNum = part.LinkNum; det.Add(d); } if (det.Count > 0) { ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); //if (datas == null || datas.Length == 0) return; } string functionName = "collision_end"; object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; foreach (ScriptData ID in datas) { m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); } } }
public void FireAttachmentCollisionEvents(EventArgs e) { CollisionEventUpdate a = (CollisionEventUpdate) e; Dictionary<uint, ContactPoint> collissionswith = a.GetCollisionEvents(); List<uint> thisHitColliders = new List<uint>(); List<uint> startedColliders = new List<uint>(); // calculate things that started colliding this time // and build up list of colliders this time foreach (uint localid in collissionswith.Keys) { thisHitColliders.Add(localid); if (!m_lastColliders.Contains(localid)) { startedColliders.Add(localid); } //MainConsole.Instance.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); } // calculate things that ended colliding List<uint> endedColliders = m_lastColliders.Where(localID => !thisHitColliders.Contains(localID)).ToList(); //add the items that started colliding this time to the last colliders list. foreach (uint localID in startedColliders) { m_lastColliders.Add(localID); } // remove things that ended colliding from the last colliders list foreach (uint localID in endedColliders) { m_lastColliders.Remove(localID); } if (IsDeleted) return; // play the sound. if (startedColliders.Count > 0 && RootPart.CollisionSound != UUID.Zero && RootPart.CollisionSoundVolume > 0.0f) { RootPart.SendSound(RootPart.CollisionSound.ToString(), RootPart.CollisionSoundVolume, true, 0, 0); } if (RootPart.CollisionSprite != UUID.Zero && RootPart.CollisionSoundVolume > 0.0f) // The collision volume isn't a mistake, its an SL feature/bug { // TODO: make a sprite! } if ((RootPart.ScriptEvents & scriptEvents.collision_start) != 0) { // do event notification if (startedColliders.Count > 0) { ColliderArgs StartCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in startedColliders) { if (localId != 0) { if (Scene == null) return; ISceneChildEntity obj = Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object } else { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = Scene.GetScenePresence(localId); if (av.LocalId == localId) { if (RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar } else { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } } } } } } if (colliding.Count > 0) { StartCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (Scene == null) return; Scene.EventManager.TriggerScriptCollidingStart(RootPart, StartCollidingMessage); } } } if ((RootPart.ScriptEvents & scriptEvents.collision) != 0) { if (m_lastColliders.Count > 0) { ColliderArgs CollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in m_lastColliders) { if (localId != 0) { if (Scene == null) return; ISceneChildEntity obj = Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object } else { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = Scene.GetScenePresence(localId); if (av != null && av.LocalId == localId) { if (RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar } else { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } } } } } } if (colliding.Count > 0) { CollidingMessage.Colliders = colliding; if (Scene == null) return; Scene.EventManager.TriggerScriptColliding(RootPart, CollidingMessage); } } } if ((RootPart.ScriptEvents & scriptEvents.collision_end) != 0) { if (endedColliders.Count > 0) { ColliderArgs EndCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in endedColliders) { if (localId != 0) { // always running this check because if the user deletes the object it would return a null reference. if (Scene == null) return; ISceneChildEntity obj = Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object } else { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = Scene.GetScenePresence(localId); if (av != null && av.LocalId == localId) { if (RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar } else { bool found = RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } } } } } } if (colliding.Count > 0) { EndCollidingMessage.Colliders = colliding; if (Scene == null) return; Scene.EventManager.TriggerScriptCollidingEnd(RootPart, EndCollidingMessage); } } } if ((RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) { if (startedColliders.Count > 0) { ColliderArgs LandStartCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandStartCollidingMessage.Colliders = colliding; if (Scene == null) return; Scene.EventManager.TriggerScriptLandCollidingStart(RootPart, LandStartCollidingMessage); } } } if ((RootPart.ScriptEvents & scriptEvents.land_collision) != 0) { if (m_lastColliders.Count > 0) { ColliderArgs LandCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandCollidingMessage.Colliders = colliding; if (Scene == null) return; Scene.EventManager.TriggerScriptLandColliding(RootPart, LandCollidingMessage); } } } if ((RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) { if (endedColliders.Count > 0) { ColliderArgs LandEndCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandEndCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (Scene == null) return; Scene.EventManager.TriggerScriptLandCollidingEnd(RootPart, LandEndCollidingMessage); } } } }