aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs672
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs7
4 files changed, 184 insertions, 514 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0089c7d..29465c0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -2338,7 +2338,10 @@ namespace OpenSim.Region.Framework.Scenes
2338 } 2338 }
2339 else 2339 else
2340 { 2340 {
2341 if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)) 2341 if (!Permissions.IsGod(remoteClient.AgentId) && sog.OwnerID != remoteClient.AgentId)
2342 continue;
2343
2344 if (!Permissions.CanTransferObject(sog.UUID, groupID))
2342 continue; 2345 continue;
2343 2346
2344 if (sog.GroupID != groupID) 2347 if (sog.GroupID != groupID)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index f9c2193..a6551c1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -755,17 +755,6 @@ namespace OpenSim.Region.Framework.Scenes
755 get { return true; } 755 get { return true; }
756 } 756 }
757 757
758 private bool m_passCollision;
759 public bool PassCollision
760 {
761 get { return m_passCollision; }
762 set
763 {
764 m_passCollision = value;
765 HasGroupChanged = true;
766 }
767 }
768
769 public bool IsSelected 758 public bool IsSelected
770 { 759 {
771 get { return m_isSelected; } 760 get { return m_isSelected; }
@@ -3752,7 +3741,8 @@ namespace OpenSim.Region.Framework.Scenes
3752 } 3741 }
3753 if ((change & ObjectChangeType.Position) != 0) 3742 if ((change & ObjectChangeType.Position) != 0)
3754 { 3743 {
3755 UpdateGroupPosition(data.position); 3744 if (m_scene.Permissions.CanObjectEntry(group.UUID, false, data.position))
3745 UpdateGroupPosition(data.position);
3756 updateType = updatetype.groupterse; 3746 updateType = updatetype.groupterse;
3757 } 3747 }
3758 else 3748 else
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b0bc188..f7edd31 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; }
@@ -2433,546 +2447,202 @@ namespace OpenSim.Region.Framework.Scenes
2433 { 2447 {
2434 } 2448 }
2435 2449
2436 public void PhysicsCollision(EventArgs e) 2450 private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName)
2437 { 2451 {
2438// m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID); 2452 if(dest.CollisionFilter.Count == 0)
2439 2453 return false;
2440 // single threaded here
2441
2442 CollisionEventUpdate a = (CollisionEventUpdate)e;
2443 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2444 List<uint> thisHitColliders = new List<uint>();
2445 List<uint> endedColliders = new List<uint>();
2446 List<uint> startedColliders = new List<uint>();
2447
2448 // calculate things that started colliding this time
2449 // and build up list of colliders this time
2450 foreach (uint localid in collissionswith.Keys)
2451 {
2452 thisHitColliders.Add(localid);
2453 if (!m_lastColliders.Contains(localid))
2454 {
2455 startedColliders.Add(localid);
2456 }
2457 //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
2458 }
2459
2460 // calculate things that ended colliding
2461 foreach (uint localID in m_lastColliders)
2462 {
2463 if (!thisHitColliders.Contains(localID))
2464 {
2465 endedColliders.Add(localID);
2466 }
2467 }
2468 2454
2469 //add the items that started colliding this time to the last colliders list. 2455 if (dest.CollisionFilter.ContainsValue(objectID.ToString()) ||
2470 foreach (uint localID in startedColliders) 2456 dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) ||
2457 dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName))
2471 { 2458 {
2472 m_lastColliders.Add(localID); 2459 if (dest.CollisionFilter.ContainsKey(1))
2473 } 2460 return false;
2474 // remove things that ended colliding from the last colliders list 2461 return true;
2475 foreach (uint localID in endedColliders)
2476 {
2477 m_lastColliders.Remove(localID);
2478 } 2462 }
2479 2463
2480 if (ParentGroup.IsDeleted) 2464 if (dest.CollisionFilter.ContainsKey(1))
2481 return; 2465 return true;
2482 2466
2483 // play the sound. 2467 return false;
2484 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2468 }
2485 {
2486 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2487 }
2488 2469
2489 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) 2470 private DetectedObject CreateDetObject(SceneObjectPart obj)
2490 { 2471 {
2491 // do event notification 2472 DetectedObject detobj = new DetectedObject();
2492 if (startedColliders.Count > 0) 2473 detobj.keyUUID = obj.UUID;
2493 { 2474 detobj.nameStr = obj.Name;
2494 ColliderArgs StartCollidingMessage = new ColliderArgs(); 2475 detobj.ownerUUID = obj.OwnerID;
2495 List<DetectedObject> colliding = new List<DetectedObject>(); 2476 detobj.posVector = obj.AbsolutePosition;
2496 foreach (uint localId in startedColliders) 2477 detobj.rotQuat = obj.GetWorldRotation();
2497 { 2478 detobj.velVector = obj.Velocity;
2498 if (localId == 0) 2479 detobj.colliderType = 0;
2499 continue; 2480 detobj.groupUUID = obj.GroupID;
2500 2481
2501 if (ParentGroup.Scene == null) 2482 return detobj;
2502 return; 2483 }
2503 2484
2504 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2485 private DetectedObject CreateDetObject(ScenePresence av)
2505 string data = ""; 2486 {
2506 if (obj != null) 2487 DetectedObject detobj = new DetectedObject();
2507 { 2488 detobj.keyUUID = av.UUID;
2508 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) 2489 detobj.nameStr = av.ControllingClient.Name;
2509 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2490 detobj.ownerUUID = av.UUID;
2510 { 2491 detobj.posVector = av.AbsolutePosition;
2511 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2492 detobj.rotQuat = av.Rotation;
2512 //If it is 1, it is to accept ONLY collisions from this object 2493 detobj.velVector = av.Velocity;
2513 if (found) 2494 detobj.colliderType = 0;
2514 { 2495 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2515 DetectedObject detobj = new DetectedObject();
2516 detobj.keyUUID = obj.UUID;
2517 detobj.nameStr = obj.Name;
2518 detobj.ownerUUID = obj.OwnerID;
2519 detobj.posVector = obj.AbsolutePosition;
2520 detobj.rotQuat = obj.GetWorldRotation();
2521 detobj.velVector = obj.Velocity;
2522 detobj.colliderType = 0;
2523 detobj.groupUUID = obj.GroupID;
2524 colliding.Add(detobj);
2525 }
2526 //If it is 0, it is to not accept collisions from this object
2527 else
2528 {
2529 }
2530 }
2531 else
2532 {
2533 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2534 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2535 if (!found)
2536 {
2537 DetectedObject detobj = new DetectedObject();
2538 detobj.keyUUID = obj.UUID;
2539 detobj.nameStr = obj.Name;
2540 detobj.ownerUUID = obj.OwnerID;
2541 detobj.posVector = obj.AbsolutePosition;
2542 detobj.rotQuat = obj.GetWorldRotation();
2543 detobj.velVector = obj.Velocity;
2544 detobj.colliderType = 0;
2545 detobj.groupUUID = obj.GroupID;
2546 colliding.Add(detobj);
2547 }
2548 }
2549 }
2550 else
2551 {
2552 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2553 {
2554 if (av.LocalId == localId)
2555 {
2556 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2557 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2558 {
2559 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2560 //If it is 1, it is to accept ONLY collisions from this avatar
2561 if (found)
2562 {
2563 DetectedObject detobj = new DetectedObject();
2564 detobj.keyUUID = av.UUID;
2565 detobj.nameStr = av.ControllingClient.Name;
2566 detobj.ownerUUID = av.UUID;
2567 detobj.posVector = av.AbsolutePosition;
2568 detobj.rotQuat = av.Rotation;
2569 detobj.velVector = av.Velocity;
2570 detobj.colliderType = 0;
2571 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2572 colliding.Add(detobj);
2573 }
2574 //If it is 0, it is to not accept collisions from this avatar
2575 else
2576 {
2577 }
2578 }
2579 else
2580 {
2581 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2582 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2583 if (!found)
2584 {
2585 DetectedObject detobj = new DetectedObject();
2586 detobj.keyUUID = av.UUID;
2587 detobj.nameStr = av.ControllingClient.Name;
2588 detobj.ownerUUID = av.UUID;
2589 detobj.posVector = av.AbsolutePosition;
2590 detobj.rotQuat = av.Rotation;
2591 detobj.velVector = av.Velocity;
2592 detobj.colliderType = 0;
2593 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2594 colliding.Add(detobj);
2595 }
2596 }
2597 2496
2598 } 2497 return detobj;
2599 }); 2498 }
2600 }
2601 }
2602 2499
2603 if (colliding.Count > 0) 2500 private DetectedObject CreateDetObjectForGround()
2604 { 2501 {
2605 StartCollidingMessage.Colliders = colliding; 2502 DetectedObject detobj = new DetectedObject();
2503 detobj.keyUUID = UUID.Zero;
2504 detobj.nameStr = "";
2505 detobj.ownerUUID = UUID.Zero;
2506 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2507 detobj.rotQuat = Quaternion.Identity;
2508 detobj.velVector = Vector3.Zero;
2509 detobj.colliderType = 0;
2510 detobj.groupUUID = UUID.Zero;
2606 2511
2607 if (ParentGroup.Scene == null) 2512 return detobj;
2608 return; 2513 }
2609 2514
2610// if (m_parentGroup.PassCollision == true) 2515 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
2611// { 2516 {
2612// //TODO: Add pass to root prim! 2517 ColliderArgs colliderArgs = new ColliderArgs();
2613// } 2518 List<DetectedObject> colliding = new List<DetectedObject>();
2519 foreach (uint localId in colliders)
2520 {
2521 if (localId == 0)
2522 continue;
2614 2523
2615 ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); 2524 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2616 } 2525 if (obj != null)
2526 {
2527 if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name))
2528 colliding.Add(CreateDetObject(obj));
2617 } 2529 }
2618 } 2530 else
2619
2620 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
2621 {
2622 if (m_lastColliders.Count > 0)
2623 { 2531 {
2624 ColliderArgs CollidingMessage = new ColliderArgs(); 2532 ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
2625 List<DetectedObject> colliding = new List<DetectedObject>(); 2533 if (av != null && (!av.IsChildAgent))
2626 foreach (uint localId in m_lastColliders)
2627 { 2534 {
2628 // always running this check because if the user deletes the object it would return a null reference. 2535 if (!dest.CollisionFilteredOut(this, av.UUID, av.Name))
2629 if (localId == 0) 2536 colliding.Add(CreateDetObject(av));
2630 continue;
2631
2632 if (ParentGroup.Scene == null)
2633 return;
2634
2635 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2636 string data = "";
2637 if (obj != null)
2638 {
2639 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2640 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2641 {
2642 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2643 //If it is 1, it is to accept ONLY collisions from this object
2644 if (found)
2645 {
2646 DetectedObject detobj = new DetectedObject();
2647 detobj.keyUUID = obj.UUID;
2648 detobj.nameStr = obj.Name;
2649 detobj.ownerUUID = obj.OwnerID;
2650 detobj.posVector = obj.AbsolutePosition;
2651 detobj.rotQuat = obj.GetWorldRotation();
2652 detobj.velVector = obj.Velocity;
2653 detobj.colliderType = 0;
2654 detobj.groupUUID = obj.GroupID;
2655 colliding.Add(detobj);
2656 }
2657 //If it is 0, it is to not accept collisions from this object
2658 else
2659 {
2660 }
2661 }
2662 else
2663 {
2664 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2665 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2666 if (!found)
2667 {
2668 DetectedObject detobj = new DetectedObject();
2669 detobj.keyUUID = obj.UUID;
2670 detobj.nameStr = obj.Name;
2671 detobj.ownerUUID = obj.OwnerID;
2672 detobj.posVector = obj.AbsolutePosition;
2673 detobj.rotQuat = obj.GetWorldRotation();
2674 detobj.velVector = obj.Velocity;
2675 detobj.colliderType = 0;
2676 detobj.groupUUID = obj.GroupID;
2677 colliding.Add(detobj);
2678 }
2679 }
2680 }
2681 else
2682 {
2683 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2684 {
2685 if (av.LocalId == localId)
2686 {
2687 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2688 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2689 {
2690 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2691 //If it is 1, it is to accept ONLY collisions from this avatar
2692 if (found)
2693 {
2694 DetectedObject detobj = new DetectedObject();
2695 detobj.keyUUID = av.UUID;
2696 detobj.nameStr = av.ControllingClient.Name;
2697 detobj.ownerUUID = av.UUID;
2698 detobj.posVector = av.AbsolutePosition;
2699 detobj.rotQuat = av.Rotation;
2700 detobj.velVector = av.Velocity;
2701 detobj.colliderType = 0;
2702 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2703 colliding.Add(detobj);
2704 }
2705 //If it is 0, it is to not accept collisions from this avatar
2706 else
2707 {
2708 }
2709 }
2710 else
2711 {
2712 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2713 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2714 if (!found)
2715 {
2716 DetectedObject detobj = new DetectedObject();
2717 detobj.keyUUID = av.UUID;
2718 detobj.nameStr = av.ControllingClient.Name;
2719 detobj.ownerUUID = av.UUID;
2720 detobj.posVector = av.AbsolutePosition;
2721 detobj.rotQuat = av.Rotation;
2722 detobj.velVector = av.Velocity;
2723 detobj.colliderType = 0;
2724 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2725 colliding.Add(detobj);
2726 }
2727 }
2728
2729 }
2730 });
2731 }
2732 }
2733 if (colliding.Count > 0)
2734 {
2735 CollidingMessage.Colliders = colliding;
2736
2737 if (ParentGroup.Scene == null)
2738 return;
2739
2740 ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage);
2741 } 2537 }
2742 } 2538 }
2743 } 2539 }
2744
2745 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
2746 {
2747 if (endedColliders.Count > 0)
2748 {
2749 ColliderArgs EndCollidingMessage = new ColliderArgs();
2750 List<DetectedObject> colliding = new List<DetectedObject>();
2751 foreach (uint localId in endedColliders)
2752 {
2753 if (localId == 0)
2754 continue;
2755 2540
2756 if (ParentGroup.Scene == null) 2541 colliderArgs.Colliders = colliding;
2757 return;
2758 2542
2759 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2543 return colliderArgs;
2760 string data = ""; 2544 }
2761 if (obj != null)
2762 {
2763 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2764 {
2765 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2766 //If it is 1, it is to accept ONLY collisions from this object
2767 if (found)
2768 {
2769 DetectedObject detobj = new DetectedObject();
2770 detobj.keyUUID = obj.UUID;
2771 detobj.nameStr = obj.Name;
2772 detobj.ownerUUID = obj.OwnerID;
2773 detobj.posVector = obj.AbsolutePosition;
2774 detobj.rotQuat = obj.GetWorldRotation();
2775 detobj.velVector = obj.Velocity;
2776 detobj.colliderType = 0;
2777 detobj.groupUUID = obj.GroupID;
2778 colliding.Add(detobj);
2779 }
2780 //If it is 0, it is to not accept collisions from this object
2781 else
2782 {
2783 }
2784 }
2785 else
2786 {
2787 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2788 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2789 if (!found)
2790 {
2791 DetectedObject detobj = new DetectedObject();
2792 detobj.keyUUID = obj.UUID;
2793 detobj.nameStr = obj.Name;
2794 detobj.ownerUUID = obj.OwnerID;
2795 detobj.posVector = obj.AbsolutePosition;
2796 detobj.rotQuat = obj.GetWorldRotation();
2797 detobj.velVector = obj.Velocity;
2798 detobj.colliderType = 0;
2799 detobj.groupUUID = obj.GroupID;
2800 colliding.Add(detobj);
2801 }
2802 }
2803 }
2804 else
2805 {
2806 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2807 {
2808 if (av.LocalId == localId)
2809 {
2810 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2811 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2812 {
2813 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2814 //If it is 1, it is to accept ONLY collisions from this avatar
2815 if (found)
2816 {
2817 DetectedObject detobj = new DetectedObject();
2818 detobj.keyUUID = av.UUID;
2819 detobj.nameStr = av.ControllingClient.Name;
2820 detobj.ownerUUID = av.UUID;
2821 detobj.posVector = av.AbsolutePosition;
2822 detobj.rotQuat = av.Rotation;
2823 detobj.velVector = av.Velocity;
2824 detobj.colliderType = 0;
2825 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2826 colliding.Add(detobj);
2827 }
2828 //If it is 0, it is to not accept collisions from this avatar
2829 else
2830 {
2831 }
2832 }
2833 else
2834 {
2835 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2836 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2837 if (!found)
2838 {
2839 DetectedObject detobj = new DetectedObject();
2840 detobj.keyUUID = av.UUID;
2841 detobj.nameStr = av.ControllingClient.Name;
2842 detobj.ownerUUID = av.UUID;
2843 detobj.posVector = av.AbsolutePosition;
2844 detobj.rotQuat = av.Rotation;
2845 detobj.velVector = av.Velocity;
2846 detobj.colliderType = 0;
2847 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2848 colliding.Add(detobj);
2849 }
2850 }
2851 2545
2852 } 2546 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
2853 }); 2547
2854 } 2548 private void SendCollisionEvent(scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
2855 } 2549 {
2856 2550 bool sendToRoot = false;
2857 if (colliding.Count > 0) 2551 ColliderArgs CollidingMessage;
2858 {
2859 EndCollidingMessage.Colliders = colliding;
2860
2861 if (ParentGroup.Scene == null)
2862 return;
2863
2864 ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage);
2865 }
2866 }
2867 }
2868 2552
2869 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2553 if (colliders.Count > 0)
2870 { 2554 {
2871 if (startedColliders.Count > 0) 2555 if ((ScriptEvents & ev) != 0)
2872 { 2556 {
2873 ColliderArgs LandStartCollidingMessage = new ColliderArgs(); 2557 CollidingMessage = CreateColliderArgs(this, colliders);
2874 List<DetectedObject> colliding = new List<DetectedObject>();
2875 foreach (uint localId in startedColliders)
2876 {
2877 if (localId == 0)
2878 {
2879 //Hope that all is left is ground!
2880 DetectedObject detobj = new DetectedObject();
2881 detobj.keyUUID = UUID.Zero;
2882 detobj.nameStr = "";
2883 detobj.ownerUUID = UUID.Zero;
2884 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2885 detobj.rotQuat = Quaternion.Identity;
2886 detobj.velVector = Vector3.Zero;
2887 detobj.colliderType = 0;
2888 detobj.groupUUID = UUID.Zero;
2889 colliding.Add(detobj);
2890 }
2891 }
2892
2893 if (colliding.Count > 0)
2894 {
2895 LandStartCollidingMessage.Colliders = colliding;
2896 2558
2897 if (ParentGroup.Scene == null) 2559 if (CollidingMessage.Colliders.Count > 0)
2898 return; 2560 notify(LocalId, CollidingMessage);
2899 2561
2900 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage); 2562 if (PassCollisions)
2901 } 2563 sendToRoot = true;
2564 }
2565 else
2566 {
2567 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0)
2568 sendToRoot = true;
2569 }
2570 if (sendToRoot && ParentGroup.RootPart != this)
2571 {
2572 CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders);
2573 if (CollidingMessage.Colliders.Count > 0)
2574 notify(ParentGroup.RootPart.LocalId, CollidingMessage);
2902 } 2575 }
2903 } 2576 }
2577 }
2904 2578
2905 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2579 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2580 {
2581 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
2906 { 2582 {
2907 if (m_lastColliders.Count > 0) 2583 ColliderArgs LandCollidingMessage = new ColliderArgs();
2908 { 2584 List<DetectedObject> colliding = new List<DetectedObject>();
2909 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2585
2910 List<DetectedObject> colliding = new List<DetectedObject>(); 2586 colliding.Add(CreateDetObjectForGround());
2911 foreach (uint localId in startedColliders) 2587 LandCollidingMessage.Colliders = colliding;
2912 {
2913 if (localId == 0)
2914 {
2915 //Hope that all is left is ground!
2916 DetectedObject detobj = new DetectedObject();
2917 detobj.keyUUID = UUID.Zero;
2918 detobj.nameStr = "";
2919 detobj.ownerUUID = UUID.Zero;
2920 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2921 detobj.rotQuat = Quaternion.Identity;
2922 detobj.velVector = Vector3.Zero;
2923 detobj.colliderType = 0;
2924 detobj.groupUUID = UUID.Zero;
2925 colliding.Add(detobj);
2926 }
2927 }
2928 2588
2929 if (colliding.Count > 0) 2589 notify(LocalId, LandCollidingMessage);
2930 { 2590 }
2931 LandCollidingMessage.Colliders = colliding; 2591 }
2932 2592
2933 if (ParentGroup.Scene == null) 2593 public void PhysicsCollision(EventArgs e)
2934 return; 2594 {
2595 if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
2596 return;
2935 2597
2936 ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage); 2598 // single threaded here
2937 } 2599 CollisionEventUpdate a = (CollisionEventUpdate)e;
2938 } 2600 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2601 List<uint> thisHitColliders = new List<uint>();
2602 List<uint> endedColliders = new List<uint>();
2603 List<uint> startedColliders = new List<uint>();
2604
2605 // calculate things that started colliding this time
2606 // and build up list of colliders this time
2607 foreach (uint localid in collissionswith.Keys)
2608 {
2609 thisHitColliders.Add(localid);
2610 if (!m_lastColliders.Contains(localid))
2611 startedColliders.Add(localid);
2939 } 2612 }
2940 2613
2941 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2614 // calculate things that ended colliding
2615 foreach (uint localID in m_lastColliders)
2942 { 2616 {
2943 if (endedColliders.Count > 0) 2617 if (!thisHitColliders.Contains(localID))
2944 { 2618 endedColliders.Add(localID);
2945 ColliderArgs LandEndCollidingMessage = new ColliderArgs(); 2619 }
2946 List<DetectedObject> colliding = new List<DetectedObject>();
2947 foreach (uint localId in startedColliders)
2948 {
2949 if (localId == 0)
2950 {
2951 //Hope that all is left is ground!
2952 DetectedObject detobj = new DetectedObject();
2953 detobj.keyUUID = UUID.Zero;
2954 detobj.nameStr = "";
2955 detobj.ownerUUID = UUID.Zero;
2956 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2957 detobj.rotQuat = Quaternion.Identity;
2958 detobj.velVector = Vector3.Zero;
2959 detobj.colliderType = 0;
2960 detobj.groupUUID = UUID.Zero;
2961 colliding.Add(detobj);
2962 }
2963 }
2964 2620
2965 if (colliding.Count > 0) 2621 //add the items that started colliding this time to the last colliders list.
2966 { 2622 foreach (uint localID in startedColliders)
2967 LandEndCollidingMessage.Colliders = colliding; 2623 m_lastColliders.Add(localID);
2968 2624
2969 if (ParentGroup.Scene == null) 2625 // remove things that ended colliding from the last colliders list
2970 return; 2626 foreach (uint localID in endedColliders)
2627 m_lastColliders.Remove(localID);
2971 2628
2972 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage); 2629 // play the sound.
2973 } 2630 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
2974 } 2631 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2632
2633 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2634 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2635 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2636
2637 if (startedColliders.Contains(0))
2638 {
2639 if (m_lastColliders.Contains(0))
2640 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2641 else
2642 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2975 } 2643 }
2644 if (endedColliders.Contains(0))
2645 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2976 } 2646 }
2977 2647
2978 public void PhysicsOutOfBounds(Vector3 pos) 2648 public void PhysicsOutOfBounds(Vector3 pos)
@@ -4724,7 +4394,7 @@ namespace OpenSim.Region.Framework.Scenes
4724// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4394// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4725// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4395// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4726// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4396// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4727 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero) 4397 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4728// (CollisionSound != UUID.Zero) 4398// (CollisionSound != UUID.Zero)
4729 ) 4399 )
4730 { 4400 {
@@ -5077,7 +4747,7 @@ namespace OpenSim.Region.Framework.Scenes
5077// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4747// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5078// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4748// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5079// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4749// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5080 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero) 4750 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5081 ) 4751 )
5082 { 4752 {
5083 // subscribe to physics updates. 4753 // subscribe to physics updates.
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 1cd8189..151eba2 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -307,6 +307,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
307 m_SOPXmlProcessors.Add("Name", ProcessName); 307 m_SOPXmlProcessors.Add("Name", ProcessName);
308 m_SOPXmlProcessors.Add("Material", ProcessMaterial); 308 m_SOPXmlProcessors.Add("Material", ProcessMaterial);
309 m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches); 309 m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches);
310 m_SOPXmlProcessors.Add("PassCollisions", ProcessPassCollisions);
310 m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle); 311 m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle);
311 m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin); 312 m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin);
312 m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition); 313 m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition);
@@ -506,6 +507,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
506 obj.PassTouches = Util.ReadBoolean(reader); 507 obj.PassTouches = Util.ReadBoolean(reader);
507 } 508 }
508 509
510 private static void ProcessPassCollisions(SceneObjectPart obj, XmlTextReader reader)
511 {
512 obj.PassCollisions = Util.ReadBoolean(reader);
513 }
514
509 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) 515 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader)
510 { 516 {
511 obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty); 517 obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty);
@@ -1246,6 +1252,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1246 writer.WriteElementString("Name", sop.Name); 1252 writer.WriteElementString("Name", sop.Name);
1247 writer.WriteElementString("Material", sop.Material.ToString()); 1253 writer.WriteElementString("Material", sop.Material.ToString());
1248 writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower()); 1254 writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower());
1255 writer.WriteElementString("PassCollisions", sop.PassCollisions.ToString().ToLower());
1249 writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString()); 1256 writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString());
1250 writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString()); 1257 writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString());
1251 1258