aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs641
-rw-r--r--OpenSim/Region/Framework/Scenes/Border.cs150
-rw-r--r--OpenSim/Region/Framework/Scenes/Cardinals.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs354
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs101
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs312
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs10
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs6
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs13
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs249
16 files changed, 1745 insertions, 137 deletions
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index 8e85559..8831791 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -10,6 +10,7 @@
10 <Extension path = "/OpenSim/RegionModules"> 10 <Extension path = "/OpenSim/RegionModules">
11 <RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" /> 11 <RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" />
12 <RegionModule id="TerrainModule" type="OpenSim.Region.CoreModules.World.Terrain.TerrainModule" /> 12 <RegionModule id="TerrainModule" type="OpenSim.Region.CoreModules.World.Terrain.TerrainModule" />
13 <RegionModule id="RegionCombinerModule" type="OpenSim.Region.CoreModules.World.Land.RegionCombinerModule" />
13 <RegionModule id="WorldMapModule" type="OpenSim.Region.CoreModules.World.WorldMap.WorldMapModule" /> 14 <RegionModule id="WorldMapModule" type="OpenSim.Region.CoreModules.World.WorldMap.WorldMapModule" />
14 <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" /> 15 <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" />
15 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> 16 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index c917840..5c2e136 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -549,6 +549,8 @@ namespace OpenSim.Region.CoreModules.World.Land
549 int x; 549 int x;
550 int y; 550 int y;
551 551
552 if (x_float > Constants.RegionSize || x_float <= 0 || y_float > Constants.RegionSize || y_float <= 0)
553 return null;
552 try 554 try
553 { 555 {
554 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0)); 556 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0));
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs
new file mode 100644
index 0000000..381d5ec
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs
@@ -0,0 +1,641 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using log4net;
5using Nini.Config;
6using OpenMetaverse;
7using OpenSim.Framework;
8using OpenSim.Region.Framework.Interfaces;
9using OpenSim.Region.Framework.Scenes;
10
11namespace OpenSim.Region.CoreModules.World.Land
12{
13 public class RegionCombinerModule : ISharedRegionModule
14 {
15 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
16
17 public string Name { get { return "RegionCombinerModule"; } }
18 public Type ReplaceableInterface
19 {
20 get { return null; }
21 }
22
23 public Type ReplacableInterface { get { return null; } }
24
25 private Dictionary<UUID, RegionConnections> m_regions = new Dictionary<UUID, RegionConnections>();
26 private bool enabledYN = false;
27 public void Initialise(IConfigSource source)
28 {
29 IConfig myConfig = source.Configs["Startup"];
30 enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false);
31
32 }
33
34 public void Close()
35 {
36
37 }
38
39 public void AddRegion(Scene scene)
40 {
41 if (!enabledYN)
42 return;
43
44 RegionConnections regionConnections = new RegionConnections();
45 regionConnections.ConnectedRegions = new List<RegionData>();
46 regionConnections.RegionScene = scene;
47 regionConnections.RegionLandChannel = scene.LandChannel;
48 regionConnections.RegionId = scene.RegionInfo.originRegionID;
49 regionConnections.X = scene.RegionInfo.RegionLocX;
50 regionConnections.Y = scene.RegionInfo.RegionLocY;
51 regionConnections.XEnd = (int)Constants.RegionSize;
52 regionConnections.YEnd = (int)Constants.RegionSize;
53 lock (m_regions)
54 {
55 bool connectedYN = false;
56
57 foreach (RegionConnections conn in m_regions.Values)
58 {
59 #region commented
60 /*
61 // If we're one region over +x +y
62 //xxy
63 //xxx
64 //xxx
65 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd
66 == (regionConnections.X * (int)Constants.RegionSize))
67 && (((int)conn.Y * (int)Constants.RegionSize) - conn.YEnd
68 == (regionConnections.Y * (int)Constants.RegionSize)))
69 {
70 Vector3 offset = Vector3.Zero;
71 offset.X = (((regionConnections.X * (int) Constants.RegionSize)) -
72 ((conn.X * (int) Constants.RegionSize)));
73 offset.Y = (((regionConnections.Y * (int) Constants.RegionSize)) -
74 ((conn.Y * (int) Constants.RegionSize)));
75
76 Vector3 extents = Vector3.Zero;
77 extents.Y = regionConnections.YEnd + conn.YEnd;
78 extents.X = conn.XEnd + conn.XEnd;
79
80 m_log.DebugFormat("Scene: {0} to the northwest of Scene{1}. Offset: {2}. Extents:{3}",
81 conn.RegionScene.RegionInfo.RegionName,
82 regionConnections.RegionScene.RegionInfo.RegionName,
83 offset, extents);
84
85 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
86
87 connectedYN = true;
88 break;
89 }
90 */
91
92 /*
93 //If we're one region over x +y
94 //xxx
95 //xxx
96 //xyx
97 if ((((int)conn.X * (int)Constants.RegionSize)
98 == (regionConnections.X * (int)Constants.RegionSize))
99 && (((int)conn.Y * (int)Constants.RegionSize) - conn.YEnd
100 == (regionConnections.Y * (int)Constants.RegionSize)))
101 {
102 Vector3 offset = Vector3.Zero;
103 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
104 ((conn.X * (int)Constants.RegionSize)));
105 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
106 ((conn.Y * (int)Constants.RegionSize)));
107
108 Vector3 extents = Vector3.Zero;
109 extents.Y = regionConnections.YEnd + conn.YEnd;
110 extents.X = conn.XEnd;
111
112 m_log.DebugFormat("Scene: {0} to the north of Scene{1}. Offset: {2}. Extents:{3}",
113 conn.RegionScene.RegionInfo.RegionName,
114 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
115
116 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
117 connectedYN = true;
118 break;
119 }
120 */
121
122 /*
123 // If we're one region over -x +y
124 //xxx
125 //xxx
126 //yxx
127 if ((((int)conn.X * (int)Constants.RegionSize) - conn.XEnd
128 == (regionConnections.X * (int)Constants.RegionSize))
129 && (((int)conn.Y * (int)Constants.RegionSize) - conn.YEnd
130 == (regionConnections.Y * (int)Constants.RegionSize)))
131 {
132 Vector3 offset = Vector3.Zero;
133 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
134 ((conn.X * (int)Constants.RegionSize)));
135 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
136 ((conn.Y * (int)Constants.RegionSize)));
137
138 Vector3 extents = Vector3.Zero;
139 extents.Y = regionConnections.YEnd + conn.YEnd;
140 extents.X = conn.XEnd + conn.XEnd;
141
142 m_log.DebugFormat("Scene: {0} to the northeast of Scene. Offset: {2}. Extents:{3}",
143 conn.RegionScene.RegionInfo.RegionName,
144 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
145
146 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
147
148
149 connectedYN = true;
150 break;
151 }
152 */
153
154 /*
155 // If we're one region over -x y
156 //xxx
157 //yxx
158 //xxx
159 if ((((int)conn.X * (int)Constants.RegionSize) - conn.XEnd
160 == (regionConnections.X * (int)Constants.RegionSize))
161 && (((int)conn.Y * (int)Constants.RegionSize)
162 == (regionConnections.Y * (int)Constants.RegionSize)))
163 {
164 Vector3 offset = Vector3.Zero;
165 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
166 ((conn.X * (int)Constants.RegionSize)));
167 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
168 ((conn.Y * (int)Constants.RegionSize)));
169
170 Vector3 extents = Vector3.Zero;
171 extents.Y = regionConnections.YEnd;
172 extents.X = conn.XEnd + conn.XEnd;
173
174 m_log.DebugFormat("Scene: {0} to the east of Scene{1} Offset: {2}. Extents:{3}",
175 conn.RegionScene.RegionInfo.RegionName,
176 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
177
178 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
179
180 connectedYN = true;
181 break;
182 }
183 */
184
185 /*
186 // If we're one region over -x -y
187 //yxx
188 //xxx
189 //xxx
190 if ((((int)conn.X * (int)Constants.RegionSize) - conn.XEnd
191 == (regionConnections.X * (int)Constants.RegionSize))
192 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
193 == (regionConnections.Y * (int)Constants.RegionSize)))
194 {
195 Vector3 offset = Vector3.Zero;
196 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
197 ((conn.X * (int)Constants.RegionSize)));
198 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
199 ((conn.Y * (int)Constants.RegionSize)));
200
201 Vector3 extents = Vector3.Zero;
202 extents.Y = regionConnections.YEnd + conn.YEnd;
203 extents.X = conn.XEnd + conn.XEnd;
204
205 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}",
206 conn.RegionScene.RegionInfo.RegionName,
207 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
208
209 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
210
211 connectedYN = true;
212 break;
213 }
214 */
215 #endregion
216
217 // If we're one region over +x y
218 //xxx
219 //xxy
220 //xxx
221 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd
222 >= (regionConnections.X * (int)Constants.RegionSize))
223 && (((int)conn.Y * (int)Constants.RegionSize)
224 >= (regionConnections.Y * (int)Constants.RegionSize)))
225 {
226 Vector3 offset = Vector3.Zero;
227 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
228 ((conn.X * (int)Constants.RegionSize)));
229 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
230 ((conn.Y * (int)Constants.RegionSize)));
231
232 Vector3 extents = Vector3.Zero;
233 extents.Y = conn.YEnd;
234 extents.X = conn.XEnd + regionConnections.XEnd;
235
236 conn.UpdateExtents(extents);
237
238
239 m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}",
240 conn.RegionScene.RegionInfo.RegionName,
241 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
242
243
244 scene.BordersLocked = true;
245 conn.RegionScene.BordersLocked = true;
246
247 RegionData ConnectedRegion = new RegionData();
248 ConnectedRegion.Offset = offset;
249 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
250 ConnectedRegion.RegionScene = scene;
251 conn.ConnectedRegions.Add(ConnectedRegion);
252
253 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
254 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
255
256 lock (conn.RegionScene.EastBorders)
257 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
258
259 lock (conn.RegionScene.NorthBorders)
260 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
261
262 lock (conn.RegionScene.SouthBorders)
263 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
264
265 lock (scene.WestBorders)
266 scene.WestBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport West
267
268 // Reset Terrain.. since terrain normally loads first.
269 //
270 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
271 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
272
273 conn.RegionScene.BordersLocked = false;
274 scene.BordersLocked = false;
275 connectedYN = true;
276 break;
277 }
278
279
280
281 // If we're one region over x +y
282 //xyx
283 //xxx
284 //xxx
285 if ((((int)conn.X * (int)Constants.RegionSize)
286 >= (regionConnections.X * (int)Constants.RegionSize))
287 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
288 >= (regionConnections.Y * (int)Constants.RegionSize)))
289 {
290 Vector3 offset = Vector3.Zero;
291 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
292 ((conn.X * (int)Constants.RegionSize)));
293 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
294 ((conn.Y * (int)Constants.RegionSize)));
295
296 Vector3 extents = Vector3.Zero;
297 extents.Y = regionConnections.YEnd + conn.YEnd;
298 extents.X = conn.XEnd;
299 conn.UpdateExtents(extents);
300
301
302 scene.BordersLocked = true;
303 conn.RegionScene.BordersLocked = true;
304
305 RegionData ConnectedRegion = new RegionData();
306 ConnectedRegion.Offset = offset;
307 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
308 ConnectedRegion.RegionScene = scene;
309 conn.ConnectedRegions.Add(ConnectedRegion);
310
311 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}",
312 conn.RegionScene.RegionInfo.RegionName,
313 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
314 conn.RegionScene.PhysicsScene.Combine(null,Vector3.Zero,extents);
315 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
316
317 lock(conn.RegionScene.NorthBorders)
318 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
319 lock(conn.RegionScene.EastBorders)
320 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
321 lock(conn.RegionScene.WestBorders)
322 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
323 lock(scene.SouthBorders)
324 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
325
326 // Reset Terrain.. since terrain normally loads first.
327 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
328 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
329 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
330
331 scene.BordersLocked = false;
332 conn.RegionScene.BordersLocked = false;
333
334 connectedYN = true;
335 break;
336 }
337
338 // If we're one region over +x +y
339 //xxy
340 //xxx
341 //xxx
342 if ((((int)conn.X * (int)Constants.RegionSize) + conn.YEnd
343 >= (regionConnections.X * (int)Constants.RegionSize))
344 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
345 >= (regionConnections.Y * (int)Constants.RegionSize)))
346 {
347 Vector3 offset = Vector3.Zero;
348 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
349 ((conn.X * (int)Constants.RegionSize)));
350 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
351 ((conn.Y * (int)Constants.RegionSize)));
352
353 Vector3 extents = Vector3.Zero;
354 extents.Y = regionConnections.YEnd + conn.YEnd;
355 extents.X = regionConnections.XEnd + conn.XEnd;
356 conn.UpdateExtents(extents);
357
358 scene.BordersLocked = true;
359 conn.RegionScene.BordersLocked = true;
360
361 RegionData ConnectedRegion = new RegionData();
362 ConnectedRegion.Offset = offset;
363 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
364 ConnectedRegion.RegionScene = scene;
365
366 conn.ConnectedRegions.Add(ConnectedRegion);
367
368 m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}",
369 conn.RegionScene.RegionInfo.RegionName,
370 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
371
372 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
373 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
374 lock(conn.RegionScene.NorthBorders)
375 if (conn.RegionScene.NorthBorders.Count == 1)// && 2)
376 {
377 //compound border
378 // already locked above
379 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
380
381 lock(conn.RegionScene.EastBorders)
382 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
383 lock(conn.RegionScene.WestBorders)
384 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
385
386
387
388 }
389 lock(scene.SouthBorders)
390 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
391
392 lock(conn.RegionScene.EastBorders)
393 if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
394 {
395
396 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
397 lock(conn.RegionScene.NorthBorders)
398 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
399 lock(conn.RegionScene.SouthBorders)
400 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
401
402
403 }
404
405 lock (scene.WestBorders)
406 scene.WestBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport West
407/*
408 else
409 {
410 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
411 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
412 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
413 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
414 }
415*/
416
417
418 // Reset Terrain.. since terrain normally loads first.
419 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
420 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
421 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
422 scene.BordersLocked = false;
423 conn.RegionScene.BordersLocked = false;
424
425 connectedYN = true;
426
427 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents);
428
429 break;
430 }
431
432
433 }
434 if (!connectedYN)
435 {
436 RegionData rdata = new RegionData();
437 rdata.Offset = Vector3.Zero;
438 rdata.RegionId = scene.RegionInfo.originRegionID;
439 rdata.RegionScene = scene;
440 regionConnections.RegionLandChannel = scene.LandChannel;
441
442 LargeLandChannel lnd = new LargeLandChannel(rdata,scene.LandChannel,regionConnections.ConnectedRegions);
443 scene.LandChannel = lnd;
444
445 m_regions.Add(scene.RegionInfo.originRegionID,regionConnections);
446 }
447
448 }
449 }
450
451 public void RemoveRegion(Scene scene)
452 {
453
454 }
455
456 public void RegionLoaded(Scene scene)
457 {
458
459 }
460
461 public void PostInitialise()
462 {
463
464 }
465 public void OnFrame()
466 {
467
468 }
469
470
471 public RegionData GetRegionFromPosition(Vector3 pPosition)
472 {
473 pPosition = pPosition/(int) Constants.RegionSize;
474 int OffsetX = (int) pPosition.X;
475 int OffsetY = (int) pPosition.Y;
476 foreach (RegionConnections regConn in m_regions.Values)
477 {
478 foreach (RegionData reg in regConn.ConnectedRegions)
479 {
480 if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY)
481 return reg;
482 }
483 }
484 return new RegionData();
485 }
486 }
487 public class RegionConnections
488 {
489 public UUID RegionId;
490 public Scene RegionScene;
491 public ILandChannel RegionLandChannel;
492 public uint X;
493 public uint Y;
494 public int XEnd;
495 public int YEnd;
496 public List<RegionData> ConnectedRegions;
497 public void UpdateExtents(Vector3 extents)
498 {
499 XEnd = (int)extents.X;
500 YEnd = (int)extents.Y;
501 }
502
503 }
504
505 public class RegionData
506 {
507 public UUID RegionId;
508 public Scene RegionScene;
509 public Vector3 Offset;
510
511 }
512
513 public class LargeLandChannel : ILandChannel
514 {
515 private static readonly ILog m_log =
516 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
517 private RegionData RegData;
518 private ILandChannel RootRegionLandChannel;
519 private readonly List<RegionData> RegionConnections;
520
521 #region ILandChannel Members
522
523 public LargeLandChannel(RegionData regData, ILandChannel rootRegionLandChannel,List<RegionData> regionConnections)
524 {
525 RegData = regData;
526 RootRegionLandChannel = rootRegionLandChannel;
527 RegionConnections = regionConnections;
528 }
529
530 public List<ILandObject> ParcelsNearPoint(Vector3 position)
531 {
532 //m_log.DebugFormat("[LANDPARCELNEARPOINT]: {0}>", position);
533 return RootRegionLandChannel.ParcelsNearPoint(position - RegData.Offset);
534 }
535
536 public List<ILandObject> AllParcels()
537 {
538
539 return RootRegionLandChannel.AllParcels();
540
541 }
542
543 public ILandObject GetLandObject(int x, int y)
544 {
545 //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
546
547 if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
548 {
549 return RootRegionLandChannel.GetLandObject(x, y);
550 }
551 else
552 {
553 int offsetX = (x / (int)Constants.RegionSize);
554 int offsetY = (x / (int)Constants.RegionSize);
555 offsetX *= (int)Constants.RegionSize;
556 offsetY *= (int)Constants.RegionSize;
557
558 foreach (RegionData regionData in RegionConnections)
559 {
560 if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
561 {
562 return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
563 }
564 }
565 ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
566 obj.landData.Name = "NO LAND";
567 return obj;
568 }
569 }
570
571 public ILandObject GetLandObject(int localID)
572 {
573 return RootRegionLandChannel.GetLandObject(localID);
574 }
575
576 public ILandObject GetLandObject(float x, float y)
577 {
578 //m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y);
579
580 if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
581 {
582 return RootRegionLandChannel.GetLandObject(x, y);
583 }
584 else
585 {
586 int offsetX = (int)(x/(int) Constants.RegionSize);
587 int offsetY = (int)(x/(int) Constants.RegionSize);
588 offsetX *= (int) Constants.RegionSize;
589 offsetY *= (int) Constants.RegionSize;
590
591 foreach (RegionData regionData in RegionConnections)
592 {
593 if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
594 {
595 return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
596 }
597 }
598 ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
599 obj.landData.Name = "NO LAND";
600 return obj;
601 }
602 }
603
604 public bool IsLandPrimCountTainted()
605 {
606 return RootRegionLandChannel.IsLandPrimCountTainted();
607 }
608
609 public bool IsForcefulBansAllowed()
610 {
611 return RootRegionLandChannel.IsForcefulBansAllowed();
612 }
613
614 public void UpdateLandObject(int localID, LandData data)
615 {
616 RootRegionLandChannel.UpdateLandObject(localID, data);
617 }
618
619 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
620 {
621 RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
622 }
623
624 public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
625 {
626 RootRegionLandChannel.setParcelObjectMaxOverride(overrideDel);
627 }
628
629 public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
630 {
631 RootRegionLandChannel.setSimulatorObjectMaxOverride(overrideDel);
632 }
633
634 public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
635 {
636 RootRegionLandChannel.SetParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
637 }
638
639 #endregion
640 }
641}
diff --git a/OpenSim/Region/Framework/Scenes/Border.cs b/OpenSim/Region/Framework/Scenes/Border.cs
new file mode 100644
index 0000000..8f02a9c
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Border.cs
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenMetaverse;
32
33namespace OpenSim.Region.Framework.Scenes
34{
35 public class Border
36 {
37
38 /// <summary>
39 /// Line perpendicular to the Direction Cardinal. Z value is the
40 /// </summary>
41 public Vector3 BorderLine = Vector3.Zero;
42
43 /// <summary>
44 /// Direction cardinal of the border, think, 'which side of the region this is'. EX South border: Cardinal.S
45 /// </summary>
46 public Cardinals CrossDirection = Cardinals.N;
47 public uint TriggerRegionX = 0;
48 public uint TriggerRegionY = 0;
49
50 public Border()
51 {
52 }
53
54 /// <summary>
55 /// Creates a Border. The line is perpendicular to the direction cardinal.
56 /// IE: if the direction cardinal is South, the line is West->East
57 /// </summary>
58 /// <param name="lineStart">The starting point for the line of the border.
59 /// The position of an object must be greater then this for this border to trigger.
60 /// Perpendicular to the direction cardinal</param>
61 /// <param name="lineEnd">The ending point for the line of the border.
62 /// The position of an object must be less then this for this border to trigger.
63 /// Perpendicular to the direction cardinal</param>
64 /// <param name="triggerCoordinate">The position that triggers border the border
65 /// cross parallel to the direction cardinal. On the North cardinal, this
66 /// normally 256. On the South cardinal, it's normally 0. Any position past this
67 /// point on the cartesian coordinate will trigger the border cross as long as it
68 /// falls within the line start and the line end.</param>
69 /// <param name="triggerRegionX">When this border triggers, teleport to this regionX
70 /// in the grid</param>
71 /// <param name="triggerRegionY">When this border triggers, teleport to this regionY
72 /// in the grid</param>
73 /// <param name="direction">Cardinal for border direction. Think, 'which side of the
74 /// region is this'</param>
75 public Border(float lineStart, float lineEnd, float triggerCoordinate, uint triggerRegionX,
76 uint triggerRegionY, Cardinals direction)
77 {
78 BorderLine = new Vector3(lineStart,lineEnd,triggerCoordinate);
79 CrossDirection = direction;
80 TriggerRegionX = triggerRegionX;
81 TriggerRegionY = triggerRegionY;
82 }
83
84 public bool TestCross(Vector3 position)
85 {
86 bool result = false;
87 switch (CrossDirection)
88 {
89 case Cardinals.N: // x+0, y+1
90 if (position.X >= BorderLine.X && position.X <=BorderLine.Y && position.Y > BorderLine.Z )
91 {
92 return true;
93 }
94 break;
95 case Cardinals.NE: // x+1, y+1
96 break;
97 case Cardinals.E: // x+1, y+0
98 if (position.Y >= BorderLine.X && position.Y <= BorderLine.Y && position.X > BorderLine.Z)
99 {
100 return true;
101 }
102 break;
103 case Cardinals.SE: // x+1, y-1
104 break;
105 case Cardinals.S: // x+0, y-1
106 if (position.X >= BorderLine.X && position.X <= BorderLine.Y && position.Y-1 < BorderLine.Z)
107 {
108 return true;
109 }
110 break;
111 case Cardinals.SW: // x-1, y-1
112 break;
113 case Cardinals.W: // x-1, y+0
114 if (position.Y >= BorderLine.X && position.Y <= BorderLine.Y && position.X-1 < BorderLine.Z)
115 {
116 return true;
117 }
118 break;
119 case Cardinals.NW: // x-1, y+1
120 break;
121
122
123 }
124
125 return result;
126 }
127
128 public float Extent
129 {
130 get
131 {
132 switch (CrossDirection)
133 {
134 case Cardinals.N:
135 break;
136 case Cardinals.S:
137 break;
138 case Cardinals.W:
139 break;
140 case Cardinals.E:
141 break;
142 }
143 return 0;
144 }
145 }
146
147 }
148
149
150}
diff --git a/OpenSim/Region/Framework/Scenes/Cardinals.cs b/OpenSim/Region/Framework/Scenes/Cardinals.cs
new file mode 100644
index 0000000..692389a
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Cardinals.cs
@@ -0,0 +1,11 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace OpenSim.Region.Framework.Scenes
6{
7 public enum Cardinals
8 {
9 N = 1, NE, E, SE, S, SW, W, NW
10 }
11}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 6118a70..3e573cf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -81,6 +81,13 @@ namespace OpenSim.Region.Framework.Scenes
81 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 81 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
82 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 82 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
83 83
84 public volatile bool BordersLocked = false;
85
86 public List<Border> NorthBorders = new List<Border>();
87 public List<Border> EastBorders = new List<Border>();
88 public List<Border> SouthBorders = new List<Border>();
89 public List<Border> WestBorders = new List<Border>();
90
84 /// <value> 91 /// <value>
85 /// The scene graph for this scene 92 /// The scene graph for this scene
86 /// </value> 93 /// </value>
@@ -326,6 +333,31 @@ namespace OpenSim.Region.Framework.Scenes
326 m_config = config; 333 m_config = config;
327 334
328 Random random = new Random(); 335 Random random = new Random();
336
337 BordersLocked = true;
338
339 Border northBorder = new Border();
340 northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
341 northBorder.CrossDirection = Cardinals.N;
342 NorthBorders.Add(northBorder);
343
344 Border southBorder = new Border();
345 southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
346 southBorder.CrossDirection = Cardinals.S;
347 SouthBorders.Add(southBorder);
348
349 Border eastBorder = new Border();
350 eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
351 eastBorder.CrossDirection = Cardinals.E;
352 EastBorders.Add(eastBorder);
353
354 Border westBorder = new Border();
355 westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
356 westBorder.CrossDirection = Cardinals.W;
357 WestBorders.Add(westBorder);
358
359 BordersLocked = false;
360
329 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); 361 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
330 m_moduleLoader = moduleLoader; 362 m_moduleLoader = moduleLoader;
331 m_authenticateHandler = authen; 363 m_authenticateHandler = authen;
@@ -455,6 +487,28 @@ namespace OpenSim.Region.Framework.Scenes
455 /// <param name="regInfo"></param> 487 /// <param name="regInfo"></param>
456 public Scene(RegionInfo regInfo) 488 public Scene(RegionInfo regInfo)
457 { 489 {
490 BordersLocked = true;
491 Border northBorder = new Border();
492 northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
493 northBorder.CrossDirection = Cardinals.N;
494 NorthBorders.Add(northBorder);
495
496 Border southBorder = new Border();
497 southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
498 southBorder.CrossDirection = Cardinals.S;
499 SouthBorders.Add(southBorder);
500
501 Border eastBorder = new Border();
502 eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
503 eastBorder.CrossDirection = Cardinals.E;
504 EastBorders.Add(eastBorder);
505
506 Border westBorder = new Border();
507 westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
508 westBorder.CrossDirection = Cardinals.W;
509 WestBorders.Add(westBorder);
510 BordersLocked = false;
511
458 m_regInfo = regInfo; 512 m_regInfo = regInfo;
459 m_eventManager = new EventManager(); 513 m_eventManager = new EventManager();
460 } 514 }
@@ -1659,35 +1713,86 @@ namespace OpenSim.Region.Framework.Scenes
1659 ulong newRegionHandle = 0; 1713 ulong newRegionHandle = 0;
1660 Vector3 pos = attemptedPosition; 1714 Vector3 pos = attemptedPosition;
1661 1715
1662 if (attemptedPosition.X > Constants.RegionSize + 0.1f) 1716 if (TestBorderCross(attemptedPosition, Cardinals.W))
1663 { 1717 {
1664 pos.X = ((pos.X - Constants.RegionSize)); 1718 if (TestBorderCross(attemptedPosition, Cardinals.S))
1665 newRegionHandle 1719 {
1666 = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize)); 1720 //Border crossedBorderx = GetCrossedBorder(attemptedPosition,Cardinals.W);
1667 // x + 1 1721 //Border crossedBordery = GetCrossedBorder(attemptedPosition, Cardinals.S);
1722 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
1723 pos.X = ((pos.X + Constants.RegionSize));
1724 pos.Y = ((pos.Y + Constants.RegionSize));
1725 newRegionHandle
1726 = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize),
1727 (uint)((thisy - 1) * Constants.RegionSize));
1728 // x - 1
1729 // y - 1
1730 }
1731 else if (TestBorderCross(attemptedPosition, Cardinals.N))
1732 {
1733 pos.X = ((pos.X + Constants.RegionSize));
1734 pos.Y = ((pos.Y - Constants.RegionSize));
1735 newRegionHandle
1736 = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize),
1737 (uint)((thisy + 1) * Constants.RegionSize));
1738 // x - 1
1739 // y + 1
1740 }
1741 else
1742 {
1743 pos.X = ((pos.X + Constants.RegionSize));
1744 newRegionHandle
1745 = Util.UIntsToLong((uint) ((thisx - 1)*Constants.RegionSize),
1746 (uint) (thisy*Constants.RegionSize));
1747 // x - 1
1748 }
1668 } 1749 }
1669 else if (attemptedPosition.X < -0.1f) 1750 else if (TestBorderCross(attemptedPosition, Cardinals.E))
1751 {
1752 if (TestBorderCross(attemptedPosition, Cardinals.S))
1753 {
1754 pos.X = ((pos.X - Constants.RegionSize));
1755 pos.Y = ((pos.Y + Constants.RegionSize));
1756 newRegionHandle
1757 = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize),
1758 (uint)((thisy - 1) * Constants.RegionSize));
1759 // x + 1
1760 // y - 1
1761 }
1762 else if (TestBorderCross(attemptedPosition, Cardinals.N))
1763 {
1764 pos.X = ((pos.X - Constants.RegionSize));
1765 pos.Y = ((pos.Y - Constants.RegionSize));
1766 newRegionHandle
1767 = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize),
1768 (uint)((thisy + 1) * Constants.RegionSize));
1769 // x + 1
1770 // y + 1
1771 }
1772 else
1773 {
1774 pos.X = ((pos.X - Constants.RegionSize));
1775 newRegionHandle
1776 = Util.UIntsToLong((uint) ((thisx + 1)*Constants.RegionSize),
1777 (uint) (thisy*Constants.RegionSize));
1778 // x + 1
1779 }
1780 }
1781 else if (TestBorderCross(attemptedPosition, Cardinals.S))
1670 { 1782 {
1671 pos.X = ((pos.X + Constants.RegionSize)); 1783 pos.Y = ((pos.Y + Constants.RegionSize));
1672 newRegionHandle 1784 newRegionHandle
1673 = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize)); 1785 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
1674 // x - 1 1786 // y - 1
1675 } 1787 }
1676 1788 else if (TestBorderCross(attemptedPosition, Cardinals.N))
1677 if (attemptedPosition.Y > Constants.RegionSize + 0.1f)
1678 { 1789 {
1790
1679 pos.Y = ((pos.Y - Constants.RegionSize)); 1791 pos.Y = ((pos.Y - Constants.RegionSize));
1680 newRegionHandle 1792 newRegionHandle
1681 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize)); 1793 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize));
1682 // y + 1 1794 // y + 1
1683 } 1795 }
1684 else if (attemptedPosition.Y < -0.1f)
1685 {
1686 pos.Y = ((pos.Y + Constants.RegionSize));
1687 newRegionHandle
1688 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
1689 // y - 1
1690 }
1691 1796
1692 // Offset the positions for the new region across the border 1797 // Offset the positions for the new region across the border
1693 Vector3 oldGroupPosition = grp.RootPart.GroupPosition; 1798 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
@@ -1701,6 +1806,186 @@ namespace OpenSim.Region.Framework.Scenes
1701 } 1806 }
1702 } 1807 }
1703 1808
1809 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
1810 {
1811 if (BordersLocked)
1812 {
1813 switch (gridline)
1814 {
1815 case Cardinals.N:
1816 lock (NorthBorders)
1817 {
1818 foreach (Border b in NorthBorders)
1819 {
1820 if (b.TestCross(position))
1821 return b;
1822 }
1823 }
1824 break;
1825 case Cardinals.S:
1826 lock (SouthBorders)
1827 {
1828 foreach (Border b in SouthBorders)
1829 {
1830 if (b.TestCross(position))
1831 return b;
1832 }
1833 }
1834
1835 break;
1836 case Cardinals.E:
1837 lock (EastBorders)
1838 {
1839 foreach (Border b in EastBorders)
1840 {
1841 if (b.TestCross(position))
1842 return b;
1843 }
1844 }
1845
1846 break;
1847 case Cardinals.W:
1848
1849 lock (WestBorders)
1850 {
1851 foreach (Border b in WestBorders)
1852 {
1853 if (b.TestCross(position))
1854 return b;
1855 }
1856 }
1857 break;
1858
1859 }
1860 }
1861 else
1862 {
1863 switch (gridline)
1864 {
1865 case Cardinals.N:
1866 foreach (Border b in NorthBorders)
1867 {
1868 if (b.TestCross(position))
1869 return b;
1870 }
1871
1872 break;
1873 case Cardinals.S:
1874 foreach (Border b in SouthBorders)
1875 {
1876 if (b.TestCross(position))
1877 return b;
1878 }
1879 break;
1880 case Cardinals.E:
1881 foreach (Border b in EastBorders)
1882 {
1883 if (b.TestCross(position))
1884 return b;
1885 }
1886
1887 break;
1888 case Cardinals.W:
1889 foreach (Border b in WestBorders)
1890 {
1891 if (b.TestCross(position))
1892 return b;
1893 }
1894 break;
1895
1896 }
1897 }
1898
1899
1900 return null;
1901 }
1902
1903 public bool TestBorderCross(Vector3 position, Cardinals border)
1904 {
1905 if (BordersLocked)
1906 {
1907 switch (border)
1908 {
1909 case Cardinals.N:
1910 lock (NorthBorders)
1911 {
1912 foreach (Border b in NorthBorders)
1913 {
1914 if (b.TestCross(position))
1915 return true;
1916 }
1917 }
1918 break;
1919 case Cardinals.E:
1920 lock (EastBorders)
1921 {
1922 foreach (Border b in EastBorders)
1923 {
1924 if (b.TestCross(position))
1925 return true;
1926 }
1927 }
1928 break;
1929 case Cardinals.S:
1930 lock (SouthBorders)
1931 {
1932 foreach (Border b in SouthBorders)
1933 {
1934 if (b.TestCross(position))
1935 return true;
1936 }
1937 }
1938 break;
1939 case Cardinals.W:
1940 lock (WestBorders)
1941 {
1942 foreach (Border b in WestBorders)
1943 {
1944 if (b.TestCross(position))
1945 return true;
1946 }
1947 }
1948 break;
1949 }
1950 }
1951 else
1952 {
1953 switch (border)
1954 {
1955 case Cardinals.N:
1956 foreach (Border b in NorthBorders)
1957 {
1958 if (b.TestCross(position))
1959 return true;
1960 }
1961 break;
1962 case Cardinals.E:
1963 foreach (Border b in EastBorders)
1964 {
1965 if (b.TestCross(position))
1966 return true;
1967 }
1968 break;
1969 case Cardinals.S:
1970 foreach (Border b in SouthBorders)
1971 {
1972 if (b.TestCross(position))
1973 return true;
1974 }
1975 break;
1976 case Cardinals.W:
1977 foreach (Border b in WestBorders)
1978 {
1979 if (b.TestCross(position))
1980 return true;
1981 }
1982 break;
1983 }
1984 }
1985 return false;
1986 }
1987
1988
1704 /// <summary> 1989 /// <summary>
1705 /// Move the given scene object into a new region 1990 /// Move the given scene object into a new region
1706 /// </summary> 1991 /// </summary>
@@ -3063,16 +3348,47 @@ namespace OpenSim.Region.Framework.Scenes
3063 3348
3064 if (sp != null) 3349 if (sp != null)
3065 { 3350 {
3351 uint regionX = m_regInfo.RegionLocX;
3352 uint regionY = m_regInfo.RegionLocY;
3353
3354 Utils.LongToUInts(regionHandle, out regionX, out regionY);
3355
3356 int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize;
3357 int shifty = (int)regionY - (int)m_regInfo.RegionLocY * (int)Constants.RegionSize;
3358
3359 position.X += shiftx;
3360 position.Y += shifty;
3361
3362 bool result = false;
3363
3364 if (TestBorderCross(position,Cardinals.N))
3365 result = true;
3366
3367 if (TestBorderCross(position, Cardinals.S))
3368 result = true;
3369
3370 if (TestBorderCross(position, Cardinals.E))
3371 result = true;
3372
3373 if (TestBorderCross(position, Cardinals.W))
3374 result = true;
3375
3376 // bordercross if position is outside of region
3377
3378 if (!result)
3379 regionHandle = m_regInfo.RegionHandle;
3380
3066 if (m_teleportModule != null) 3381 if (m_teleportModule != null)
3067 { 3382 {
3068 m_teleportModule.RequestTeleportToLocation(sp, regionHandle, 3383 m_teleportModule.RequestTeleportToLocation(sp, regionHandle,
3069 position, lookAt, teleportFlags); 3384 position, lookAt, teleportFlags);
3070 } 3385 }
3071 else 3386 else
3072 { 3387 {
3073 m_sceneGridService.RequestTeleportToLocation(sp, regionHandle, 3388 m_sceneGridService.RequestTeleportToLocation(sp, regionHandle,
3074 position, lookAt, teleportFlags); 3389 position, lookAt, teleportFlags);
3075 } 3390 }
3391
3076 } 3392 }
3077 } 3393 }
3078 3394
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 65c97e8..1673a22 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -803,11 +803,11 @@ namespace OpenSim.Region.Framework.Scenes
803 if (regionHandle == m_regionInfo.RegionHandle) 803 if (regionHandle == m_regionInfo.RegionHandle)
804 { 804 {
805 m_log.DebugFormat( 805 m_log.DebugFormat(
806 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", 806 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}",
807 position, m_regionInfo.RegionName); 807 position, m_regionInfo.RegionName);
808 808
809 // Teleport within the same region 809 // Teleport within the same region
810 if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) 810 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
811 { 811 {
812 Vector3 emergencyPos = new Vector3(128, 128, 128); 812 Vector3 emergencyPos = new Vector3(128, 128, 128);
813 813
@@ -816,10 +816,17 @@ namespace OpenSim.Region.Framework.Scenes
816 position, avatar.Name, avatar.UUID, emergencyPos); 816 position, avatar.Name, avatar.UUID, emergencyPos);
817 position = emergencyPos; 817 position = emergencyPos;
818 } 818 }
819 819
820 // TODO: Get proper AVG Height 820 // TODO: Get proper AVG Height
821 float localAVHeight = 1.56f; 821 float localAVHeight = 1.56f;
822 float posZLimit = (float)avatar.Scene.Heightmap[(int)position.X, (int)position.Y]; 822 float posZLimit = 22;
823
824 // TODO: Check other Scene HeightField
825 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <=(int)Constants.RegionSize)
826 {
827 posZLimit = (float) avatar.Scene.Heightmap[(int) position.X, (int) position.Y];
828 }
829
823 float newPosZ = posZLimit + localAVHeight; 830 float newPosZ = posZLimit + localAVHeight;
824 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 831 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
825 { 832 {
@@ -1084,6 +1091,21 @@ namespace OpenSim.Region.Framework.Scenes
1084 } 1091 }
1085 } 1092 }
1086 1093
1094 private bool IsOutsideRegion(Scene s, Vector3 pos)
1095 {
1096
1097 if (s.TestBorderCross(pos,Cardinals.N))
1098 return true;
1099 if (s.TestBorderCross(pos, Cardinals.S))
1100 return true;
1101 if (s.TestBorderCross(pos, Cardinals.E))
1102 return true;
1103 if (s.TestBorderCross(pos, Cardinals.W))
1104 return true;
1105
1106 return false;
1107 }
1108
1087 public bool WaitForCallback(UUID id) 1109 public bool WaitForCallback(UUID id)
1088 { 1110 {
1089 int count = 200; 1111 int count = 200;
@@ -1158,34 +1180,91 @@ namespace OpenSim.Region.Framework.Scenes
1158 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1180 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1159 uint neighbourx = m_regionInfo.RegionLocX; 1181 uint neighbourx = m_regionInfo.RegionLocX;
1160 uint neighboury = m_regionInfo.RegionLocY; 1182 uint neighboury = m_regionInfo.RegionLocY;
1183 const float boundaryDistance = 1.7f;
1184 Vector3 northCross = new Vector3(0, boundaryDistance, 0);
1185 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
1186 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
1187 Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0);
1161 1188
1162 // distance to edge that will trigger crossing 1189 // distance to edge that will trigger crossing
1163 const float boundaryDistance = 1.7f; 1190
1164 1191
1165 // distance into new region to place avatar 1192 // distance into new region to place avatar
1166 const float enterDistance = 0.1f; 1193 const float enterDistance = 0.5f;
1194
1195 if (scene.TestBorderCross(pos + westCross, Cardinals.W))
1196 {
1197 if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1198 {
1199 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1200 neighboury += (uint)(int)(b.BorderLine.Z/(int)Constants.RegionSize);
1201 }
1202 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1203 {
1204 neighboury--;
1205 newpos.Y = Constants.RegionSize - enterDistance;
1206 }
1207
1208 neighbourx--;
1209 newpos.X = Constants.RegionSize - enterDistance;
1210
1211 }
1212 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1213 {
1214 Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
1215 neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1216 newpos.X = enterDistance;
1217
1218 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1219 {
1220 neighboury--;
1221 newpos.Y = Constants.RegionSize - enterDistance;
1222 }
1223 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1224 {
1225 Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1226 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
1227 newpos.Y = enterDistance;
1228 }
1229
1230
1231 }
1232 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1233 {
1234 neighboury--;
1235 newpos.Y = Constants.RegionSize - enterDistance;
1236 }
1237 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1238 {
1239 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1240 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1241 newpos.Y = enterDistance;
1242 }
1243
1244 /*
1167 1245
1168 if (pos.X < boundaryDistance) 1246 if (pos.X < boundaryDistance) //West
1169 { 1247 {
1170 neighbourx--; 1248 neighbourx--;
1171 newpos.X = Constants.RegionSize - enterDistance; 1249 newpos.X = Constants.RegionSize - enterDistance;
1172 } 1250 }
1173 else if (pos.X > Constants.RegionSize - boundaryDistance) 1251 else if (pos.X > Constants.RegionSize - boundaryDistance) // East
1174 { 1252 {
1175 neighbourx++; 1253 neighbourx++;
1176 newpos.X = enterDistance; 1254 newpos.X = enterDistance;
1177 } 1255 }
1178 1256
1179 if (pos.Y < boundaryDistance) 1257 if (pos.Y < boundaryDistance) // South
1180 { 1258 {
1181 neighboury--; 1259 neighboury--;
1182 newpos.Y = Constants.RegionSize - enterDistance; 1260 newpos.Y = Constants.RegionSize - enterDistance;
1183 } 1261 }
1184 else if (pos.Y > Constants.RegionSize - boundaryDistance) 1262 else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
1185 { 1263 {
1186 neighboury++; 1264 neighboury++;
1187 newpos.Y = enterDistance; 1265 newpos.Y = enterDistance;
1188 } 1266 }
1267 */
1189 1268
1190 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1269 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1191 d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d); 1270 d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 1b541c4..e5c6bf1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -264,7 +264,9 @@ namespace OpenSim.Region.Framework.Scenes
264 { 264 {
265 Vector3 val = value; 265 Vector3 val = value;
266 266
267 if ((val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) && !IsAttachment) 267 if ((m_scene.TestBorderCross(val,Cardinals.E) || m_scene.TestBorderCross(val,Cardinals.W)
268 || m_scene.TestBorderCross(val, Cardinals.N) || m_scene.TestBorderCross(val, Cardinals.S))
269 && !IsAttachment)
268 { 270 {
269 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 271 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
270 } 272 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cf716e8..40e7471 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2097,7 +2097,8 @@ if (m_shape != null) {
2097 if (PhysActor != null) 2097 if (PhysActor != null)
2098 { 2098 {
2099 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2099 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2100 if (newpos.X > 257f || newpos.X < -1f || newpos.Y > 257f || newpos.Y < -1f) 2100
2101 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2101 { 2102 {
2102 m_parentGroup.AbsolutePosition = newpos; 2103 m_parentGroup.AbsolutePosition = newpos;
2103 return; 2104 return;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ff97183..46e3289 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -222,10 +222,7 @@ namespace OpenSim.Region.Framework.Scenes
222 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 222 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
223 } 223 }
224 224
225 protected enum Cardinals 225
226 {
227 N=1,NE,E,SE,S,SW,W,NW
228 }
229 /// <summary> 226 /// <summary>
230 /// Position at which a significant movement was made 227 /// Position at which a significant movement was made
231 /// </summary> 228 /// </summary>
@@ -2833,29 +2830,31 @@ namespace OpenSim.Region.Framework.Scenes
2833 if (!IsInTransit) 2830 if (!IsInTransit)
2834 { 2831 {
2835 // Checks if where it's headed exists a region 2832 // Checks if where it's headed exists a region
2836 if (pos2.X < 0) 2833
2834 if (m_scene.TestBorderCross(pos2, Cardinals.W))
2837 { 2835 {
2838 if (pos2.Y < 0) 2836 if (m_scene.TestBorderCross(pos2, Cardinals.S))
2839 neighbor = HaveNeighbor(Cardinals.SW, ref fix); 2837 neighbor = HaveNeighbor(Cardinals.SW, ref fix);
2840 else if (pos2.Y > Constants.RegionSize) 2838 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
2841 neighbor = HaveNeighbor(Cardinals.NW, ref fix); 2839 neighbor = HaveNeighbor(Cardinals.NW, ref fix);
2842 else 2840 else
2843 neighbor = HaveNeighbor(Cardinals.W, ref fix); 2841 neighbor = HaveNeighbor(Cardinals.W, ref fix);
2844 } 2842 }
2845 else if (pos2.X > Constants.RegionSize) 2843 else if (m_scene.TestBorderCross(pos2, Cardinals.E))
2846 { 2844 {
2847 if (pos2.Y < 0) 2845 if (m_scene.TestBorderCross(pos2, Cardinals.S))
2848 neighbor = HaveNeighbor(Cardinals.SE, ref fix); 2846 neighbor = HaveNeighbor(Cardinals.SE, ref fix);
2849 else if (pos2.Y > Constants.RegionSize) 2847 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
2850 neighbor = HaveNeighbor(Cardinals.NE, ref fix); 2848 neighbor = HaveNeighbor(Cardinals.NE, ref fix);
2851 else 2849 else
2852 neighbor = HaveNeighbor(Cardinals.E, ref fix); 2850 neighbor = HaveNeighbor(Cardinals.E, ref fix);
2853 } 2851 }
2854 else if (pos2.Y < 0) 2852 else if (m_scene.TestBorderCross(pos2, Cardinals.S))
2855 neighbor = HaveNeighbor(Cardinals.S, ref fix); 2853 neighbor = HaveNeighbor(Cardinals.S, ref fix);
2856 else if (pos2.Y > Constants.RegionSize) 2854 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
2857 neighbor = HaveNeighbor(Cardinals.N, ref fix); 2855 neighbor = HaveNeighbor(Cardinals.N, ref fix);
2858 2856
2857
2859 // Makes sure avatar does not end up outside region 2858 // Makes sure avatar does not end up outside region
2860 if (neighbor < 0) 2859 if (neighbor < 0)
2861 AbsolutePosition = new Vector3( 2860 AbsolutePosition = new Vector3(
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
new file mode 100644
index 0000000..272c96e
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -0,0 +1,312 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenMetaverse;
5using OpenSim.Region.Framework.Scenes;
6
7using NUnit.Framework;
8
9namespace OpenSim.Region.Framework.Scenes.Tests
10{
11 [TestFixture]
12 public class BorderTests
13 {
14
15 [Test]
16 public void TestCross()
17 {
18 List<Border> testborders = new List<Border>();
19
20 Border NorthBorder = new Border();
21 NorthBorder.BorderLine = new Vector3(0, 256, 256); //<---
22 NorthBorder.CrossDirection = Cardinals.N;
23 testborders.Add(NorthBorder);
24
25 Border SouthBorder = new Border();
26 SouthBorder.BorderLine = new Vector3(0, 256, 0); //--->
27 SouthBorder.CrossDirection = Cardinals.S;
28 testborders.Add(SouthBorder);
29
30 Border EastBorder = new Border();
31 EastBorder.BorderLine = new Vector3(0, 256, 256); //<---
32 EastBorder.CrossDirection = Cardinals.E;
33 testborders.Add(EastBorder);
34
35 Border WestBorder = new Border();
36 WestBorder.BorderLine = new Vector3(0, 256, 0); //--->
37 WestBorder.CrossDirection = Cardinals.W;
38 testborders.Add(WestBorder);
39
40 Vector3 position = new Vector3(200,200,21);
41
42 foreach (Border b in testborders)
43 {
44 Assert.That(!b.TestCross(position));
45
46 }
47
48 position = new Vector3(200,280,21);
49 Assert.That(NorthBorder.TestCross(position));
50
51
52
53 // Test automatic border crossing
54 // by setting the border crossing aabb to be the whole region
55 position = new Vector3(25,25,21); // safely within one 256m region
56
57 // The Z value of the BorderLine is reversed, making all positions within the region
58 // trigger bordercross
59
60 SouthBorder.BorderLine = new Vector3(0,256,256); // automatic border cross in the region
61 Assert.That(SouthBorder.TestCross(position));
62
63 NorthBorder.BorderLine = new Vector3(0, 256, 0); // automatic border cross in the region
64 Assert.That(NorthBorder.TestCross(position));
65
66 EastBorder.BorderLine = new Vector3(0, 256, 0); // automatic border cross in the region
67 Assert.That(EastBorder.TestCross(position));
68
69 WestBorder.BorderLine = new Vector3(0, 256, 255); // automatic border cross in the region
70 Assert.That(WestBorder.TestCross(position));
71
72 }
73
74 [Test]
75 public void TestCrossSquare512()
76 {
77 List<Border> testborders = new List<Border>();
78
79 Border NorthBorder = new Border();
80 NorthBorder.BorderLine = new Vector3(0, 512, 512);
81 NorthBorder.CrossDirection = Cardinals.N;
82 testborders.Add(NorthBorder);
83
84 Border SouthBorder = new Border();
85 SouthBorder.BorderLine = new Vector3(0, 512, 0);
86 SouthBorder.CrossDirection = Cardinals.S;
87 testborders.Add(SouthBorder);
88
89 Border EastBorder = new Border();
90 EastBorder.BorderLine = new Vector3(0, 512, 512);
91 EastBorder.CrossDirection = Cardinals.E;
92 testborders.Add(EastBorder);
93
94 Border WestBorder = new Border();
95 WestBorder.BorderLine = new Vector3(0, 512, 0);
96 WestBorder.CrossDirection = Cardinals.W;
97 testborders.Add(WestBorder);
98
99 Vector3 position = new Vector3(450,220,21);
100
101 foreach (Border b in testborders)
102 {
103 Assert.That(!b.TestCross(position));
104
105 }
106
107 //Trigger east border
108 position = new Vector3(513,220,21);
109 foreach (Border b in testborders)
110 {
111 if (b.CrossDirection == Cardinals.E)
112 Assert.That(b.TestCross(position));
113 else
114 Assert.That(!b.TestCross(position));
115
116 }
117
118 //Trigger west border
119 position = new Vector3(-1, 220, 21);
120 foreach (Border b in testborders)
121 {
122 if (b.CrossDirection == Cardinals.W)
123 Assert.That(b.TestCross(position));
124 else
125 Assert.That(!b.TestCross(position));
126
127 }
128
129 //Trigger north border
130 position = new Vector3(220, 513, 21);
131 foreach (Border b in testborders)
132 {
133 if (b.CrossDirection == Cardinals.N)
134 Assert.That(b.TestCross(position));
135 else
136 Assert.That(!b.TestCross(position));
137
138 }
139
140 //Trigger south border
141 position = new Vector3(220, -1, 21);
142 foreach (Border b in testborders)
143 {
144 if (b.CrossDirection == Cardinals.S)
145 Assert.That(b.TestCross(position));
146 else
147 Assert.That(!b.TestCross(position));
148
149 }
150
151 }
152
153 [Test]
154 public void TestCrossRectangle512x256()
155 {
156 List<Border> testborders = new List<Border>();
157
158 Border NorthBorder = new Border();
159 NorthBorder.BorderLine = new Vector3(0, 512, 256);
160 NorthBorder.CrossDirection = Cardinals.N;
161 testborders.Add(NorthBorder);
162
163 Border SouthBorder = new Border();
164 SouthBorder.BorderLine = new Vector3(0, 512, 0);
165 SouthBorder.CrossDirection = Cardinals.S;
166 testborders.Add(SouthBorder);
167
168 Border EastBorder = new Border();
169 EastBorder.BorderLine = new Vector3(0, 256, 512);
170 EastBorder.CrossDirection = Cardinals.E;
171 testborders.Add(EastBorder);
172
173 Border WestBorder = new Border();
174 WestBorder.BorderLine = new Vector3(0, 256, 0);
175 WestBorder.CrossDirection = Cardinals.W;
176 testborders.Add(WestBorder);
177
178 Vector3 position = new Vector3(450, 220, 21);
179
180 foreach (Border b in testborders)
181 {
182 Assert.That(!b.TestCross(position));
183
184 }
185
186 //Trigger east border
187 position = new Vector3(513, 220, 21);
188 foreach (Border b in testborders)
189 {
190 if (b.CrossDirection == Cardinals.E)
191 Assert.That(b.TestCross(position));
192 else
193 Assert.That(!b.TestCross(position));
194
195 }
196
197 //Trigger west border
198 position = new Vector3(-1, 220, 21);
199 foreach (Border b in testborders)
200 {
201 if (b.CrossDirection == Cardinals.W)
202 Assert.That(b.TestCross(position));
203 else
204 Assert.That(!b.TestCross(position));
205
206 }
207
208 //Trigger north border
209 position = new Vector3(220, 257, 21);
210 foreach (Border b in testborders)
211 {
212 if (b.CrossDirection == Cardinals.N)
213 Assert.That(b.TestCross(position));
214 else
215 Assert.That(!b.TestCross(position));
216
217 }
218
219 //Trigger south border
220 position = new Vector3(220, -1, 21);
221 foreach (Border b in testborders)
222 {
223 if (b.CrossDirection == Cardinals.S)
224 Assert.That(b.TestCross(position));
225 else
226 Assert.That(!b.TestCross(position));
227
228 }
229 }
230
231 [Test]
232 public void TestCrossOdd512x512w256hole()
233 {
234 List<Border> testborders = new List<Border>();
235 // 512____
236 // | |
237 // 256__| |___
238 // | |
239 // |______|
240 // 0 | 512
241 // 256
242
243 // Compound North border since the hole is at the top
244 Border NorthBorder1 = new Border();
245 NorthBorder1.BorderLine = new Vector3(0, 256, 512);
246 NorthBorder1.CrossDirection = Cardinals.N;
247 testborders.Add(NorthBorder1);
248
249 Border NorthBorder2 = new Border();
250 NorthBorder2.BorderLine = new Vector3(256, 512, 256);
251 NorthBorder2.CrossDirection = Cardinals.N;
252 testborders.Add(NorthBorder2);
253
254 Border SouthBorder = new Border();
255 SouthBorder.BorderLine = new Vector3(0, 512, 0);
256 SouthBorder.CrossDirection = Cardinals.S;
257 testborders.Add(SouthBorder);
258
259 //Compound East border
260 Border EastBorder1 = new Border();
261 EastBorder1.BorderLine = new Vector3(0, 256, 512);
262 EastBorder1.CrossDirection = Cardinals.E;
263 testborders.Add(EastBorder1);
264
265 Border EastBorder2 = new Border();
266 EastBorder2.BorderLine = new Vector3(257, 512, 256);
267 EastBorder2.CrossDirection = Cardinals.E;
268 testborders.Add(EastBorder2);
269
270
271
272 Border WestBorder = new Border();
273 WestBorder.BorderLine = new Vector3(0, 512, 0);
274 WestBorder.CrossDirection = Cardinals.W;
275 testborders.Add(WestBorder);
276
277 Vector3 position = new Vector3(450, 220, 21);
278
279 foreach (Border b in testborders)
280 {
281 Assert.That(!b.TestCross(position));
282
283 }
284
285 position = new Vector3(220, 450, 21);
286
287 foreach (Border b in testborders)
288 {
289 Assert.That(!b.TestCross(position));
290
291 }
292
293 bool result = false;
294 int bordersTriggered = 0;
295
296 position = new Vector3(450, 450, 21);
297
298 foreach (Border b in testborders)
299 {
300 if (b.TestCross(position))
301 {
302 bordersTriggered++;
303 result = true;
304 }
305 }
306
307 Assert.That(result);
308 Assert.That(bordersTriggered == 2);
309
310 }
311 }
312}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 6937a25..5c46344 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -162,6 +162,16 @@ namespace OpenSim.Region.Physics.Manager
162 return false; 162 return false;
163 } 163 }
164 164
165 public virtual bool SupportsCombining()
166 {
167 return false;
168 }
169
170 public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
171 {
172 return;
173 }
174
165 /// <summary> 175 /// <summary>
166 /// Queue a raycast against the physics scene. 176 /// Queue a raycast against the physics scene.
167 /// The provided callback method will be called when the raycast is complete 177 /// The provided callback method will be called when the raycast is complete
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index d192018..38df751 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -161,7 +161,7 @@ namespace OpenSim.Region.Physics.OdePlugin
161 } 161 }
162 else 162 else
163 { 163 {
164 _position = new PhysicsVector(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), parent_scene.GetTerrainHeightAtXY(128, 128) + 10); 164 _position = new PhysicsVector(((int)_parent_scene.WorldExtents.X * 0.5f), ((int)_parent_scene.WorldExtents.Y * 0.5f), parent_scene.GetTerrainHeightAtXY(128, 128) + 10);
165 m_taintPosition.X = _position.X; 165 m_taintPosition.X = _position.X;
166 m_taintPosition.Y = _position.Y; 166 m_taintPosition.Y = _position.Y;
167 m_taintPosition.Z = _position.Z; 167 m_taintPosition.Z = _position.Z;
@@ -1092,8 +1092,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1092 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) 1092 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
1093 if (vec.X < 0.0f) vec.X = 0.0f; 1093 if (vec.X < 0.0f) vec.X = 0.0f;
1094 if (vec.Y < 0.0f) vec.Y = 0.0f; 1094 if (vec.Y < 0.0f) vec.Y = 0.0f;
1095 if (vec.X > (int)Constants.RegionSize - 0.05f) vec.X = (int)Constants.RegionSize - 0.05f; 1095 if (vec.X > (int)_parent_scene.WorldExtents.X - 0.05f) vec.X = (int)_parent_scene.WorldExtents.X - 0.05f;
1096 if (vec.Y > (int)Constants.RegionSize - 0.05f) vec.Y = (int)Constants.RegionSize - 0.05f; 1096 if (vec.Y > (int)_parent_scene.WorldExtents.Y - 0.05f) vec.Y = (int)_parent_scene.WorldExtents.Y - 0.05f;
1097 1097
1098 _position.X = vec.X; 1098 _position.X = vec.X;
1099 _position.Y = vec.Y; 1099 _position.Y = vec.Y;
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 443788c..d0f77e6 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -2538,7 +2538,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2538 l_orientation.Z = ori.Z; 2538 l_orientation.Z = ori.Z;
2539 l_orientation.W = ori.W; 2539 l_orientation.W = ori.W;
2540 2540
2541 if (l_position.X > ((int)Constants.RegionSize - 0.05f) || l_position.X < 0f || l_position.Y > ((int)Constants.RegionSize - 0.05f) || l_position.Y < 0f) 2541 if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
2542 { 2542 {
2543 //base.RaiseOutOfBounds(l_position); 2543 //base.RaiseOutOfBounds(l_position);
2544 2544
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index c4cb250..d9f4951 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -232,17 +232,12 @@ namespace OpenSim.Region.Physics.OdePlugin
232 */ 232 */
233 233
234 // Exclude heightfield geom 234 // Exclude heightfield geom
235 if (g1 == m_scene.LandGeom) 235
236 return; 236 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
237 if (g2 == m_scene.LandGeom)
238 return;
239 if (g1 == m_scene.WaterGeom)
240 return; 237 return;
241 if (g2 == m_scene.WaterGeom) 238 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
242 return; 239 return;
243 240
244
245
246 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. 241 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
247 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) 242 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
248 { 243 {
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index b7030f1..817cc22 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -227,13 +227,11 @@ namespace OpenSim.Region.Physics.OdePlugin
227 227
228 public int bodyFramesAutoDisable = 20; 228 public int bodyFramesAutoDisable = 20;
229 229
230 private float[] _heightmap; 230
231 231
232 private float[] _watermap; 232 private float[] _watermap;
233 private bool m_filterCollisions = true; 233 private bool m_filterCollisions = true;
234 234
235 private float[] _origheightmap; // Used for Fly height. Kitto Flora
236
237 private d.NearCallback nearCallback; 235 private d.NearCallback nearCallback;
238 public d.TriCallback triCallback; 236 public d.TriCallback triCallback;
239 public d.TriArrayCallback triArrayCallback; 237 public d.TriArrayCallback triArrayCallback;
@@ -257,6 +255,8 @@ namespace OpenSim.Region.Physics.OdePlugin
257 private Object externalJointRequestsLock = new Object(); 255 private Object externalJointRequestsLock = new Object();
258 private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>(); 256 private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>();
259 private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>(); 257 private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>();
258 private readonly DoubleDictionary<Vector3, IntPtr, IntPtr> RegionTerrain = new DoubleDictionary<Vector3, IntPtr, IntPtr>();
259 private readonly Dictionary<IntPtr,float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>();
260 260
261 private d.Contact contact; 261 private d.Contact contact;
262 private d.Contact TerrainContact; 262 private d.Contact TerrainContact;
@@ -311,6 +311,10 @@ namespace OpenSim.Region.Physics.OdePlugin
311 311
312 private volatile int m_global_contactcount = 0; 312 private volatile int m_global_contactcount = 0;
313 313
314 private Vector3 m_worldOffset = Vector3.Zero;
315 public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize);
316 private PhysicsScene m_parentScene = null;
317
314 private ODERayCastRequestManager m_rayCastManager; 318 private ODERayCastRequestManager m_rayCastManager;
315 319
316 /// <summary> 320 /// <summary>
@@ -347,11 +351,7 @@ namespace OpenSim.Region.Physics.OdePlugin
347 #endif 351 #endif
348 } 352 }
349 353
350 // zero out a heightmap array float array (single dimension [flattened])) 354
351 if ((int)Constants.RegionSize == 256)
352 _heightmap = new float[514*514];
353 else
354 _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))];
355 _watermap = new float[258 * 258]; 355 _watermap = new float[258 * 258];
356 356
357 // Zero out the prim spaces array (we split our space into smaller spaces so 357 // Zero out the prim spaces array (we split our space into smaller spaces so
@@ -1556,28 +1556,65 @@ namespace OpenSim.Region.Physics.OdePlugin
1556 } 1556 }
1557 1557
1558 #endregion 1558 #endregion
1559 1559
1560 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
1561 {
1562 m_worldOffset = offset;
1563 WorldExtents = new Vector2(extents.X, extents.Y);
1564 m_parentScene = pScene;
1565
1566 }
1560// Recovered for use by fly height. Kitto Flora 1567// Recovered for use by fly height. Kitto Flora
1561 public float GetTerrainHeightAtXY(float x, float y) 1568 public float GetTerrainHeightAtXY(float x, float y)
1562 { 1569 {
1563 1570
1564 int index; 1571 int offsetX = ((int) (x/256)) * 256;
1572 int offsetY = ((int) (y/256)) * 256;
1565 1573
1566 // Teravus: Kitto, this code causes recurring errors that stall physics permenantly unless 1574 IntPtr heightFieldGeom = IntPtr.Zero;
1567 // the values are checked, so checking below.
1568 // Is there any reason that we don't do this in ScenePresence?
1569 // The only physics engine that benefits from it in the physics plugin is this one
1570 1575
1571 if ((int)x > Constants.RegionSize || (int)y > Constants.RegionSize || 1576 if (RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom))
1572 (int)x < 0.001f || (int)y < 0.001f) 1577 {
1573 return 0; 1578 if (heightFieldGeom != IntPtr.Zero)
1579 {
1580 if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
1581 {
1582
1583 int index;
1584
1585
1586 if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y ||
1587 (int)x < 0.001f || (int)y < 0.001f)
1588 return 0;
1574 1589
1575 index = (int) ((int)y * Constants.RegionSize + (int)x); 1590 x = x - offsetX;
1591 y = y - offsetY;
1576 1592
1577 if (index < _origheightmap.Length) 1593 index = (int)((int)y * (int)Constants.RegionSize + (int)x);
1578 return (float)_origheightmap[(int)y * Constants.RegionSize + (int)x]; 1594
1595 if (index < TerrainHeightFieldHeights[heightFieldGeom].Length)
1596 return (float)TerrainHeightFieldHeights[heightFieldGeom][(int)y * (int)Constants.RegionSize + (int)x];
1597 else
1598 return 0f;
1599 }
1600 else
1601 {
1602 return 0f;
1603 }
1604
1605 }
1606 else
1607 {
1608 return 0f;
1609 }
1610
1611 }
1579 else 1612 else
1580 return 0; 1613 {
1614 return 0f;
1615 }
1616
1617
1581 } 1618 }
1582// End recovered. Kitto Flora 1619// End recovered. Kitto Flora
1583 1620
@@ -1646,6 +1683,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1646 private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, 1683 private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
1647 IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) 1684 IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
1648 { 1685 {
1686
1649 PhysicsVector pos = new PhysicsVector(position.X, position.Y, position.Z); 1687 PhysicsVector pos = new PhysicsVector(position.X, position.Y, position.Z);
1650 //pos.X = position.X; 1688 //pos.X = position.X;
1651 //pos.Y = position.Y; 1689 //pos.Y = position.Y;
@@ -2548,6 +2586,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2548 if (framecount >= int.MaxValue) 2586 if (framecount >= int.MaxValue)
2549 framecount = 0; 2587 framecount = 0;
2550 2588
2589 //if (m_worldOffset != Vector3.Zero)
2590 // return 0;
2591
2551 framecount++; 2592 framecount++;
2552 2593
2553 float fps = 0; 2594 float fps = 0;
@@ -3006,14 +3047,14 @@ namespace OpenSim.Region.Physics.OdePlugin
3006 public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) 3047 public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
3007 { 3048 {
3008 float[] returnarr = new float[262144]; 3049 float[] returnarr = new float[262144];
3009 float[,] resultarr = new float[m_regionWidth, m_regionHeight]; 3050 float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y];
3010 3051
3011 // Filling out the array into its multi-dimensional components 3052 // Filling out the array into its multi-dimensional components
3012 for (int y = 0; y < m_regionHeight; y++) 3053 for (int y = 0; y < WorldExtents.Y; y++)
3013 { 3054 {
3014 for (int x = 0; x < m_regionWidth; x++) 3055 for (int x = 0; x < WorldExtents.X; x++)
3015 { 3056 {
3016 resultarr[y, x] = heightMap[y * m_regionWidth + x]; 3057 resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x];
3017 } 3058 }
3018 } 3059 }
3019 3060
@@ -3077,21 +3118,21 @@ namespace OpenSim.Region.Physics.OdePlugin
3077 // on single loop. 3118 // on single loop.
3078 3119
3079 float[,] resultarr2 = new float[512, 512]; 3120 float[,] resultarr2 = new float[512, 512];
3080 for (int y = 0; y < m_regionHeight; y++) 3121 for (int y = 0; y < WorldExtents.Y; y++)
3081 { 3122 {
3082 for (int x = 0; x < m_regionWidth; x++) 3123 for (int x = 0; x < WorldExtents.X; x++)
3083 { 3124 {
3084 resultarr2[y * 2, x * 2] = resultarr[y, x]; 3125 resultarr2[y * 2, x * 2] = resultarr[y, x];
3085 3126
3086 if (y < m_regionHeight) 3127 if (y < WorldExtents.Y)
3087 { 3128 {
3088 resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x]; 3129 resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x];
3089 } 3130 }
3090 if (x < m_regionWidth) 3131 if (x < WorldExtents.X)
3091 { 3132 {
3092 resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x]; 3133 resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x];
3093 } 3134 }
3094 if (x < m_regionWidth && y < m_regionHeight) 3135 if (x < WorldExtents.X && y < WorldExtents.Y)
3095 { 3136 {
3096 resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x]; 3137 resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x];
3097 } 3138 }
@@ -3119,14 +3160,14 @@ namespace OpenSim.Region.Physics.OdePlugin
3119 public float[] ResizeTerrain512Interpolation(float[] heightMap) 3160 public float[] ResizeTerrain512Interpolation(float[] heightMap)
3120 { 3161 {
3121 float[] returnarr = new float[262144]; 3162 float[] returnarr = new float[262144];
3122 float[,] resultarr = new float[m_regionWidth,m_regionHeight]; 3163 float[,] resultarr = new float[512,512];
3123 3164
3124 // Filling out the array into its multi-dimensional components 3165 // Filling out the array into its multi-dimensional components
3125 for (int y = 0; y < m_regionHeight; y++) 3166 for (int y = 0; y < 256; y++)
3126 { 3167 {
3127 for (int x = 0; x < m_regionWidth; x++) 3168 for (int x = 0; x < 256; x++)
3128 { 3169 {
3129 resultarr[y, x] = heightMap[y*m_regionWidth + x]; 3170 resultarr[y, x] = heightMap[y * 256 + x];
3130 } 3171 }
3131 } 3172 }
3132 3173
@@ -3190,17 +3231,17 @@ namespace OpenSim.Region.Physics.OdePlugin
3190 // on single loop. 3231 // on single loop.
3191 3232
3192 float[,] resultarr2 = new float[512,512]; 3233 float[,] resultarr2 = new float[512,512];
3193 for (int y = 0; y < m_regionHeight; y++) 3234 for (int y = 0; y < (int)Constants.RegionSize; y++)
3194 { 3235 {
3195 for (int x = 0; x < m_regionWidth; x++) 3236 for (int x = 0; x < (int)Constants.RegionSize; x++)
3196 { 3237 {
3197 resultarr2[y*2, x*2] = resultarr[y, x]; 3238 resultarr2[y*2, x*2] = resultarr[y, x];
3198 3239
3199 if (y < m_regionHeight) 3240 if (y < (int)Constants.RegionSize)
3200 { 3241 {
3201 if (y + 1 < m_regionHeight) 3242 if (y + 1 < (int)Constants.RegionSize)
3202 { 3243 {
3203 if (x + 1 < m_regionWidth) 3244 if (x + 1 < (int)Constants.RegionSize)
3204 { 3245 {
3205 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] + 3246 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
3206 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); 3247 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
@@ -3215,11 +3256,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3215 resultarr2[(y*2) + 1, x*2] = resultarr[y, x]; 3256 resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
3216 } 3257 }
3217 } 3258 }
3218 if (x < m_regionWidth) 3259 if (x < (int)Constants.RegionSize)
3219 { 3260 {
3220 if (x + 1 < m_regionWidth) 3261 if (x + 1 < (int)Constants.RegionSize)
3221 { 3262 {
3222 if (y + 1 < m_regionHeight) 3263 if (y + 1 < (int)Constants.RegionSize)
3223 { 3264 {
3224 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + 3265 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
3225 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); 3266 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
@@ -3234,9 +3275,9 @@ namespace OpenSim.Region.Physics.OdePlugin
3234 resultarr2[y*2, (x*2) + 1] = resultarr[y, x]; 3275 resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
3235 } 3276 }
3236 } 3277 }
3237 if (x < m_regionWidth && y < m_regionHeight) 3278 if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
3238 { 3279 {
3239 if ((x + 1 < m_regionWidth) && (y + 1 < m_regionHeight)) 3280 if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize))
3240 { 3281 {
3241 resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + 3282 resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
3242 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); 3283 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
@@ -3271,41 +3312,68 @@ namespace OpenSim.Region.Physics.OdePlugin
3271 3312
3272 public override void SetTerrain(float[] heightMap) 3313 public override void SetTerrain(float[] heightMap)
3273 { 3314 {
3274 // this._heightmap[i] = (double)heightMap[i]; 3315 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
3275 // dbm (danx0r) -- creating a buffer zone of one extra sample all around
3276 _origheightmap = heightMap; // Used for Fly height. Kitto Flora
3277 uint heightmapWidth = m_regionWidth + 1;
3278 uint heightmapHeight = m_regionHeight + 1;
3279
3280 uint heightmapWidthSamples;
3281
3282 uint heightmapHeightSamples;
3283 if (((int)Constants.RegionSize) == 256)
3284 { 3316 {
3285 heightmapWidthSamples = 2*m_regionWidth + 2; 3317 if (m_parentScene is OdeScene)
3286 heightmapHeightSamples = 2*m_regionHeight + 2; 3318 {
3287 heightmapWidth++; 3319 ((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset);
3288 heightmapHeight++; 3320 }
3289 } 3321 }
3290 else 3322 else
3291 { 3323 {
3292 heightmapWidthSamples = m_regionWidth + 1; 3324 SetTerrain(heightMap, m_worldOffset);
3293 heightmapHeightSamples = m_regionHeight + 1;
3294 } 3325 }
3326 }
3327
3328 public void SetTerrain(float[] heightMap, Vector3 pOffset)
3329 {
3330 // this._heightmap[i] = (double)heightMap[i];
3331 // dbm (danx0r) -- creating a buffer zone of one extra sample all around
3332 //_origheightmap = heightMap;
3333
3334 float[] _heightmap;
3335
3336 // zero out a heightmap array float array (single dimension [flattened]))
3337 //if ((int)Constants.RegionSize == 256)
3338 // _heightmap = new float[514 * 514];
3339 //else
3340
3341 _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))];
3342
3343 uint heightmapWidth = Constants.RegionSize + 1;
3344 uint heightmapHeight = Constants.RegionSize + 1;
3345
3346 uint heightmapWidthSamples;
3347
3348 uint heightmapHeightSamples;
3349
3350 //if (((int)Constants.RegionSize) == 256)
3351 //{
3352 // heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2;
3353 // heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2;
3354 // heightmapWidth++;
3355 // heightmapHeight++;
3356 //}
3357 //else
3358 //{
3359
3360 heightmapWidthSamples = (uint)Constants.RegionSize + 1;
3361 heightmapHeightSamples = (uint)Constants.RegionSize + 1;
3362 //}
3295 3363
3296 const float scale = 1.0f; 3364 const float scale = 1.0f;
3297 const float offset = 0.0f; 3365 const float offset = 0.0f;
3298 const float thickness = 0.2f; 3366 const float thickness = 0.2f;
3299 const int wrap = 0; 3367 const int wrap = 0;
3300
3301 3368
3369 int regionsize = (int) Constants.RegionSize;
3302 //Double resolution 3370 //Double resolution
3303 if (((int)Constants.RegionSize) == 256) 3371 //if (((int)Constants.RegionSize) == 256)
3304 heightMap = ResizeTerrain512Interpolation(heightMap); 3372 // heightMap = ResizeTerrain512Interpolation(heightMap);
3305 3373
3306 int regionsize = (int)Constants.RegionSize; 3374
3307 if (regionsize == 256) 3375 // if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256)
3308 regionsize = 512; 3376 // regionsize = 512;
3309 3377
3310 float hfmin = 2000; 3378 float hfmin = 2000;
3311 float hfmax = -2000; 3379 float hfmax = -2000;
@@ -3316,8 +3384,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3316 int xx = Util.Clip(x - 1, 0, regionsize - 1); 3384 int xx = Util.Clip(x - 1, 0, regionsize - 1);
3317 int yy = Util.Clip(y - 1, 0, regionsize - 1); 3385 int yy = Util.Clip(y - 1, 0, regionsize - 1);
3318 3386
3319 float val = heightMap[yy*regionsize + xx]; 3387 float val = heightMap[yy * regionsize + xx];
3320 _heightmap[x*heightmapHeightSamples + y] = val; 3388 _heightmap[x * heightmapHeightSamples + y] = val;
3321 hfmin = (val < hfmin) ? val : hfmin; 3389 hfmin = (val < hfmin) ? val : hfmin;
3322 hfmax = (val > hfmax) ? val : hfmax; 3390 hfmax = (val > hfmax) ? val : hfmax;
3323 } 3391 }
@@ -3325,23 +3393,34 @@ namespace OpenSim.Region.Physics.OdePlugin
3325 3393
3326 lock (OdeLock) 3394 lock (OdeLock)
3327 { 3395 {
3328 if (LandGeom != IntPtr.Zero) 3396 IntPtr GroundGeom = IntPtr.Zero;
3397 if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
3329 { 3398 {
3330 d.SpaceRemove(space, LandGeom); 3399 RegionTerrain.Remove(pOffset);
3400 if (GroundGeom != IntPtr.Zero)
3401 {
3402 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
3403 {
3404 TerrainHeightFieldHeights.Remove(GroundGeom);
3405 }
3406 d.SpaceRemove(space, GroundGeom);
3407 d.GeomDestroy(GroundGeom);
3408 }
3409
3331 } 3410 }
3332 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 3411 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
3333 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight, 3412 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight,
3334 (int) heightmapWidthSamples, (int) heightmapHeightSamples, scale, 3413 (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
3335 offset, thickness, wrap); 3414 offset, thickness, wrap);
3336 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1 , hfmax + 1); 3415 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
3337 LandGeom = d.CreateHeightfield(space, HeightmapData, 1); 3416 GroundGeom = d.CreateHeightfield(space, HeightmapData, 1);
3338 if (LandGeom != IntPtr.Zero) 3417 if (GroundGeom != IntPtr.Zero)
3339 { 3418 {
3340 d.GeomSetCategoryBits(LandGeom, (int)(CollisionCategories.Land)); 3419 d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
3341 d.GeomSetCollideBits(LandGeom, (int)(CollisionCategories.Space)); 3420 d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
3342 3421
3343 } 3422 }
3344 geom_name_map[LandGeom] = "Terrain"; 3423 geom_name_map[GroundGeom] = "Terrain";
3345 3424
3346 d.Matrix3 R = new d.Matrix3(); 3425 d.Matrix3 R = new d.Matrix3();
3347 3426
@@ -3349,15 +3428,23 @@ namespace OpenSim.Region.Physics.OdePlugin
3349 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); 3428 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
3350 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); 3429 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
3351 3430
3352 q1 = q1*q2; 3431 q1 = q1 * q2;
3353 //q1 = q1 * q3; 3432 //q1 = q1 * q3;
3354 Vector3 v3; 3433 Vector3 v3;
3355 float angle; 3434 float angle;
3356 q1.GetAxisAngle(out v3, out angle); 3435 q1.GetAxisAngle(out v3, out angle);
3357 3436
3358 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 3437 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
3359 d.GeomSetRotation(LandGeom, ref R); 3438 d.GeomSetRotation(GroundGeom, ref R);
3360 d.GeomSetPosition(LandGeom, (int)Constants.RegionSize * 0.5f, (int)Constants.RegionSize * 0.5f, 0); 3439 d.GeomSetPosition(GroundGeom, pOffset.X + ((int)Constants.RegionSize * 0.5f), pOffset.Y + ((int)Constants.RegionSize * 0.5f), 0);
3440 IntPtr testGround = IntPtr.Zero;
3441 if (RegionTerrain.TryGetValue(pOffset, out testGround))
3442 {
3443 RegionTerrain.Remove(pOffset);
3444 }
3445 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
3446 TerrainHeightFieldHeights.Add(GroundGeom,_heightmap);
3447
3361 } 3448 }
3362 } 3449 }
3363 3450
@@ -3370,6 +3457,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3370 return waterlevel; 3457 return waterlevel;
3371 } 3458 }
3372 3459
3460
3461
3373 public override void SetWaterLevel(float baseheight) 3462 public override void SetWaterLevel(float baseheight)
3374 { 3463 {
3375 waterlevel = baseheight; 3464 waterlevel = baseheight;