diff options
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 207 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 128 |
2 files changed, 187 insertions, 148 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index eb08257..f2850bb 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -121,8 +121,53 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
121 | /// </summary> | 121 | /// </summary> |
122 | private EntityTransferStateMachine m_entityTransferStateMachine; | 122 | private EntityTransferStateMachine m_entityTransferStateMachine; |
123 | 123 | ||
124 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | 124 | // For performance, we keed a cached of banned regions so we don't keep going |
125 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 125 | // to the grid service. |
126 | private class BannedRegionCache | ||
127 | { | ||
128 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | ||
129 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | ||
130 | ExpiringCache<ulong, DateTime> m_idCache; | ||
131 | DateTime m_banUntil; | ||
132 | public BannedRegionCache() | ||
133 | { | ||
134 | } | ||
135 | // Return 'true' if there is a valid ban entry for this agent in this region | ||
136 | public bool IfBanned(ulong pRegionHandle, UUID pAgentID) | ||
137 | { | ||
138 | bool ret = false; | ||
139 | if (m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | ||
140 | { | ||
141 | if (m_idCache.TryGetValue(pRegionHandle, out m_banUntil)) | ||
142 | { | ||
143 | if (DateTime.Now < m_banUntil) | ||
144 | { | ||
145 | ret = true; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | return ret; | ||
150 | } | ||
151 | // Add this agent in this region as a banned person | ||
152 | public void Add(ulong pRegionHandle, UUID pAgentID) | ||
153 | { | ||
154 | if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | ||
155 | { | ||
156 | m_idCache = new ExpiringCache<ulong, DateTime>(); | ||
157 | m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(45)); | ||
158 | } | ||
159 | m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | ||
160 | } | ||
161 | // Remove the agent from the region's banned list | ||
162 | public void Remove(ulong pRegionHandle, UUID pAgentID) | ||
163 | { | ||
164 | if (m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | ||
165 | { | ||
166 | m_idCache.Remove(pRegionHandle); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | private BannedRegionCache m_bannedRegionCache = new BannedRegionCache(); | ||
126 | 171 | ||
127 | private IEventQueue m_eqModule; | 172 | private IEventQueue m_eqModule; |
128 | private IRegionCombinerModule m_regionCombinerModule; | 173 | private IRegionCombinerModule m_regionCombinerModule; |
@@ -1393,7 +1438,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1393 | 1438 | ||
1394 | // Call the grid service to lookup the region containing the new position. | 1439 | // Call the grid service to lookup the region containing the new position. |
1395 | GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, | 1440 | GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, |
1396 | presenceWorldX, presenceWorldY); | 1441 | presenceWorldX, presenceWorldY, |
1442 | Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); | ||
1397 | 1443 | ||
1398 | if (neighbourRegion != null) | 1444 | if (neighbourRegion != null) |
1399 | { | 1445 | { |
@@ -1402,24 +1448,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1402 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), | 1448 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), |
1403 | pos.Z); | 1449 | pos.Z); |
1404 | 1450 | ||
1405 | // Check if banned from destination region. | 1451 | if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) |
1406 | ExpiringCache<ulong, DateTime> r; | ||
1407 | DateTime banUntil; | ||
1408 | if (m_bannedRegions.TryGetValue(agentID, out r)) | ||
1409 | { | 1452 | { |
1410 | if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil)) | 1453 | neighbourRegion = null; |
1411 | { | ||
1412 | if (DateTime.Now < banUntil) | ||
1413 | { | ||
1414 | // If we're banned from the destination, we just can't go there. | ||
1415 | neighbourRegion = null; | ||
1416 | } | ||
1417 | r.Remove(neighbourRegion.RegionHandle); | ||
1418 | } | ||
1419 | } | 1454 | } |
1420 | else | 1455 | else |
1421 | { | 1456 | { |
1422 | r = null; | 1457 | // If not banned, make sure this agent is not in the list. |
1458 | m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID); | ||
1423 | } | 1459 | } |
1424 | 1460 | ||
1425 | // Check to see if we have access to the target region. | 1461 | // Check to see if we have access to the target region. |
@@ -1427,17 +1463,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1427 | if (neighbourRegion != null | 1463 | if (neighbourRegion != null |
1428 | && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) | 1464 | && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) |
1429 | { | 1465 | { |
1430 | if (r == null) | 1466 | // remember banned |
1431 | { | 1467 | m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); |
1432 | r = new ExpiringCache<ulong, DateTime>(); | ||
1433 | r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | ||
1434 | |||
1435 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); | ||
1436 | } | ||
1437 | else | ||
1438 | { | ||
1439 | r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | ||
1440 | } | ||
1441 | neighbourRegion = null; | 1468 | neighbourRegion = null; |
1442 | } | 1469 | } |
1443 | } | 1470 | } |
@@ -1993,14 +2020,119 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1993 | 0f); | 2020 | 0f); |
1994 | } | 2021 | } |
1995 | 2022 | ||
2023 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) | ||
2024 | { | ||
2025 | // Since we don't know how big the regions could be, we have to search a very large area | ||
2026 | // to find possible regions. | ||
2027 | return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize); | ||
2028 | } | ||
2029 | |||
2030 | #region NotFoundLocationCache class | ||
2031 | // A collection of not found locations to make future lookups 'not found' lookups quick. | ||
2032 | // A simple expiring cache that keeps not found locations for some number of seconds. | ||
2033 | // A 'not found' location is presumed to be anywhere in the minimum sized region that | ||
2034 | // contains that point. A conservitive estimate. | ||
2035 | private class NotFoundLocationCache | ||
2036 | { | ||
2037 | private struct NotFoundLocation | ||
2038 | { | ||
2039 | public double minX, maxX, minY, maxY; | ||
2040 | public DateTime expireTime; | ||
2041 | } | ||
2042 | private List<NotFoundLocation> m_notFoundLocations = new List<NotFoundLocation>(); | ||
2043 | public NotFoundLocationCache() | ||
2044 | { | ||
2045 | } | ||
2046 | // Add an area to the lost of 'not found' places. The area is the snapped region | ||
2047 | // area around the added point. | ||
2048 | public void Add(double pX, double pY) | ||
2049 | { | ||
2050 | lock (m_notFoundLocations) | ||
2051 | { | ||
2052 | if (!LockedContains(pX, pY)) | ||
2053 | { | ||
2054 | NotFoundLocation nfl = new NotFoundLocation(); | ||
2055 | // A not found location is not found for at least a whole region sized area | ||
2056 | nfl.minX = pX - (pX % (double)Constants.RegionSize); | ||
2057 | nfl.minY = pY - (pY % (double)Constants.RegionSize); | ||
2058 | nfl.maxX = nfl.minX + (double)Constants.RegionSize; | ||
2059 | nfl.maxY = nfl.minY + (double)Constants.RegionSize; | ||
2060 | nfl.expireTime = DateTime.Now + TimeSpan.FromSeconds(30); | ||
2061 | m_notFoundLocations.Add(nfl); | ||
2062 | } | ||
2063 | } | ||
2064 | |||
2065 | } | ||
2066 | // Test to see of this point is in any of the 'not found' areas. | ||
2067 | // Return 'true' if the point is found inside the 'not found' areas. | ||
2068 | public bool Contains(double pX, double pY) | ||
2069 | { | ||
2070 | bool ret = false; | ||
2071 | lock (m_notFoundLocations) | ||
2072 | ret = LockedContains(pX, pY); | ||
2073 | return ret; | ||
2074 | } | ||
2075 | private bool LockedContains(double pX, double pY) | ||
2076 | { | ||
2077 | bool ret = false; | ||
2078 | this.DoExpiration(); | ||
2079 | foreach (NotFoundLocation nfl in m_notFoundLocations) | ||
2080 | { | ||
2081 | if (pX >= nfl.minX && pX < nfl.maxX && pY >= nfl.minY && pY < nfl.maxY) | ||
2082 | { | ||
2083 | ret = true; | ||
2084 | break; | ||
2085 | } | ||
2086 | } | ||
2087 | return ret; | ||
2088 | } | ||
2089 | private void DoExpiration() | ||
2090 | { | ||
2091 | List<NotFoundLocation> m_toRemove = null; | ||
2092 | DateTime now = DateTime.Now; | ||
2093 | foreach (NotFoundLocation nfl in m_notFoundLocations) | ||
2094 | { | ||
2095 | if (nfl.expireTime < now) | ||
2096 | { | ||
2097 | if (m_toRemove == null) | ||
2098 | m_toRemove = new List<NotFoundLocation>(); | ||
2099 | m_toRemove.Add(nfl); | ||
2100 | } | ||
2101 | } | ||
2102 | if (m_toRemove != null) | ||
2103 | { | ||
2104 | foreach (NotFoundLocation nfl in m_toRemove) | ||
2105 | m_notFoundLocations.Remove(nfl); | ||
2106 | m_toRemove.Clear(); | ||
2107 | } | ||
2108 | } | ||
2109 | } | ||
2110 | #endregion // NotFoundLocationCache class | ||
2111 | private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); | ||
2112 | |||
1996 | // Given a world position (fractional meter coordinate), get the GridRegion info for | 2113 | // Given a world position (fractional meter coordinate), get the GridRegion info for |
1997 | // the region containing that point. | 2114 | // the region containing that point. |
1998 | // Someday this should be a method on GridService. | 2115 | // Someday this should be a method on GridService. |
2116 | // 'pSizeHint' is the size of the source region but since the destination point can be anywhere | ||
2117 | // the size of the target region is unknown thus the search area might have to be very large. | ||
1999 | // Return 'null' if no such region exists. | 2118 | // Return 'null' if no such region exists. |
2000 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) | 2119 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, |
2120 | double px, double py, uint pSizeHint) | ||
2001 | { | 2121 | { |
2002 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py); | 2122 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py); |
2003 | GridRegion ret = null; | 2123 | GridRegion ret = null; |
2124 | const double fudge = 2.0; | ||
2125 | |||
2126 | // One problem with this routine is negative results. That is, this can be called lots of times | ||
2127 | // for regions that don't exist. m_notFoundLocationCache remembers 'not found' results so they | ||
2128 | // will be quick 'not found's next time. | ||
2129 | // NotFoundLocationCache is an expiring cache so it will eventually forget about 'not found' and | ||
2130 | // thus re-ask the GridService about the location. | ||
2131 | if (m_notFoundLocationCache.Contains(px, py)) | ||
2132 | { | ||
2133 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); | ||
2134 | return null; | ||
2135 | } | ||
2004 | 2136 | ||
2005 | // As an optimization, since most regions will be legacy sized regions (256x256), first try to get | 2137 | // As an optimization, since most regions will be legacy sized regions (256x256), first try to get |
2006 | // the region at the appropriate legacy region location. | 2138 | // the region at the appropriate legacy region location. |
@@ -2018,13 +2150,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2018 | if (ret == null) | 2150 | if (ret == null) |
2019 | { | 2151 | { |
2020 | // If the simple lookup failed, search the larger area for a region that contains this point | 2152 | // If the simple lookup failed, search the larger area for a region that contains this point |
2021 | double range = (double)Constants.RegionSize * 2 + 2; | 2153 | double range = (double)pSizeHint + fudge; |
2022 | while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) | 2154 | while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) |
2023 | { | 2155 | { |
2024 | // Get from the grid service a list of regions that might contain this point | 2156 | // Get from the grid service a list of regions that might contain this point. |
2157 | // The region origin will be in the zero direction so only subtract the range. | ||
2025 | List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID, | 2158 | List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID, |
2026 | (int)(px - range), (int)(px + range), | 2159 | (int)(px - range), (int)(px), |
2027 | (int)(py - range), (int)(py + range)); | 2160 | (int)(py - range), (int)(py)); |
2028 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}", | 2161 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}", |
2029 | LogHeader, possibleRegions.Count, range); | 2162 | LogHeader, possibleRegions.Count, range); |
2030 | if (possibleRegions != null && possibleRegions.Count > 0) | 2163 | if (possibleRegions != null && possibleRegions.Count > 0) |
@@ -2048,6 +2181,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2048 | range *= 2; | 2181 | range *= 2; |
2049 | } | 2182 | } |
2050 | } | 2183 | } |
2184 | |||
2185 | if (ret == null) | ||
2186 | { | ||
2187 | // remember this location was not found so we can quickly not find it next time | ||
2188 | m_notFoundLocationCache.Add(px, py); | ||
2189 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py); | ||
2190 | } | ||
2191 | |||
2051 | return ret; | 2192 | return ret; |
2052 | } | 2193 | } |
2053 | 2194 | ||
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4efd9d5..a98baea 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -3425,6 +3425,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3425 | if (!IsInTransit) | 3425 | if (!IsInTransit) |
3426 | { | 3426 | { |
3427 | Vector3 pos2 = AbsolutePosition; | 3427 | Vector3 pos2 = AbsolutePosition; |
3428 | Vector3 origPosition = pos2; | ||
3428 | Vector3 vel = Velocity; | 3429 | Vector3 vel = Velocity; |
3429 | int neighbor = 0; | 3430 | int neighbor = 0; |
3430 | int[] fix = new int[2]; | 3431 | int[] fix = new int[2]; |
@@ -3459,128 +3460,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
3459 | // Tried to make crossing happen but it failed. | 3460 | // Tried to make crossing happen but it failed. |
3460 | if (m_requestedSitTargetUUID == UUID.Zero) | 3461 | if (m_requestedSitTargetUUID == UUID.Zero) |
3461 | { | 3462 | { |
3462 | 3463 | m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader); | |
3463 | Vector3 pos = AbsolutePosition; | 3464 | const float borderFudge = 0.1f; |
3464 | if (AbsolutePosition.X < 0) | 3465 | |
3465 | pos.X += Velocity.X * 2; | 3466 | if (origPosition.X < 0) |
3466 | else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX) | 3467 | origPosition.X = borderFudge; |
3467 | pos.X -= Velocity.X * 2; | 3468 | else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX) |
3468 | if (AbsolutePosition.Y < 0) | 3469 | origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge; |
3469 | pos.Y += Velocity.Y * 2; | 3470 | if (origPosition.Y < 0) |
3470 | else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY) | 3471 | origPosition.Y = borderFudge; |
3471 | pos.Y -= Velocity.Y * 2; | 3472 | else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY) |
3473 | origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge; | ||
3472 | Velocity = Vector3.Zero; | 3474 | Velocity = Vector3.Zero; |
3473 | AbsolutePosition = pos; | 3475 | AbsolutePosition = origPosition; |
3474 | 3476 | ||
3475 | AddToPhysicalScene(isFlying); | 3477 | AddToPhysicalScene(isFlying); |
3476 | } | 3478 | } |
3477 | } | 3479 | } |
3478 | 3480 | ||
3479 | } | 3481 | } |
3480 | |||
3481 | /* | ||
3482 | // Checks if where it's headed exists a region | ||
3483 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) | ||
3484 | { | ||
3485 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
3486 | { | ||
3487 | needsTransit = true; | ||
3488 | neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix); | ||
3489 | } | ||
3490 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
3491 | { | ||
3492 | needsTransit = true; | ||
3493 | neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix); | ||
3494 | } | ||
3495 | else | ||
3496 | { | ||
3497 | needsTransit = true; | ||
3498 | neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix); | ||
3499 | } | ||
3500 | } | ||
3501 | else if (m_scene.TestBorderCross(pos2, Cardinals.E)) | ||
3502 | { | ||
3503 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
3504 | { | ||
3505 | needsTransit = true; | ||
3506 | neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix); | ||
3507 | } | ||
3508 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
3509 | { | ||
3510 | needsTransit = true; | ||
3511 | neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix); | ||
3512 | } | ||
3513 | else | ||
3514 | { | ||
3515 | needsTransit = true; | ||
3516 | neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix); | ||
3517 | } | ||
3518 | } | ||
3519 | else if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
3520 | { | ||
3521 | needsTransit = true; | ||
3522 | neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix); | ||
3523 | } | ||
3524 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
3525 | { | ||
3526 | needsTransit = true; | ||
3527 | neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix); | ||
3528 | } | ||
3529 | |||
3530 | // Makes sure avatar does not end up outside region | ||
3531 | if (neighbor <= 0) | ||
3532 | { | ||
3533 | if (needsTransit) | ||
3534 | { | ||
3535 | if (m_requestedSitTargetUUID == UUID.Zero) | ||
3536 | { | ||
3537 | bool isFlying = Flying; | ||
3538 | RemoveFromPhysicalScene(); | ||
3539 | |||
3540 | Vector3 pos = AbsolutePosition; | ||
3541 | if (AbsolutePosition.X < 0) | ||
3542 | pos.X += Velocity.X * 2; | ||
3543 | else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX) | ||
3544 | pos.X -= Velocity.X * 2; | ||
3545 | if (AbsolutePosition.Y < 0) | ||
3546 | pos.Y += Velocity.Y * 2; | ||
3547 | else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY) | ||
3548 | pos.Y -= Velocity.Y * 2; | ||
3549 | Velocity = Vector3.Zero; | ||
3550 | AbsolutePosition = pos; | ||
3551 | |||
3552 | // m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition); | ||
3553 | |||
3554 | AddToPhysicalScene(isFlying); | ||
3555 | } | ||
3556 | } | ||
3557 | } | ||
3558 | else if (neighbor > 0) | ||
3559 | { | ||
3560 | if (!CrossToNewRegion()) | ||
3561 | { | ||
3562 | if (m_requestedSitTargetUUID == UUID.Zero) | ||
3563 | { | ||
3564 | bool isFlying = Flying; | ||
3565 | RemoveFromPhysicalScene(); | ||
3566 | |||
3567 | Vector3 pos = AbsolutePosition; | ||
3568 | if (AbsolutePosition.X < 0) | ||
3569 | pos.X += Velocity.X * 2; | ||
3570 | else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX) | ||
3571 | pos.X -= Velocity.X * 2; | ||
3572 | if (AbsolutePosition.Y < 0) | ||
3573 | pos.Y += Velocity.Y * 2; | ||
3574 | else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY) | ||
3575 | pos.Y -= Velocity.Y * 2; | ||
3576 | Velocity = Vector3.Zero; | ||
3577 | AbsolutePosition = pos; | ||
3578 | |||
3579 | AddToPhysicalScene(isFlying); | ||
3580 | } | ||
3581 | } | ||
3582 | } | ||
3583 | */ | ||
3584 | } | 3482 | } |
3585 | else | 3483 | else |
3586 | { | 3484 | { |