aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs672
1 files changed, 171 insertions, 501 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 82bba35..f9c5e28 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -271,7 +271,8 @@ namespace OpenSim.Region.Framework.Scenes
271 private string m_touchName = String.Empty; 271 private string m_touchName = String.Empty;
272 private UndoRedoState m_UndoRedo = null; 272 private UndoRedoState m_UndoRedo = null;
273 273
274 private bool m_passTouches; 274 private bool m_passTouches = false;
275 private bool m_passCollisions = false;
275 276
276 protected Vector3 m_acceleration; 277 protected Vector3 m_acceleration;
277 protected Vector3 m_angularVelocity; 278 protected Vector3 m_angularVelocity;
@@ -571,6 +572,7 @@ namespace OpenSim.Region.Framework.Scenes
571 } 572 }
572 } 573 }
573 574
575 [XmlIgnore]
574 public bool PassTouches 576 public bool PassTouches
575 { 577 {
576 get { return m_passTouches; } 578 get { return m_passTouches; }
@@ -583,6 +585,18 @@ namespace OpenSim.Region.Framework.Scenes
583 } 585 }
584 } 586 }
585 587
588 public bool PassCollisions
589 {
590 get { return m_passCollisions; }
591 set
592 {
593 m_passCollisions = value;
594
595 if (ParentGroup != null)
596 ParentGroup.HasGroupChanged = true;
597 }
598 }
599
586 public bool IsSelected 600 public bool IsSelected
587 { 601 {
588 get { return m_isSelected; } 602 get { return m_isSelected; }
@@ -2436,546 +2450,202 @@ namespace OpenSim.Region.Framework.Scenes
2436 { 2450 {
2437 } 2451 }
2438 2452
2439 public void PhysicsCollision(EventArgs e) 2453 private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName)
2440 { 2454 {
2441// m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID); 2455 if(dest.CollisionFilter.Count == 0)
2442 2456 return false;
2443 // single threaded here
2444
2445 CollisionEventUpdate a = (CollisionEventUpdate)e;
2446 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2447 List<uint> thisHitColliders = new List<uint>();
2448 List<uint> endedColliders = new List<uint>();
2449 List<uint> startedColliders = new List<uint>();
2450
2451 // calculate things that started colliding this time
2452 // and build up list of colliders this time
2453 foreach (uint localid in collissionswith.Keys)
2454 {
2455 thisHitColliders.Add(localid);
2456 if (!m_lastColliders.Contains(localid))
2457 {
2458 startedColliders.Add(localid);
2459 }
2460 //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
2461 }
2462
2463 // calculate things that ended colliding
2464 foreach (uint localID in m_lastColliders)
2465 {
2466 if (!thisHitColliders.Contains(localID))
2467 {
2468 endedColliders.Add(localID);
2469 }
2470 }
2471 2457
2472 //add the items that started colliding this time to the last colliders list. 2458 if (dest.CollisionFilter.ContainsValue(objectID.ToString()) ||
2473 foreach (uint localID in startedColliders) 2459 dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) ||
2460 dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName))
2474 { 2461 {
2475 m_lastColliders.Add(localID); 2462 if (dest.CollisionFilter.ContainsKey(1))
2476 } 2463 return false;
2477 // remove things that ended colliding from the last colliders list 2464 return true;
2478 foreach (uint localID in endedColliders)
2479 {
2480 m_lastColliders.Remove(localID);
2481 } 2465 }
2482 2466
2483 if (ParentGroup.IsDeleted) 2467 if (dest.CollisionFilter.ContainsKey(1))
2484 return; 2468 return true;
2485 2469
2486 // play the sound. 2470 return false;
2487 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2471 }
2488 {
2489 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2490 }
2491 2472
2492 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) 2473 private DetectedObject CreateDetObject(SceneObjectPart obj)
2493 { 2474 {
2494 // do event notification 2475 DetectedObject detobj = new DetectedObject();
2495 if (startedColliders.Count > 0) 2476 detobj.keyUUID = obj.UUID;
2496 { 2477 detobj.nameStr = obj.Name;
2497 ColliderArgs StartCollidingMessage = new ColliderArgs(); 2478 detobj.ownerUUID = obj.OwnerID;
2498 List<DetectedObject> colliding = new List<DetectedObject>(); 2479 detobj.posVector = obj.AbsolutePosition;
2499 foreach (uint localId in startedColliders) 2480 detobj.rotQuat = obj.GetWorldRotation();
2500 { 2481 detobj.velVector = obj.Velocity;
2501 if (localId == 0) 2482 detobj.colliderType = 0;
2502 continue; 2483 detobj.groupUUID = obj.GroupID;
2503 2484
2504 if (ParentGroup.Scene == null) 2485 return detobj;
2505 return; 2486 }
2506 2487
2507 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2488 private DetectedObject CreateDetObject(ScenePresence av)
2508 string data = ""; 2489 {
2509 if (obj != null) 2490 DetectedObject detobj = new DetectedObject();
2510 { 2491 detobj.keyUUID = av.UUID;
2511 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) 2492 detobj.nameStr = av.ControllingClient.Name;
2512 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2493 detobj.ownerUUID = av.UUID;
2513 { 2494 detobj.posVector = av.AbsolutePosition;
2514 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2495 detobj.rotQuat = av.Rotation;
2515 //If it is 1, it is to accept ONLY collisions from this object 2496 detobj.velVector = av.Velocity;
2516 if (found) 2497 detobj.colliderType = 0;
2517 { 2498 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2518 DetectedObject detobj = new DetectedObject();
2519 detobj.keyUUID = obj.UUID;
2520 detobj.nameStr = obj.Name;
2521 detobj.ownerUUID = obj.OwnerID;
2522 detobj.posVector = obj.AbsolutePosition;
2523 detobj.rotQuat = obj.GetWorldRotation();
2524 detobj.velVector = obj.Velocity;
2525 detobj.colliderType = 0;
2526 detobj.groupUUID = obj.GroupID;
2527 colliding.Add(detobj);
2528 }
2529 //If it is 0, it is to not accept collisions from this object
2530 else
2531 {
2532 }
2533 }
2534 else
2535 {
2536 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2537 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2538 if (!found)
2539 {
2540 DetectedObject detobj = new DetectedObject();
2541 detobj.keyUUID = obj.UUID;
2542 detobj.nameStr = obj.Name;
2543 detobj.ownerUUID = obj.OwnerID;
2544 detobj.posVector = obj.AbsolutePosition;
2545 detobj.rotQuat = obj.GetWorldRotation();
2546 detobj.velVector = obj.Velocity;
2547 detobj.colliderType = 0;
2548 detobj.groupUUID = obj.GroupID;
2549 colliding.Add(detobj);
2550 }
2551 }
2552 }
2553 else
2554 {
2555 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2556 {
2557 if (av.LocalId == localId)
2558 {
2559 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2560 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2561 {
2562 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2563 //If it is 1, it is to accept ONLY collisions from this avatar
2564 if (found)
2565 {
2566 DetectedObject detobj = new DetectedObject();
2567 detobj.keyUUID = av.UUID;
2568 detobj.nameStr = av.ControllingClient.Name;
2569 detobj.ownerUUID = av.UUID;
2570 detobj.posVector = av.AbsolutePosition;
2571 detobj.rotQuat = av.Rotation;
2572 detobj.velVector = av.Velocity;
2573 detobj.colliderType = 0;
2574 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2575 colliding.Add(detobj);
2576 }
2577 //If it is 0, it is to not accept collisions from this avatar
2578 else
2579 {
2580 }
2581 }
2582 else
2583 {
2584 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2585 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2586 if (!found)
2587 {
2588 DetectedObject detobj = new DetectedObject();
2589 detobj.keyUUID = av.UUID;
2590 detobj.nameStr = av.ControllingClient.Name;
2591 detobj.ownerUUID = av.UUID;
2592 detobj.posVector = av.AbsolutePosition;
2593 detobj.rotQuat = av.Rotation;
2594 detobj.velVector = av.Velocity;
2595 detobj.colliderType = 0;
2596 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2597 colliding.Add(detobj);
2598 }
2599 }
2600 2499
2601 } 2500 return detobj;
2602 }); 2501 }
2603 }
2604 }
2605 2502
2606 if (colliding.Count > 0) 2503 private DetectedObject CreateDetObjectForGround()
2607 { 2504 {
2608 StartCollidingMessage.Colliders = colliding; 2505 DetectedObject detobj = new DetectedObject();
2506 detobj.keyUUID = UUID.Zero;
2507 detobj.nameStr = "";
2508 detobj.ownerUUID = UUID.Zero;
2509 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2510 detobj.rotQuat = Quaternion.Identity;
2511 detobj.velVector = Vector3.Zero;
2512 detobj.colliderType = 0;
2513 detobj.groupUUID = UUID.Zero;
2609 2514
2610 if (ParentGroup.Scene == null) 2515 return detobj;
2611 return; 2516 }
2612 2517
2613// if (m_parentGroup.PassCollision == true) 2518 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
2614// { 2519 {
2615// //TODO: Add pass to root prim! 2520 ColliderArgs colliderArgs = new ColliderArgs();
2616// } 2521 List<DetectedObject> colliding = new List<DetectedObject>();
2522 foreach (uint localId in colliders)
2523 {
2524 if (localId == 0)
2525 continue;
2617 2526
2618 ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); 2527 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2619 } 2528 if (obj != null)
2529 {
2530 if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name))
2531 colliding.Add(CreateDetObject(obj));
2620 } 2532 }
2621 } 2533 else
2622
2623 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
2624 {
2625 if (m_lastColliders.Count > 0)
2626 { 2534 {
2627 ColliderArgs CollidingMessage = new ColliderArgs(); 2535 ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
2628 List<DetectedObject> colliding = new List<DetectedObject>(); 2536 if (av != null && (!av.IsChildAgent))
2629 foreach (uint localId in m_lastColliders)
2630 { 2537 {
2631 // always running this check because if the user deletes the object it would return a null reference. 2538 if (!dest.CollisionFilteredOut(this, av.UUID, av.Name))
2632 if (localId == 0) 2539 colliding.Add(CreateDetObject(av));
2633 continue;
2634
2635 if (ParentGroup.Scene == null)
2636 return;
2637
2638 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2639 string data = "";
2640 if (obj != null)
2641 {
2642 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2643 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2644 {
2645 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2646 //If it is 1, it is to accept ONLY collisions from this object
2647 if (found)
2648 {
2649 DetectedObject detobj = new DetectedObject();
2650 detobj.keyUUID = obj.UUID;
2651 detobj.nameStr = obj.Name;
2652 detobj.ownerUUID = obj.OwnerID;
2653 detobj.posVector = obj.AbsolutePosition;
2654 detobj.rotQuat = obj.GetWorldRotation();
2655 detobj.velVector = obj.Velocity;
2656 detobj.colliderType = 0;
2657 detobj.groupUUID = obj.GroupID;
2658 colliding.Add(detobj);
2659 }
2660 //If it is 0, it is to not accept collisions from this object
2661 else
2662 {
2663 }
2664 }
2665 else
2666 {
2667 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2668 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2669 if (!found)
2670 {
2671 DetectedObject detobj = new DetectedObject();
2672 detobj.keyUUID = obj.UUID;
2673 detobj.nameStr = obj.Name;
2674 detobj.ownerUUID = obj.OwnerID;
2675 detobj.posVector = obj.AbsolutePosition;
2676 detobj.rotQuat = obj.GetWorldRotation();
2677 detobj.velVector = obj.Velocity;
2678 detobj.colliderType = 0;
2679 detobj.groupUUID = obj.GroupID;
2680 colliding.Add(detobj);
2681 }
2682 }
2683 }
2684 else
2685 {
2686 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2687 {
2688 if (av.LocalId == localId)
2689 {
2690 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2691 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2692 {
2693 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2694 //If it is 1, it is to accept ONLY collisions from this avatar
2695 if (found)
2696 {
2697 DetectedObject detobj = new DetectedObject();
2698 detobj.keyUUID = av.UUID;
2699 detobj.nameStr = av.ControllingClient.Name;
2700 detobj.ownerUUID = av.UUID;
2701 detobj.posVector = av.AbsolutePosition;
2702 detobj.rotQuat = av.Rotation;
2703 detobj.velVector = av.Velocity;
2704 detobj.colliderType = 0;
2705 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2706 colliding.Add(detobj);
2707 }
2708 //If it is 0, it is to not accept collisions from this avatar
2709 else
2710 {
2711 }
2712 }
2713 else
2714 {
2715 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2716 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2717 if (!found)
2718 {
2719 DetectedObject detobj = new DetectedObject();
2720 detobj.keyUUID = av.UUID;
2721 detobj.nameStr = av.ControllingClient.Name;
2722 detobj.ownerUUID = av.UUID;
2723 detobj.posVector = av.AbsolutePosition;
2724 detobj.rotQuat = av.Rotation;
2725 detobj.velVector = av.Velocity;
2726 detobj.colliderType = 0;
2727 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2728 colliding.Add(detobj);
2729 }
2730 }
2731
2732 }
2733 });
2734 }
2735 }
2736 if (colliding.Count > 0)
2737 {
2738 CollidingMessage.Colliders = colliding;
2739
2740 if (ParentGroup.Scene == null)
2741 return;
2742
2743 ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage);
2744 } 2540 }
2745 } 2541 }
2746 } 2542 }
2747
2748 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
2749 {
2750 if (endedColliders.Count > 0)
2751 {
2752 ColliderArgs EndCollidingMessage = new ColliderArgs();
2753 List<DetectedObject> colliding = new List<DetectedObject>();
2754 foreach (uint localId in endedColliders)
2755 {
2756 if (localId == 0)
2757 continue;
2758 2543
2759 if (ParentGroup.Scene == null) 2544 colliderArgs.Colliders = colliding;
2760 return;
2761 2545
2762 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2546 return colliderArgs;
2763 string data = ""; 2547 }
2764 if (obj != null)
2765 {
2766 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2767 {
2768 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2769 //If it is 1, it is to accept ONLY collisions from this object
2770 if (found)
2771 {
2772 DetectedObject detobj = new DetectedObject();
2773 detobj.keyUUID = obj.UUID;
2774 detobj.nameStr = obj.Name;
2775 detobj.ownerUUID = obj.OwnerID;
2776 detobj.posVector = obj.AbsolutePosition;
2777 detobj.rotQuat = obj.GetWorldRotation();
2778 detobj.velVector = obj.Velocity;
2779 detobj.colliderType = 0;
2780 detobj.groupUUID = obj.GroupID;
2781 colliding.Add(detobj);
2782 }
2783 //If it is 0, it is to not accept collisions from this object
2784 else
2785 {
2786 }
2787 }
2788 else
2789 {
2790 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2791 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2792 if (!found)
2793 {
2794 DetectedObject detobj = new DetectedObject();
2795 detobj.keyUUID = obj.UUID;
2796 detobj.nameStr = obj.Name;
2797 detobj.ownerUUID = obj.OwnerID;
2798 detobj.posVector = obj.AbsolutePosition;
2799 detobj.rotQuat = obj.GetWorldRotation();
2800 detobj.velVector = obj.Velocity;
2801 detobj.colliderType = 0;
2802 detobj.groupUUID = obj.GroupID;
2803 colliding.Add(detobj);
2804 }
2805 }
2806 }
2807 else
2808 {
2809 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2810 {
2811 if (av.LocalId == localId)
2812 {
2813 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2814 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2815 {
2816 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2817 //If it is 1, it is to accept ONLY collisions from this avatar
2818 if (found)
2819 {
2820 DetectedObject detobj = new DetectedObject();
2821 detobj.keyUUID = av.UUID;
2822 detobj.nameStr = av.ControllingClient.Name;
2823 detobj.ownerUUID = av.UUID;
2824 detobj.posVector = av.AbsolutePosition;
2825 detobj.rotQuat = av.Rotation;
2826 detobj.velVector = av.Velocity;
2827 detobj.colliderType = 0;
2828 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2829 colliding.Add(detobj);
2830 }
2831 //If it is 0, it is to not accept collisions from this avatar
2832 else
2833 {
2834 }
2835 }
2836 else
2837 {
2838 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2839 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2840 if (!found)
2841 {
2842 DetectedObject detobj = new DetectedObject();
2843 detobj.keyUUID = av.UUID;
2844 detobj.nameStr = av.ControllingClient.Name;
2845 detobj.ownerUUID = av.UUID;
2846 detobj.posVector = av.AbsolutePosition;
2847 detobj.rotQuat = av.Rotation;
2848 detobj.velVector = av.Velocity;
2849 detobj.colliderType = 0;
2850 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2851 colliding.Add(detobj);
2852 }
2853 }
2854 2548
2855 } 2549 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
2856 }); 2550
2857 } 2551 private void SendCollisionEvent(scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
2858 } 2552 {
2859 2553 bool sendToRoot = false;
2860 if (colliding.Count > 0) 2554 ColliderArgs CollidingMessage;
2861 {
2862 EndCollidingMessage.Colliders = colliding;
2863
2864 if (ParentGroup.Scene == null)
2865 return;
2866
2867 ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage);
2868 }
2869 }
2870 }
2871 2555
2872 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2556 if (colliders.Count > 0)
2873 { 2557 {
2874 if (startedColliders.Count > 0) 2558 if ((ScriptEvents & ev) != 0)
2875 { 2559 {
2876 ColliderArgs LandStartCollidingMessage = new ColliderArgs(); 2560 CollidingMessage = CreateColliderArgs(this, colliders);
2877 List<DetectedObject> colliding = new List<DetectedObject>();
2878 foreach (uint localId in startedColliders)
2879 {
2880 if (localId == 0)
2881 {
2882 //Hope that all is left is ground!
2883 DetectedObject detobj = new DetectedObject();
2884 detobj.keyUUID = UUID.Zero;
2885 detobj.nameStr = "";
2886 detobj.ownerUUID = UUID.Zero;
2887 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2888 detobj.rotQuat = Quaternion.Identity;
2889 detobj.velVector = Vector3.Zero;
2890 detobj.colliderType = 0;
2891 detobj.groupUUID = UUID.Zero;
2892 colliding.Add(detobj);
2893 }
2894 }
2895
2896 if (colliding.Count > 0)
2897 {
2898 LandStartCollidingMessage.Colliders = colliding;
2899 2561
2900 if (ParentGroup.Scene == null) 2562 if (CollidingMessage.Colliders.Count > 0)
2901 return; 2563 notify(LocalId, CollidingMessage);
2902 2564
2903 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage); 2565 if (PassCollisions)
2904 } 2566 sendToRoot = true;
2567 }
2568 else
2569 {
2570 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0)
2571 sendToRoot = true;
2572 }
2573 if (sendToRoot && ParentGroup.RootPart != this)
2574 {
2575 CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders);
2576 if (CollidingMessage.Colliders.Count > 0)
2577 notify(ParentGroup.RootPart.LocalId, CollidingMessage);
2905 } 2578 }
2906 } 2579 }
2580 }
2907 2581
2908 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2582 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2583 {
2584 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
2909 { 2585 {
2910 if (m_lastColliders.Count > 0) 2586 ColliderArgs LandCollidingMessage = new ColliderArgs();
2911 { 2587 List<DetectedObject> colliding = new List<DetectedObject>();
2912 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2588
2913 List<DetectedObject> colliding = new List<DetectedObject>(); 2589 colliding.Add(CreateDetObjectForGround());
2914 foreach (uint localId in startedColliders) 2590 LandCollidingMessage.Colliders = colliding;
2915 {
2916 if (localId == 0)
2917 {
2918 //Hope that all is left is ground!
2919 DetectedObject detobj = new DetectedObject();
2920 detobj.keyUUID = UUID.Zero;
2921 detobj.nameStr = "";
2922 detobj.ownerUUID = UUID.Zero;
2923 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2924 detobj.rotQuat = Quaternion.Identity;
2925 detobj.velVector = Vector3.Zero;
2926 detobj.colliderType = 0;
2927 detobj.groupUUID = UUID.Zero;
2928 colliding.Add(detobj);
2929 }
2930 }
2931 2591
2932 if (colliding.Count > 0) 2592 notify(LocalId, LandCollidingMessage);
2933 { 2593 }
2934 LandCollidingMessage.Colliders = colliding; 2594 }
2935 2595
2936 if (ParentGroup.Scene == null) 2596 public void PhysicsCollision(EventArgs e)
2937 return; 2597 {
2598 if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
2599 return;
2938 2600
2939 ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage); 2601 // single threaded here
2940 } 2602 CollisionEventUpdate a = (CollisionEventUpdate)e;
2941 } 2603 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2604 List<uint> thisHitColliders = new List<uint>();
2605 List<uint> endedColliders = new List<uint>();
2606 List<uint> startedColliders = new List<uint>();
2607
2608 // calculate things that started colliding this time
2609 // and build up list of colliders this time
2610 foreach (uint localid in collissionswith.Keys)
2611 {
2612 thisHitColliders.Add(localid);
2613 if (!m_lastColliders.Contains(localid))
2614 startedColliders.Add(localid);
2942 } 2615 }
2943 2616
2944 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2617 // calculate things that ended colliding
2618 foreach (uint localID in m_lastColliders)
2945 { 2619 {
2946 if (endedColliders.Count > 0) 2620 if (!thisHitColliders.Contains(localID))
2947 { 2621 endedColliders.Add(localID);
2948 ColliderArgs LandEndCollidingMessage = new ColliderArgs(); 2622 }
2949 List<DetectedObject> colliding = new List<DetectedObject>();
2950 foreach (uint localId in startedColliders)
2951 {
2952 if (localId == 0)
2953 {
2954 //Hope that all is left is ground!
2955 DetectedObject detobj = new DetectedObject();
2956 detobj.keyUUID = UUID.Zero;
2957 detobj.nameStr = "";
2958 detobj.ownerUUID = UUID.Zero;
2959 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2960 detobj.rotQuat = Quaternion.Identity;
2961 detobj.velVector = Vector3.Zero;
2962 detobj.colliderType = 0;
2963 detobj.groupUUID = UUID.Zero;
2964 colliding.Add(detobj);
2965 }
2966 }
2967 2623
2968 if (colliding.Count > 0) 2624 //add the items that started colliding this time to the last colliders list.
2969 { 2625 foreach (uint localID in startedColliders)
2970 LandEndCollidingMessage.Colliders = colliding; 2626 m_lastColliders.Add(localID);
2971 2627
2972 if (ParentGroup.Scene == null) 2628 // remove things that ended colliding from the last colliders list
2973 return; 2629 foreach (uint localID in endedColliders)
2630 m_lastColliders.Remove(localID);
2974 2631
2975 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage); 2632 // play the sound.
2976 } 2633 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
2977 } 2634 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2635
2636 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2637 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2638 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2639
2640 if (startedColliders.Contains(0))
2641 {
2642 if (m_lastColliders.Contains(0))
2643 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2644 else
2645 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2978 } 2646 }
2647 if (endedColliders.Contains(0))
2648 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2979 } 2649 }
2980 2650
2981 public void PhysicsOutOfBounds(Vector3 pos) 2651 public void PhysicsOutOfBounds(Vector3 pos)
@@ -4728,7 +4398,7 @@ namespace OpenSim.Region.Framework.Scenes
4728// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4398// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4729// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4399// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4730// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4400// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4731 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero) 4401 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4732// (CollisionSound != UUID.Zero) 4402// (CollisionSound != UUID.Zero)
4733 ) 4403 )
4734 { 4404 {
@@ -5080,7 +4750,7 @@ namespace OpenSim.Region.Framework.Scenes
5080// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4750// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5081// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4751// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5082// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4752// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5083 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero) 4753 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5084 ) 4754 )
5085 { 4755 {
5086 // subscribe to physics updates. 4756 // subscribe to physics updates.