diff options
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 | ||