aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Data/Tests/RegionTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs685
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs21
5 files changed, 202 insertions, 523 deletions
diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs
index 1f03ec5..474609b 100644
--- a/OpenSim/Data/Tests/RegionTests.cs
+++ b/OpenSim/Data/Tests/RegionTests.cs
@@ -632,7 +632,6 @@ namespace OpenSim.Data.Tests
632 .IgnoreProperty(x=>x.RegionUUID) 632 .IgnoreProperty(x=>x.RegionUUID)
633 .IgnoreProperty(x=>x.Scene) 633 .IgnoreProperty(x=>x.Scene)
634 .IgnoreProperty(x=>x.Parts) 634 .IgnoreProperty(x=>x.Parts)
635 .IgnoreProperty(x=>x.PassCollision)
636 .IgnoreProperty(x=>x.RootPart)); 635 .IgnoreProperty(x=>x.RootPart));
637 } 636 }
638 637
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 05bea8d..20d7a01 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -505,17 +505,6 @@ namespace OpenSim.Region.Framework.Scenes
505 get { return true; } 505 get { return true; }
506 } 506 }
507 507
508 private bool m_passCollision;
509 public bool PassCollision
510 {
511 get { return m_passCollision; }
512 set
513 {
514 m_passCollision = value;
515 HasGroupChanged = true;
516 }
517 }
518
519 public bool IsSelected 508 public bool IsSelected
520 { 509 {
521 get { return m_isSelected; } 510 get { return m_isSelected; }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1a940aa..dc76d22 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -254,7 +254,8 @@ namespace OpenSim.Region.Framework.Scenes
254 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 254 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
255 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5); 255 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
256 256
257 private bool m_passTouches; 257 private bool m_passTouches = false;
258 private bool m_passCollisions = false;
258 259
259 protected Vector3 m_acceleration; 260 protected Vector3 m_acceleration;
260 protected Vector3 m_angularVelocity; 261 protected Vector3 m_angularVelocity;
@@ -541,6 +542,7 @@ namespace OpenSim.Region.Framework.Scenes
541 } 542 }
542 } 543 }
543 544
545 [XmlIgnore]
544 public bool PassTouches 546 public bool PassTouches
545 { 547 {
546 get { return m_passTouches; } 548 get { return m_passTouches; }
@@ -553,8 +555,18 @@ namespace OpenSim.Region.Framework.Scenes
553 } 555 }
554 } 556 }
555 557
556 558 public bool PassCollisions
557 559 {
560 get { return m_passCollisions; }
561 set
562 {
563 m_passCollisions = value;
564
565 if (ParentGroup != null)
566 ParentGroup.HasGroupChanged = true;
567 }
568 }
569
558 public Dictionary<int, string> CollisionFilter 570 public Dictionary<int, string> CollisionFilter
559 { 571 {
560 get { return m_CollisionFilter; } 572 get { return m_CollisionFilter; }
@@ -2011,546 +2023,202 @@ namespace OpenSim.Region.Framework.Scenes
2011 { 2023 {
2012 } 2024 }
2013 2025
2014 public void PhysicsCollision(EventArgs e) 2026 private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName)
2015 { 2027 {
2016// m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID); 2028 if(dest.CollisionFilter.Count == 0)
2017 2029 return false;
2018 // single threaded here
2019
2020 CollisionEventUpdate a = (CollisionEventUpdate)e;
2021 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2022 List<uint> thisHitColliders = new List<uint>();
2023 List<uint> endedColliders = new List<uint>();
2024 List<uint> startedColliders = new List<uint>();
2025
2026 // calculate things that started colliding this time
2027 // and build up list of colliders this time
2028 foreach (uint localid in collissionswith.Keys)
2029 {
2030 thisHitColliders.Add(localid);
2031 if (!m_lastColliders.Contains(localid))
2032 {
2033 startedColliders.Add(localid);
2034 }
2035 //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
2036 }
2037 2030
2038 // calculate things that ended colliding 2031 if (dest.CollisionFilter.ContainsValue(objectID.ToString()) ||
2039 foreach (uint localID in m_lastColliders) 2032 dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) ||
2033 dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName))
2040 { 2034 {
2041 if (!thisHitColliders.Contains(localID)) 2035 if (dest.CollisionFilter.ContainsKey(1))
2042 { 2036 return false;
2043 endedColliders.Add(localID); 2037 return true;
2044 }
2045 } 2038 }
2046 2039
2047 //add the items that started colliding this time to the last colliders list. 2040 if (dest.CollisionFilter.ContainsKey(1))
2048 foreach (uint localID in startedColliders) 2041 return true;
2049 {
2050 m_lastColliders.Add(localID);
2051 }
2052 // remove things that ended colliding from the last colliders list
2053 foreach (uint localID in endedColliders)
2054 {
2055 m_lastColliders.Remove(localID);
2056 }
2057
2058 if (ParentGroup.IsDeleted)
2059 return;
2060 2042
2061 // play the sound. 2043 return false;
2062 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2044 }
2063 {
2064 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2065 }
2066 2045
2067 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) 2046 private DetectedObject CreateDetObject(SceneObjectPart obj)
2068 { 2047 {
2069 // do event notification 2048 DetectedObject detobj = new DetectedObject();
2070 if (startedColliders.Count > 0) 2049 detobj.keyUUID = obj.UUID;
2071 { 2050 detobj.nameStr = obj.Name;
2072 ColliderArgs StartCollidingMessage = new ColliderArgs(); 2051 detobj.ownerUUID = obj.OwnerID;
2073 List<DetectedObject> colliding = new List<DetectedObject>(); 2052 detobj.posVector = obj.AbsolutePosition;
2074 foreach (uint localId in startedColliders) 2053 detobj.rotQuat = obj.GetWorldRotation();
2075 { 2054 detobj.velVector = obj.Velocity;
2076 if (localId == 0) 2055 detobj.colliderType = 0;
2077 continue; 2056 detobj.groupUUID = obj.GroupID;
2078 2057
2079 if (ParentGroup.Scene == null) 2058 return detobj;
2080 return; 2059 }
2081 2060
2082 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2061 private DetectedObject CreateDetObject(ScenePresence av)
2083 string data = ""; 2062 {
2084 if (obj != null) 2063 DetectedObject detobj = new DetectedObject();
2085 { 2064 detobj.keyUUID = av.UUID;
2086 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) 2065 detobj.nameStr = av.ControllingClient.Name;
2087 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2066 detobj.ownerUUID = av.UUID;
2088 { 2067 detobj.posVector = av.AbsolutePosition;
2089 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2068 detobj.rotQuat = av.Rotation;
2090 //If it is 1, it is to accept ONLY collisions from this object 2069 detobj.velVector = av.Velocity;
2091 if (found) 2070 detobj.colliderType = 0;
2092 { 2071 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2093 DetectedObject detobj = new DetectedObject();
2094 detobj.keyUUID = obj.UUID;
2095 detobj.nameStr = obj.Name;
2096 detobj.ownerUUID = obj.OwnerID;
2097 detobj.posVector = obj.AbsolutePosition;
2098 detobj.rotQuat = obj.GetWorldRotation();
2099 detobj.velVector = obj.Velocity;
2100 detobj.colliderType = 0;
2101 detobj.groupUUID = obj.GroupID;
2102 colliding.Add(detobj);
2103 }
2104 //If it is 0, it is to not accept collisions from this object
2105 else
2106 {
2107 }
2108 }
2109 else
2110 {
2111 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2112 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2113 if (!found)
2114 {
2115 DetectedObject detobj = new DetectedObject();
2116 detobj.keyUUID = obj.UUID;
2117 detobj.nameStr = obj.Name;
2118 detobj.ownerUUID = obj.OwnerID;
2119 detobj.posVector = obj.AbsolutePosition;
2120 detobj.rotQuat = obj.GetWorldRotation();
2121 detobj.velVector = obj.Velocity;
2122 detobj.colliderType = 0;
2123 detobj.groupUUID = obj.GroupID;
2124 colliding.Add(detobj);
2125 }
2126 }
2127 }
2128 else
2129 {
2130 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2131 {
2132 if (av.LocalId == localId)
2133 {
2134 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2135 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2136 {
2137 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2138 //If it is 1, it is to accept ONLY collisions from this avatar
2139 if (found)
2140 {
2141 DetectedObject detobj = new DetectedObject();
2142 detobj.keyUUID = av.UUID;
2143 detobj.nameStr = av.ControllingClient.Name;
2144 detobj.ownerUUID = av.UUID;
2145 detobj.posVector = av.AbsolutePosition;
2146 detobj.rotQuat = av.Rotation;
2147 detobj.velVector = av.Velocity;
2148 detobj.colliderType = 0;
2149 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2150 colliding.Add(detobj);
2151 }
2152 //If it is 0, it is to not accept collisions from this avatar
2153 else
2154 {
2155 }
2156 }
2157 else
2158 {
2159 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2160 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2161 if (!found)
2162 {
2163 DetectedObject detobj = new DetectedObject();
2164 detobj.keyUUID = av.UUID;
2165 detobj.nameStr = av.ControllingClient.Name;
2166 detobj.ownerUUID = av.UUID;
2167 detobj.posVector = av.AbsolutePosition;
2168 detobj.rotQuat = av.Rotation;
2169 detobj.velVector = av.Velocity;
2170 detobj.colliderType = 0;
2171 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2172 colliding.Add(detobj);
2173 }
2174 }
2175 2072
2176 } 2073 return detobj;
2177 }); 2074 }
2178 }
2179 }
2180 2075
2181 if (colliding.Count > 0) 2076 private DetectedObject CreateDetObjectForGround()
2182 { 2077 {
2183 StartCollidingMessage.Colliders = colliding; 2078 DetectedObject detobj = new DetectedObject();
2079 detobj.keyUUID = UUID.Zero;
2080 detobj.nameStr = "";
2081 detobj.ownerUUID = UUID.Zero;
2082 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2083 detobj.rotQuat = Quaternion.Identity;
2084 detobj.velVector = Vector3.Zero;
2085 detobj.colliderType = 0;
2086 detobj.groupUUID = UUID.Zero;
2184 2087
2185 if (ParentGroup.Scene == null) 2088 return detobj;
2186 return; 2089 }
2187 2090
2188// if (m_parentGroup.PassCollision == true) 2091 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
2189// { 2092 {
2190// //TODO: Add pass to root prim! 2093 ColliderArgs colliderArgs = new ColliderArgs();
2191// } 2094 List<DetectedObject> colliding = new List<DetectedObject>();
2095 foreach (uint localId in colliders)
2096 {
2097 if (localId == 0)
2098 continue;
2192 2099
2193 ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); 2100 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2194 } 2101 if (obj != null)
2102 {
2103 if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name))
2104 colliding.Add(CreateDetObject(obj));
2195 } 2105 }
2196 } 2106 else
2197
2198 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
2199 {
2200 if (m_lastColliders.Count > 0)
2201 { 2107 {
2202 ColliderArgs CollidingMessage = new ColliderArgs(); 2108 ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
2203 List<DetectedObject> colliding = new List<DetectedObject>(); 2109 if (av != null && (!av.IsChildAgent))
2204 foreach (uint localId in m_lastColliders)
2205 {
2206 // always running this check because if the user deletes the object it would return a null reference.
2207 if (localId == 0)
2208 continue;
2209
2210 if (ParentGroup.Scene == null)
2211 return;
2212
2213 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2214 string data = "";
2215 if (obj != null)
2216 {
2217 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2218 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2219 {
2220 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2221 //If it is 1, it is to accept ONLY collisions from this object
2222 if (found)
2223 {
2224 DetectedObject detobj = new DetectedObject();
2225 detobj.keyUUID = obj.UUID;
2226 detobj.nameStr = obj.Name;
2227 detobj.ownerUUID = obj.OwnerID;
2228 detobj.posVector = obj.AbsolutePosition;
2229 detobj.rotQuat = obj.GetWorldRotation();
2230 detobj.velVector = obj.Velocity;
2231 detobj.colliderType = 0;
2232 detobj.groupUUID = obj.GroupID;
2233 colliding.Add(detobj);
2234 }
2235 //If it is 0, it is to not accept collisions from this object
2236 else
2237 {
2238 }
2239 }
2240 else
2241 {
2242 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2243 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2244 if (!found)
2245 {
2246 DetectedObject detobj = new DetectedObject();
2247 detobj.keyUUID = obj.UUID;
2248 detobj.nameStr = obj.Name;
2249 detobj.ownerUUID = obj.OwnerID;
2250 detobj.posVector = obj.AbsolutePosition;
2251 detobj.rotQuat = obj.GetWorldRotation();
2252 detobj.velVector = obj.Velocity;
2253 detobj.colliderType = 0;
2254 detobj.groupUUID = obj.GroupID;
2255 colliding.Add(detobj);
2256 }
2257 }
2258 }
2259 else
2260 {
2261 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2262 {
2263 if (av.LocalId == localId)
2264 {
2265 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2266 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2267 {
2268 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2269 //If it is 1, it is to accept ONLY collisions from this avatar
2270 if (found)
2271 {
2272 DetectedObject detobj = new DetectedObject();
2273 detobj.keyUUID = av.UUID;
2274 detobj.nameStr = av.ControllingClient.Name;
2275 detobj.ownerUUID = av.UUID;
2276 detobj.posVector = av.AbsolutePosition;
2277 detobj.rotQuat = av.Rotation;
2278 detobj.velVector = av.Velocity;
2279 detobj.colliderType = 0;
2280 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2281 colliding.Add(detobj);
2282 }
2283 //If it is 0, it is to not accept collisions from this avatar
2284 else
2285 {
2286 }
2287 }
2288 else
2289 {
2290 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2291 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2292 if (!found)
2293 {
2294 DetectedObject detobj = new DetectedObject();
2295 detobj.keyUUID = av.UUID;
2296 detobj.nameStr = av.ControllingClient.Name;
2297 detobj.ownerUUID = av.UUID;
2298 detobj.posVector = av.AbsolutePosition;
2299 detobj.rotQuat = av.Rotation;
2300 detobj.velVector = av.Velocity;
2301 detobj.colliderType = 0;
2302 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2303 colliding.Add(detobj);
2304 }
2305 }
2306
2307 }
2308 });
2309 }
2310 }
2311 if (colliding.Count > 0)
2312 { 2110 {
2313 CollidingMessage.Colliders = colliding; 2111 if (!dest.CollisionFilteredOut(this, av.UUID, av.Name))
2314 2112 colliding.Add(CreateDetObject(av));
2315 if (ParentGroup.Scene == null)
2316 return;
2317
2318 ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage);
2319 } 2113 }
2320 } 2114 }
2321 } 2115 }
2322
2323 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
2324 {
2325 if (endedColliders.Count > 0)
2326 {
2327 ColliderArgs EndCollidingMessage = new ColliderArgs();
2328 List<DetectedObject> colliding = new List<DetectedObject>();
2329 foreach (uint localId in endedColliders)
2330 {
2331 if (localId == 0)
2332 continue;
2333 2116
2334 if (ParentGroup.Scene == null) 2117 colliderArgs.Colliders = colliding;
2335 return;
2336 2118
2337 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2119 return colliderArgs;
2338 string data = ""; 2120 }
2339 if (obj != null)
2340 {
2341 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2342 {
2343 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2344 //If it is 1, it is to accept ONLY collisions from this object
2345 if (found)
2346 {
2347 DetectedObject detobj = new DetectedObject();
2348 detobj.keyUUID = obj.UUID;
2349 detobj.nameStr = obj.Name;
2350 detobj.ownerUUID = obj.OwnerID;
2351 detobj.posVector = obj.AbsolutePosition;
2352 detobj.rotQuat = obj.GetWorldRotation();
2353 detobj.velVector = obj.Velocity;
2354 detobj.colliderType = 0;
2355 detobj.groupUUID = obj.GroupID;
2356 colliding.Add(detobj);
2357 }
2358 //If it is 0, it is to not accept collisions from this object
2359 else
2360 {
2361 }
2362 }
2363 else
2364 {
2365 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2366 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2367 if (!found)
2368 {
2369 DetectedObject detobj = new DetectedObject();
2370 detobj.keyUUID = obj.UUID;
2371 detobj.nameStr = obj.Name;
2372 detobj.ownerUUID = obj.OwnerID;
2373 detobj.posVector = obj.AbsolutePosition;
2374 detobj.rotQuat = obj.GetWorldRotation();
2375 detobj.velVector = obj.Velocity;
2376 detobj.colliderType = 0;
2377 detobj.groupUUID = obj.GroupID;
2378 colliding.Add(detobj);
2379 }
2380 }
2381 }
2382 else
2383 {
2384 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2385 {
2386 if (av.LocalId == localId)
2387 {
2388 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2389 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2390 {
2391 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2392 //If it is 1, it is to accept ONLY collisions from this avatar
2393 if (found)
2394 {
2395 DetectedObject detobj = new DetectedObject();
2396 detobj.keyUUID = av.UUID;
2397 detobj.nameStr = av.ControllingClient.Name;
2398 detobj.ownerUUID = av.UUID;
2399 detobj.posVector = av.AbsolutePosition;
2400 detobj.rotQuat = av.Rotation;
2401 detobj.velVector = av.Velocity;
2402 detobj.colliderType = 0;
2403 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2404 colliding.Add(detobj);
2405 }
2406 //If it is 0, it is to not accept collisions from this avatar
2407 else
2408 {
2409 }
2410 }
2411 else
2412 {
2413 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2414 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2415 if (!found)
2416 {
2417 DetectedObject detobj = new DetectedObject();
2418 detobj.keyUUID = av.UUID;
2419 detobj.nameStr = av.ControllingClient.Name;
2420 detobj.ownerUUID = av.UUID;
2421 detobj.posVector = av.AbsolutePosition;
2422 detobj.rotQuat = av.Rotation;
2423 detobj.velVector = av.Velocity;
2424 detobj.colliderType = 0;
2425 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2426 colliding.Add(detobj);
2427 }
2428 }
2429 2121
2430 } 2122 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
2431 }); 2123
2432 } 2124 private void SendCollisionEvent(scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
2433 } 2125 {
2434 2126 bool sendToRoot = false;
2435 if (colliding.Count > 0) 2127 ColliderArgs CollidingMessage;
2436 {
2437 EndCollidingMessage.Colliders = colliding;
2438
2439 if (ParentGroup.Scene == null)
2440 return;
2441
2442 ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage);
2443 }
2444 }
2445 }
2446 2128
2447 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2129 if (colliders.Count > 0)
2448 { 2130 {
2449 if (startedColliders.Count > 0) 2131 if ((ScriptEvents & ev) != 0)
2450 { 2132 {
2451 ColliderArgs LandStartCollidingMessage = new ColliderArgs(); 2133 CollidingMessage = CreateColliderArgs(this, colliders);
2452 List<DetectedObject> colliding = new List<DetectedObject>();
2453 foreach (uint localId in startedColliders)
2454 {
2455 if (localId == 0)
2456 {
2457 //Hope that all is left is ground!
2458 DetectedObject detobj = new DetectedObject();
2459 detobj.keyUUID = UUID.Zero;
2460 detobj.nameStr = "";
2461 detobj.ownerUUID = UUID.Zero;
2462 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2463 detobj.rotQuat = Quaternion.Identity;
2464 detobj.velVector = Vector3.Zero;
2465 detobj.colliderType = 0;
2466 detobj.groupUUID = UUID.Zero;
2467 colliding.Add(detobj);
2468 }
2469 }
2470 2134
2471 if (colliding.Count > 0) 2135 if (CollidingMessage.Colliders.Count > 0)
2472 { 2136 notify(LocalId, CollidingMessage);
2473 LandStartCollidingMessage.Colliders = colliding;
2474
2475 if (ParentGroup.Scene == null)
2476 return;
2477 2137
2478 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage); 2138 if (PassCollisions)
2479 } 2139 sendToRoot = true;
2140 }
2141 else
2142 {
2143 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
2144 sendToRoot = true;
2145 }
2146 if (sendToRoot && ParentGroup.RootPart != this)
2147 {
2148 CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders);
2149 if (CollidingMessage.Colliders.Count > 0)
2150 notify(ParentGroup.RootPart.LocalId, CollidingMessage);
2480 } 2151 }
2481 } 2152 }
2153 }
2482 2154
2483 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2155 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2156 {
2157 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
2484 { 2158 {
2485 if (m_lastColliders.Count > 0) 2159 ColliderArgs LandCollidingMessage = new ColliderArgs();
2486 { 2160 List<DetectedObject> colliding = new List<DetectedObject>();
2487 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2161
2488 List<DetectedObject> colliding = new List<DetectedObject>(); 2162 colliding.Add(CreateDetObjectForGround());
2489 foreach (uint localId in startedColliders) 2163 LandCollidingMessage.Colliders = colliding;
2490 {
2491 if (localId == 0)
2492 {
2493 //Hope that all is left is ground!
2494 DetectedObject detobj = new DetectedObject();
2495 detobj.keyUUID = UUID.Zero;
2496 detobj.nameStr = "";
2497 detobj.ownerUUID = UUID.Zero;
2498 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2499 detobj.rotQuat = Quaternion.Identity;
2500 detobj.velVector = Vector3.Zero;
2501 detobj.colliderType = 0;
2502 detobj.groupUUID = UUID.Zero;
2503 colliding.Add(detobj);
2504 }
2505 }
2506 2164
2507 if (colliding.Count > 0) 2165 notify(LocalId, LandCollidingMessage);
2508 { 2166 }
2509 LandCollidingMessage.Colliders = colliding; 2167 }
2168
2169 public void PhysicsCollision(EventArgs e)
2170 {
2171 if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
2172 return;
2510 2173
2511 if (ParentGroup.Scene == null) 2174 // single threaded here
2512 return; 2175 CollisionEventUpdate a = (CollisionEventUpdate)e;
2176 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2177 List<uint> thisHitColliders = new List<uint>();
2178 List<uint> endedColliders = new List<uint>();
2179 List<uint> startedColliders = new List<uint>();
2513 2180
2514 ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage); 2181 // calculate things that started colliding this time
2515 } 2182 // and build up list of colliders this time
2516 } 2183 foreach (uint localid in collissionswith.Keys)
2184 {
2185 thisHitColliders.Add(localid);
2186 if (!m_lastColliders.Contains(localid))
2187 startedColliders.Add(localid);
2517 } 2188 }
2518 2189
2519 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2190 // calculate things that ended colliding
2191 foreach (uint localID in m_lastColliders)
2520 { 2192 {
2521 if (endedColliders.Count > 0) 2193 if (!thisHitColliders.Contains(localID))
2522 { 2194 endedColliders.Add(localID);
2523 ColliderArgs LandEndCollidingMessage = new ColliderArgs(); 2195 }
2524 List<DetectedObject> colliding = new List<DetectedObject>();
2525 foreach (uint localId in startedColliders)
2526 {
2527 if (localId == 0)
2528 {
2529 //Hope that all is left is ground!
2530 DetectedObject detobj = new DetectedObject();
2531 detobj.keyUUID = UUID.Zero;
2532 detobj.nameStr = "";
2533 detobj.ownerUUID = UUID.Zero;
2534 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2535 detobj.rotQuat = Quaternion.Identity;
2536 detobj.velVector = Vector3.Zero;
2537 detobj.colliderType = 0;
2538 detobj.groupUUID = UUID.Zero;
2539 colliding.Add(detobj);
2540 }
2541 }
2542 2196
2543 if (colliding.Count > 0) 2197 //add the items that started colliding this time to the last colliders list.
2544 { 2198 foreach (uint localID in startedColliders)
2545 LandEndCollidingMessage.Colliders = colliding; 2199 m_lastColliders.Add(localID);
2546 2200
2547 if (ParentGroup.Scene == null) 2201 // remove things that ended colliding from the last colliders list
2548 return; 2202 foreach (uint localID in endedColliders)
2203 m_lastColliders.Remove(localID);
2549 2204
2550 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage); 2205 // play the sound.
2551 } 2206 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
2552 } 2207 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2208
2209 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2210 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2211 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2212
2213 if (startedColliders.Contains(0))
2214 {
2215 if (m_lastColliders.Contains(0))
2216 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2217 else
2218 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2553 } 2219 }
2220 if (endedColliders.Contains(0))
2221 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2554 } 2222 }
2555 2223
2556 public void PhysicsOutOfBounds(Vector3 pos) 2224 public void PhysicsOutOfBounds(Vector3 pos)
@@ -4339,6 +4007,12 @@ namespace OpenSim.Region.Framework.Scenes
4339 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4007 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4340 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4008 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4341 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4009 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4010 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4011 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4012 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4013 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4014 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4015 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4342 (CollisionSound != UUID.Zero) 4016 (CollisionSound != UUID.Zero)
4343 ) 4017 )
4344 { 4018 {
@@ -4622,6 +4296,9 @@ namespace OpenSim.Region.Framework.Scenes
4622 4296
4623 public void aggregateScriptEvents() 4297 public void aggregateScriptEvents()
4624 { 4298 {
4299 if (ParentGroup == null || ParentGroup.RootPart == null)
4300 return;
4301
4625 AggregateScriptEvents = 0; 4302 AggregateScriptEvents = 0;
4626 4303
4627 // Aggregate script events 4304 // Aggregate script events
@@ -4663,6 +4340,12 @@ namespace OpenSim.Region.Framework.Scenes
4663 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4340 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4664 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4341 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4665 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4342 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4343 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4344 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4345 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4346 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4347 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4348 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4666 (CollisionSound != UUID.Zero) 4349 (CollisionSound != UUID.Zero)
4667 ) 4350 )
4668 { 4351 {
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index e6b88a3..a11dc49 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -301,6 +301,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
301 m_SOPXmlProcessors.Add("Name", ProcessName); 301 m_SOPXmlProcessors.Add("Name", ProcessName);
302 m_SOPXmlProcessors.Add("Material", ProcessMaterial); 302 m_SOPXmlProcessors.Add("Material", ProcessMaterial);
303 m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches); 303 m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches);
304 m_SOPXmlProcessors.Add("PassCollisions", ProcessPassCollisions);
304 m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle); 305 m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle);
305 m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin); 306 m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin);
306 m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition); 307 m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition);
@@ -485,6 +486,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
485 obj.PassTouches = Util.ReadBoolean(reader); 486 obj.PassTouches = Util.ReadBoolean(reader);
486 } 487 }
487 488
489 private static void ProcessPassCollisions(SceneObjectPart obj, XmlTextReader reader)
490 {
491 obj.PassCollisions = Util.ReadBoolean(reader);
492 }
493
488 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) 494 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader)
489 { 495 {
490 obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty); 496 obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty);
@@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1153 writer.WriteElementString("Name", sop.Name); 1159 writer.WriteElementString("Name", sop.Name);
1154 writer.WriteElementString("Material", sop.Material.ToString()); 1160 writer.WriteElementString("Material", sop.Material.ToString());
1155 writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower()); 1161 writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower());
1162 writer.WriteElementString("PassCollisions", sop.PassCollisions.ToString().ToLower());
1156 writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString()); 1163 writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString());
1157 writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString()); 1164 writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString());
1158 1165
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 5bff2e9..d213c35 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2929,14 +2929,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2929 { 2929 {
2930 m_host.AddScriptLPS(1); 2930 m_host.AddScriptLPS(1);
2931 m_host.CollisionFilter.Clear(); 2931 m_host.CollisionFilter.Clear();
2932 if (id != null) 2932 UUID objectID;
2933 { 2933
2934 m_host.CollisionFilter.Add(accept,id); 2934 if (!UUID.TryParse(id, out objectID))
2935 } 2935 objectID = UUID.Zero;
2936 else 2936
2937 { 2937 if (objectID == UUID.Zero && name == "")
2938 m_host.CollisionFilter.Add(accept,name); 2938 return;
2939 } 2939
2940 m_host.CollisionFilter.Add(accept,objectID.ToString() + name);
2940 } 2941 }
2941 2942
2942 public void llTakeControls(int controls, int accept, int pass_on) 2943 public void llTakeControls(int controls, int accept, int pass_on)
@@ -4466,11 +4467,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4466 m_host.AddScriptLPS(1); 4467 m_host.AddScriptLPS(1);
4467 if (pass == 0) 4468 if (pass == 0)
4468 { 4469 {
4469 m_host.ParentGroup.PassCollision = false; 4470 m_host.PassCollisions = false;
4470 } 4471 }
4471 else 4472 else
4472 { 4473 {
4473 m_host.ParentGroup.PassCollision = true; 4474 m_host.PassCollisions = true;
4474 } 4475 }
4475 } 4476 }
4476 4477