aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2012-05-15 01:02:38 +0100
committerMelanie2012-05-15 01:02:38 +0100
commite7819ce909e7d0bd7494db9af8a8d5dc4212a6cb (patch)
tree173a1d33acd111c5925f7739052a7979fb41cb2d /OpenSim/Region
parentSave the Telehub and its Spawn Points in the OAR (diff)
downloadopensim-SC-e7819ce909e7d0bd7494db9af8a8d5dc4212a6cb.zip
opensim-SC-e7819ce909e7d0bd7494db9af8a8d5dc4212a6cb.tar.gz
opensim-SC-e7819ce909e7d0bd7494db9af8a8d5dc4212a6cb.tar.bz2
opensim-SC-e7819ce909e7d0bd7494db9af8a8d5dc4212a6cb.tar.xz
Port Avination's collision fixes to core.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs682
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs21
4 files changed, 199 insertions, 522 deletions
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 f911ef8..35986cf 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; }
@@ -2000,546 +2012,202 @@ namespace OpenSim.Region.Framework.Scenes
2000 { 2012 {
2001 } 2013 }
2002 2014
2003 public void PhysicsCollision(EventArgs e) 2015 private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName)
2004 { 2016 {
2005// m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID); 2017 if(dest.CollisionFilter.Count == 0)
2006 2018 return false;
2007 // single threaded here
2008
2009 CollisionEventUpdate a = (CollisionEventUpdate)e;
2010 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2011 List<uint> thisHitColliders = new List<uint>();
2012 List<uint> endedColliders = new List<uint>();
2013 List<uint> startedColliders = new List<uint>();
2014
2015 // calculate things that started colliding this time
2016 // and build up list of colliders this time
2017 foreach (uint localid in collissionswith.Keys)
2018 {
2019 thisHitColliders.Add(localid);
2020 if (!m_lastColliders.Contains(localid))
2021 {
2022 startedColliders.Add(localid);
2023 }
2024 //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
2025 }
2026 2019
2027 // calculate things that ended colliding 2020 if (dest.CollisionFilter.ContainsValue(objectID.ToString()) ||
2028 foreach (uint localID in m_lastColliders) 2021 dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) ||
2022 dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName))
2029 { 2023 {
2030 if (!thisHitColliders.Contains(localID)) 2024 if (dest.CollisionFilter.ContainsKey(1))
2031 { 2025 return false;
2032 endedColliders.Add(localID); 2026 return true;
2033 }
2034 } 2027 }
2035 2028
2036 //add the items that started colliding this time to the last colliders list. 2029 if (dest.CollisionFilter.ContainsKey(1))
2037 foreach (uint localID in startedColliders) 2030 return true;
2038 {
2039 m_lastColliders.Add(localID);
2040 }
2041 // remove things that ended colliding from the last colliders list
2042 foreach (uint localID in endedColliders)
2043 {
2044 m_lastColliders.Remove(localID);
2045 }
2046
2047 if (ParentGroup.IsDeleted)
2048 return;
2049 2031
2050 // play the sound. 2032 return false;
2051 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2033 }
2052 {
2053 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2054 }
2055 2034
2056 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) 2035 private DetectedObject CreateDetObject(SceneObjectPart obj)
2057 { 2036 {
2058 // do event notification 2037 DetectedObject detobj = new DetectedObject();
2059 if (startedColliders.Count > 0) 2038 detobj.keyUUID = obj.UUID;
2060 { 2039 detobj.nameStr = obj.Name;
2061 ColliderArgs StartCollidingMessage = new ColliderArgs(); 2040 detobj.ownerUUID = obj.OwnerID;
2062 List<DetectedObject> colliding = new List<DetectedObject>(); 2041 detobj.posVector = obj.AbsolutePosition;
2063 foreach (uint localId in startedColliders) 2042 detobj.rotQuat = obj.GetWorldRotation();
2064 { 2043 detobj.velVector = obj.Velocity;
2065 if (localId == 0) 2044 detobj.colliderType = 0;
2066 continue; 2045 detobj.groupUUID = obj.GroupID;
2067 2046
2068 if (ParentGroup.Scene == null) 2047 return detobj;
2069 return; 2048 }
2070 2049
2071 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2050 private DetectedObject CreateDetObject(ScenePresence av)
2072 string data = ""; 2051 {
2073 if (obj != null) 2052 DetectedObject detobj = new DetectedObject();
2074 { 2053 detobj.keyUUID = av.UUID;
2075 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) 2054 detobj.nameStr = av.ControllingClient.Name;
2076 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2055 detobj.ownerUUID = av.UUID;
2077 { 2056 detobj.posVector = av.AbsolutePosition;
2078 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2057 detobj.rotQuat = av.Rotation;
2079 //If it is 1, it is to accept ONLY collisions from this object 2058 detobj.velVector = av.Velocity;
2080 if (found) 2059 detobj.colliderType = 0;
2081 { 2060 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2082 DetectedObject detobj = new DetectedObject();
2083 detobj.keyUUID = obj.UUID;
2084 detobj.nameStr = obj.Name;
2085 detobj.ownerUUID = obj.OwnerID;
2086 detobj.posVector = obj.AbsolutePosition;
2087 detobj.rotQuat = obj.GetWorldRotation();
2088 detobj.velVector = obj.Velocity;
2089 detobj.colliderType = 0;
2090 detobj.groupUUID = obj.GroupID;
2091 colliding.Add(detobj);
2092 }
2093 //If it is 0, it is to not accept collisions from this object
2094 else
2095 {
2096 }
2097 }
2098 else
2099 {
2100 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2101 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2102 if (!found)
2103 {
2104 DetectedObject detobj = new DetectedObject();
2105 detobj.keyUUID = obj.UUID;
2106 detobj.nameStr = obj.Name;
2107 detobj.ownerUUID = obj.OwnerID;
2108 detobj.posVector = obj.AbsolutePosition;
2109 detobj.rotQuat = obj.GetWorldRotation();
2110 detobj.velVector = obj.Velocity;
2111 detobj.colliderType = 0;
2112 detobj.groupUUID = obj.GroupID;
2113 colliding.Add(detobj);
2114 }
2115 }
2116 }
2117 else
2118 {
2119 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2120 {
2121 if (av.LocalId == localId)
2122 {
2123 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2124 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2125 {
2126 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2127 //If it is 1, it is to accept ONLY collisions from this avatar
2128 if (found)
2129 {
2130 DetectedObject detobj = new DetectedObject();
2131 detobj.keyUUID = av.UUID;
2132 detobj.nameStr = av.ControllingClient.Name;
2133 detobj.ownerUUID = av.UUID;
2134 detobj.posVector = av.AbsolutePosition;
2135 detobj.rotQuat = av.Rotation;
2136 detobj.velVector = av.Velocity;
2137 detobj.colliderType = 0;
2138 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2139 colliding.Add(detobj);
2140 }
2141 //If it is 0, it is to not accept collisions from this avatar
2142 else
2143 {
2144 }
2145 }
2146 else
2147 {
2148 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2149 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2150 if (!found)
2151 {
2152 DetectedObject detobj = new DetectedObject();
2153 detobj.keyUUID = av.UUID;
2154 detobj.nameStr = av.ControllingClient.Name;
2155 detobj.ownerUUID = av.UUID;
2156 detobj.posVector = av.AbsolutePosition;
2157 detobj.rotQuat = av.Rotation;
2158 detobj.velVector = av.Velocity;
2159 detobj.colliderType = 0;
2160 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2161 colliding.Add(detobj);
2162 }
2163 }
2164 2061
2165 } 2062 return detobj;
2166 }); 2063 }
2167 }
2168 }
2169 2064
2170 if (colliding.Count > 0) 2065 private DetectedObject CreateDetObjectForGround()
2171 { 2066 {
2172 StartCollidingMessage.Colliders = colliding; 2067 DetectedObject detobj = new DetectedObject();
2068 detobj.keyUUID = UUID.Zero;
2069 detobj.nameStr = "";
2070 detobj.ownerUUID = UUID.Zero;
2071 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2072 detobj.rotQuat = Quaternion.Identity;
2073 detobj.velVector = Vector3.Zero;
2074 detobj.colliderType = 0;
2075 detobj.groupUUID = UUID.Zero;
2173 2076
2174 if (ParentGroup.Scene == null) 2077 return detobj;
2175 return; 2078 }
2176 2079
2177// if (m_parentGroup.PassCollision == true) 2080 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
2178// { 2081 {
2179// //TODO: Add pass to root prim! 2082 ColliderArgs colliderArgs = new ColliderArgs();
2180// } 2083 List<DetectedObject> colliding = new List<DetectedObject>();
2084 foreach (uint localId in colliders)
2085 {
2086 if (localId == 0)
2087 continue;
2181 2088
2182 ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); 2089 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2183 } 2090 if (obj != null)
2091 {
2092 if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name))
2093 colliding.Add(CreateDetObject(obj));
2184 } 2094 }
2185 } 2095 else
2186
2187 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
2188 {
2189 if (m_lastColliders.Count > 0)
2190 { 2096 {
2191 ColliderArgs CollidingMessage = new ColliderArgs(); 2097 ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
2192 List<DetectedObject> colliding = new List<DetectedObject>(); 2098 if (av != null && (!av.IsChildAgent))
2193 foreach (uint localId in m_lastColliders)
2194 {
2195 // always running this check because if the user deletes the object it would return a null reference.
2196 if (localId == 0)
2197 continue;
2198
2199 if (ParentGroup.Scene == null)
2200 return;
2201
2202 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
2203 string data = "";
2204 if (obj != null)
2205 {
2206 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2207 || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2208 {
2209 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2210 //If it is 1, it is to accept ONLY collisions from this object
2211 if (found)
2212 {
2213 DetectedObject detobj = new DetectedObject();
2214 detobj.keyUUID = obj.UUID;
2215 detobj.nameStr = obj.Name;
2216 detobj.ownerUUID = obj.OwnerID;
2217 detobj.posVector = obj.AbsolutePosition;
2218 detobj.rotQuat = obj.GetWorldRotation();
2219 detobj.velVector = obj.Velocity;
2220 detobj.colliderType = 0;
2221 detobj.groupUUID = obj.GroupID;
2222 colliding.Add(detobj);
2223 }
2224 //If it is 0, it is to not accept collisions from this object
2225 else
2226 {
2227 }
2228 }
2229 else
2230 {
2231 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2232 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2233 if (!found)
2234 {
2235 DetectedObject detobj = new DetectedObject();
2236 detobj.keyUUID = obj.UUID;
2237 detobj.nameStr = obj.Name;
2238 detobj.ownerUUID = obj.OwnerID;
2239 detobj.posVector = obj.AbsolutePosition;
2240 detobj.rotQuat = obj.GetWorldRotation();
2241 detobj.velVector = obj.Velocity;
2242 detobj.colliderType = 0;
2243 detobj.groupUUID = obj.GroupID;
2244 colliding.Add(detobj);
2245 }
2246 }
2247 }
2248 else
2249 {
2250 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2251 {
2252 if (av.LocalId == localId)
2253 {
2254 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2255 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2256 {
2257 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2258 //If it is 1, it is to accept ONLY collisions from this avatar
2259 if (found)
2260 {
2261 DetectedObject detobj = new DetectedObject();
2262 detobj.keyUUID = av.UUID;
2263 detobj.nameStr = av.ControllingClient.Name;
2264 detobj.ownerUUID = av.UUID;
2265 detobj.posVector = av.AbsolutePosition;
2266 detobj.rotQuat = av.Rotation;
2267 detobj.velVector = av.Velocity;
2268 detobj.colliderType = 0;
2269 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2270 colliding.Add(detobj);
2271 }
2272 //If it is 0, it is to not accept collisions from this avatar
2273 else
2274 {
2275 }
2276 }
2277 else
2278 {
2279 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2280 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2281 if (!found)
2282 {
2283 DetectedObject detobj = new DetectedObject();
2284 detobj.keyUUID = av.UUID;
2285 detobj.nameStr = av.ControllingClient.Name;
2286 detobj.ownerUUID = av.UUID;
2287 detobj.posVector = av.AbsolutePosition;
2288 detobj.rotQuat = av.Rotation;
2289 detobj.velVector = av.Velocity;
2290 detobj.colliderType = 0;
2291 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2292 colliding.Add(detobj);
2293 }
2294 }
2295
2296 }
2297 });
2298 }
2299 }
2300 if (colliding.Count > 0)
2301 { 2099 {
2302 CollidingMessage.Colliders = colliding; 2100 if (!dest.CollisionFilteredOut(this, av.UUID, av.Name))
2303 2101 colliding.Add(CreateDetObject(av));
2304 if (ParentGroup.Scene == null)
2305 return;
2306
2307 ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage);
2308 } 2102 }
2309 } 2103 }
2310 } 2104 }
2311
2312 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
2313 {
2314 if (endedColliders.Count > 0)
2315 {
2316 ColliderArgs EndCollidingMessage = new ColliderArgs();
2317 List<DetectedObject> colliding = new List<DetectedObject>();
2318 foreach (uint localId in endedColliders)
2319 {
2320 if (localId == 0)
2321 continue;
2322 2105
2323 if (ParentGroup.Scene == null) 2106 colliderArgs.Colliders = colliding;
2324 return;
2325 2107
2326 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2108 return colliderArgs;
2327 string data = ""; 2109 }
2328 if (obj != null)
2329 {
2330 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2331 {
2332 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2333 //If it is 1, it is to accept ONLY collisions from this object
2334 if (found)
2335 {
2336 DetectedObject detobj = new DetectedObject();
2337 detobj.keyUUID = obj.UUID;
2338 detobj.nameStr = obj.Name;
2339 detobj.ownerUUID = obj.OwnerID;
2340 detobj.posVector = obj.AbsolutePosition;
2341 detobj.rotQuat = obj.GetWorldRotation();
2342 detobj.velVector = obj.Velocity;
2343 detobj.colliderType = 0;
2344 detobj.groupUUID = obj.GroupID;
2345 colliding.Add(detobj);
2346 }
2347 //If it is 0, it is to not accept collisions from this object
2348 else
2349 {
2350 }
2351 }
2352 else
2353 {
2354 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2355 //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
2356 if (!found)
2357 {
2358 DetectedObject detobj = new DetectedObject();
2359 detobj.keyUUID = obj.UUID;
2360 detobj.nameStr = obj.Name;
2361 detobj.ownerUUID = obj.OwnerID;
2362 detobj.posVector = obj.AbsolutePosition;
2363 detobj.rotQuat = obj.GetWorldRotation();
2364 detobj.velVector = obj.Velocity;
2365 detobj.colliderType = 0;
2366 detobj.groupUUID = obj.GroupID;
2367 colliding.Add(detobj);
2368 }
2369 }
2370 }
2371 else
2372 {
2373 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
2374 {
2375 if (av.LocalId == localId)
2376 {
2377 if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2378 || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2379 {
2380 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2381 //If it is 1, it is to accept ONLY collisions from this avatar
2382 if (found)
2383 {
2384 DetectedObject detobj = new DetectedObject();
2385 detobj.keyUUID = av.UUID;
2386 detobj.nameStr = av.ControllingClient.Name;
2387 detobj.ownerUUID = av.UUID;
2388 detobj.posVector = av.AbsolutePosition;
2389 detobj.rotQuat = av.Rotation;
2390 detobj.velVector = av.Velocity;
2391 detobj.colliderType = 0;
2392 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2393 colliding.Add(detobj);
2394 }
2395 //If it is 0, it is to not accept collisions from this avatar
2396 else
2397 {
2398 }
2399 }
2400 else
2401 {
2402 bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2403 //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
2404 if (!found)
2405 {
2406 DetectedObject detobj = new DetectedObject();
2407 detobj.keyUUID = av.UUID;
2408 detobj.nameStr = av.ControllingClient.Name;
2409 detobj.ownerUUID = av.UUID;
2410 detobj.posVector = av.AbsolutePosition;
2411 detobj.rotQuat = av.Rotation;
2412 detobj.velVector = av.Velocity;
2413 detobj.colliderType = 0;
2414 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2415 colliding.Add(detobj);
2416 }
2417 }
2418 2110
2419 } 2111 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
2420 }); 2112
2421 } 2113 private void SendCollisionEvent(scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
2422 } 2114 {
2423 2115 bool sendToRoot = false;
2424 if (colliding.Count > 0) 2116 ColliderArgs CollidingMessage;
2425 {
2426 EndCollidingMessage.Colliders = colliding;
2427
2428 if (ParentGroup.Scene == null)
2429 return;
2430
2431 ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage);
2432 }
2433 }
2434 }
2435 2117
2436 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2118 if (colliders.Count > 0)
2437 { 2119 {
2438 if (startedColliders.Count > 0) 2120 if ((ScriptEvents & ev) != 0)
2439 { 2121 {
2440 ColliderArgs LandStartCollidingMessage = new ColliderArgs(); 2122 CollidingMessage = CreateColliderArgs(this, colliders);
2441 List<DetectedObject> colliding = new List<DetectedObject>();
2442 foreach (uint localId in startedColliders)
2443 {
2444 if (localId == 0)
2445 {
2446 //Hope that all is left is ground!
2447 DetectedObject detobj = new DetectedObject();
2448 detobj.keyUUID = UUID.Zero;
2449 detobj.nameStr = "";
2450 detobj.ownerUUID = UUID.Zero;
2451 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2452 detobj.rotQuat = Quaternion.Identity;
2453 detobj.velVector = Vector3.Zero;
2454 detobj.colliderType = 0;
2455 detobj.groupUUID = UUID.Zero;
2456 colliding.Add(detobj);
2457 }
2458 }
2459
2460 if (colliding.Count > 0)
2461 {
2462 LandStartCollidingMessage.Colliders = colliding;
2463 2123
2464 if (ParentGroup.Scene == null) 2124 if (CollidingMessage.Colliders.Count > 0)
2465 return; 2125 notify(LocalId, CollidingMessage);
2466 2126
2467 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage); 2127 if (PassCollisions)
2468 } 2128 sendToRoot = true;
2129 }
2130 else
2131 {
2132 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
2133 sendToRoot = true;
2134 }
2135 if (sendToRoot && ParentGroup.RootPart != this)
2136 {
2137 CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders);
2138 if (CollidingMessage.Colliders.Count > 0)
2139 notify(ParentGroup.RootPart.LocalId, CollidingMessage);
2469 } 2140 }
2470 } 2141 }
2142 }
2471 2143
2472 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2144 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2145 {
2146 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
2473 { 2147 {
2474 if (m_lastColliders.Count > 0) 2148 ColliderArgs LandCollidingMessage = new ColliderArgs();
2475 { 2149 List<DetectedObject> colliding = new List<DetectedObject>();
2476 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2150
2477 List<DetectedObject> colliding = new List<DetectedObject>(); 2151 colliding.Add(CreateDetObjectForGround());
2478 foreach (uint localId in startedColliders) 2152 LandCollidingMessage.Colliders = colliding;
2479 {
2480 if (localId == 0)
2481 {
2482 //Hope that all is left is ground!
2483 DetectedObject detobj = new DetectedObject();
2484 detobj.keyUUID = UUID.Zero;
2485 detobj.nameStr = "";
2486 detobj.ownerUUID = UUID.Zero;
2487 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2488 detobj.rotQuat = Quaternion.Identity;
2489 detobj.velVector = Vector3.Zero;
2490 detobj.colliderType = 0;
2491 detobj.groupUUID = UUID.Zero;
2492 colliding.Add(detobj);
2493 }
2494 }
2495 2153
2496 if (colliding.Count > 0) 2154 notify(LocalId, LandCollidingMessage);
2497 { 2155 }
2498 LandCollidingMessage.Colliders = colliding; 2156 }
2499 2157
2500 if (ParentGroup.Scene == null) 2158 public void PhysicsCollision(EventArgs e)
2501 return; 2159 {
2160 if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
2161 return;
2502 2162
2503 ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage); 2163 // single threaded here
2504 } 2164 CollisionEventUpdate a = (CollisionEventUpdate)e;
2505 } 2165 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
2166 List<uint> thisHitColliders = new List<uint>();
2167 List<uint> endedColliders = new List<uint>();
2168 List<uint> startedColliders = new List<uint>();
2169
2170 // calculate things that started colliding this time
2171 // and build up list of colliders this time
2172 foreach (uint localid in collissionswith.Keys)
2173 {
2174 thisHitColliders.Add(localid);
2175 if (!m_lastColliders.Contains(localid))
2176 startedColliders.Add(localid);
2506 } 2177 }
2507 2178
2508 if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2179 // calculate things that ended colliding
2180 foreach (uint localID in m_lastColliders)
2509 { 2181 {
2510 if (endedColliders.Count > 0) 2182 if (!thisHitColliders.Contains(localID))
2511 { 2183 endedColliders.Add(localID);
2512 ColliderArgs LandEndCollidingMessage = new ColliderArgs(); 2184 }
2513 List<DetectedObject> colliding = new List<DetectedObject>();
2514 foreach (uint localId in startedColliders)
2515 {
2516 if (localId == 0)
2517 {
2518 //Hope that all is left is ground!
2519 DetectedObject detobj = new DetectedObject();
2520 detobj.keyUUID = UUID.Zero;
2521 detobj.nameStr = "";
2522 detobj.ownerUUID = UUID.Zero;
2523 detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
2524 detobj.rotQuat = Quaternion.Identity;
2525 detobj.velVector = Vector3.Zero;
2526 detobj.colliderType = 0;
2527 detobj.groupUUID = UUID.Zero;
2528 colliding.Add(detobj);
2529 }
2530 }
2531 2185
2532 if (colliding.Count > 0) 2186 //add the items that started colliding this time to the last colliders list.
2533 { 2187 foreach (uint localID in startedColliders)
2534 LandEndCollidingMessage.Colliders = colliding; 2188 m_lastColliders.Add(localID);
2535 2189
2536 if (ParentGroup.Scene == null) 2190 // remove things that ended colliding from the last colliders list
2537 return; 2191 foreach (uint localID in endedColliders)
2192 m_lastColliders.Remove(localID);
2538 2193
2539 ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage); 2194 // play the sound.
2540 } 2195 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
2541 } 2196 SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
2197
2198 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2199 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2200 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2201
2202 if (startedColliders.Contains(0))
2203 {
2204 if (m_lastColliders.Contains(0))
2205 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2206 else
2207 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2542 } 2208 }
2209 if (endedColliders.Contains(0))
2210 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2543 } 2211 }
2544 2212
2545 public void PhysicsOutOfBounds(Vector3 pos) 2213 public void PhysicsOutOfBounds(Vector3 pos)
@@ -4328,6 +3996,12 @@ namespace OpenSim.Region.Framework.Scenes
4328 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 3996 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4329 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 3997 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4330 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 3998 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
3999 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4000 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4001 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4002 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4003 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4004 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4331 (CollisionSound != UUID.Zero) 4005 (CollisionSound != UUID.Zero)
4332 ) 4006 )
4333 { 4007 {
@@ -4652,6 +4326,12 @@ namespace OpenSim.Region.Framework.Scenes
4652 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4326 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4653 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4327 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4654 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4328 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4329 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4330 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4331 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4332 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4333 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4334 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4655 (CollisionSound != UUID.Zero) 4335 (CollisionSound != UUID.Zero)
4656 ) 4336 )
4657 { 4337 {
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