aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs')
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs969
1 files changed, 969 insertions, 0 deletions
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
new file mode 100644
index 0000000..7ec1d4b
--- /dev/null
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -0,0 +1,969 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Framework.Client;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Framework.Console;
39using OpenSim.Region.Physics.Manager;
40using Mono.Addins;
41
42[assembly: Addin("RegionCombinerModule", "0.1")]
43[assembly: AddinDependency("OpenSim", "0.5")]
44namespace OpenSim.Region.RegionCombinerModule
45{
46
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
48 public class RegionCombinerModule : ISharedRegionModule
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 public string Name
53 {
54 get { return "RegionCombinerModule"; }
55 }
56
57 public Type ReplaceableInterface
58 {
59 get { return null; }
60 }
61
62 private Dictionary<UUID, RegionConnections> m_regions = new Dictionary<UUID, RegionConnections>();
63 private bool enabledYN = false;
64 private Dictionary<UUID, Scene> m_startingScenes = new Dictionary<UUID, Scene>();
65
66 public void Initialise(IConfigSource source)
67 {
68 IConfig myConfig = source.Configs["Startup"];
69 enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false);
70 //enabledYN = true;
71 if (enabledYN)
72 MainConsole.Instance.Commands.AddCommand("RegionCombinerModule", false, "fix-phantoms",
73 "Fix phantom objects", "Fixes phantom objects after an import to megaregions", FixPhantoms);
74 }
75
76 public void Close()
77 {
78 }
79
80 public void AddRegion(Scene scene)
81 {
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86 }
87
88 public void RegionLoaded(Scene scene)
89 {
90 if (enabledYN)
91 RegionLoadedDoWork(scene);
92 }
93
94 private void RegionLoadedDoWork(Scene scene)
95 {
96/*
97 // For testing on a single instance
98 if (scene.RegionInfo.RegionLocX == 1004 && scene.RegionInfo.RegionLocY == 1000)
99 return;
100 //
101*/
102 lock (m_startingScenes)
103 m_startingScenes.Add(scene.RegionInfo.originRegionID, scene);
104
105 // Give each region a standard set of non-infinite borders
106 Border northBorder = new Border();
107 northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
108 northBorder.CrossDirection = Cardinals.N;
109 scene.NorthBorders[0] = northBorder;
110
111 Border southBorder = new Border();
112 southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
113 southBorder.CrossDirection = Cardinals.S;
114 scene.SouthBorders[0] = southBorder;
115
116 Border eastBorder = new Border();
117 eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
118 eastBorder.CrossDirection = Cardinals.E;
119 scene.EastBorders[0] = eastBorder;
120
121 Border westBorder = new Border();
122 westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
123 westBorder.CrossDirection = Cardinals.W;
124 scene.WestBorders[0] = westBorder;
125
126
127
128 RegionConnections regionConnections = new RegionConnections();
129 regionConnections.ConnectedRegions = new List<RegionData>();
130 regionConnections.RegionScene = scene;
131 regionConnections.RegionLandChannel = scene.LandChannel;
132 regionConnections.RegionId = scene.RegionInfo.originRegionID;
133 regionConnections.X = scene.RegionInfo.RegionLocX;
134 regionConnections.Y = scene.RegionInfo.RegionLocY;
135 regionConnections.XEnd = (int)Constants.RegionSize;
136 regionConnections.YEnd = (int)Constants.RegionSize;
137
138
139 lock (m_regions)
140 {
141 bool connectedYN = false;
142
143 foreach (RegionConnections conn in m_regions.Values)
144 {
145 #region commented
146 /*
147 // If we're one region over +x +y
148 //xxy
149 //xxx
150 //xxx
151 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd
152 == (regionConnections.X * (int)Constants.RegionSize))
153 && (((int)conn.Y * (int)Constants.RegionSize) - conn.YEnd
154 == (regionConnections.Y * (int)Constants.RegionSize)))
155 {
156 Vector3 offset = Vector3.Zero;
157 offset.X = (((regionConnections.X * (int) Constants.RegionSize)) -
158 ((conn.X * (int) Constants.RegionSize)));
159 offset.Y = (((regionConnections.Y * (int) Constants.RegionSize)) -
160 ((conn.Y * (int) Constants.RegionSize)));
161
162 Vector3 extents = Vector3.Zero;
163 extents.Y = regionConnections.YEnd + conn.YEnd;
164 extents.X = conn.XEnd + conn.XEnd;
165
166 m_log.DebugFormat("Scene: {0} to the northwest of Scene{1}. Offset: {2}. Extents:{3}",
167 conn.RegionScene.RegionInfo.RegionName,
168 regionConnections.RegionScene.RegionInfo.RegionName,
169 offset, extents);
170
171 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
172
173 connectedYN = true;
174 break;
175 }
176 */
177
178 /*
179 //If we're one region over x +y
180 //xxx
181 //xxx
182 //xyx
183 if ((((int)conn.X * (int)Constants.RegionSize)
184 == (regionConnections.X * (int)Constants.RegionSize))
185 && (((int)conn.Y * (int)Constants.RegionSize) - conn.YEnd
186 == (regionConnections.Y * (int)Constants.RegionSize)))
187 {
188 Vector3 offset = Vector3.Zero;
189 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
190 ((conn.X * (int)Constants.RegionSize)));
191 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
192 ((conn.Y * (int)Constants.RegionSize)));
193
194 Vector3 extents = Vector3.Zero;
195 extents.Y = regionConnections.YEnd + conn.YEnd;
196 extents.X = conn.XEnd;
197
198 m_log.DebugFormat("Scene: {0} to the north of Scene{1}. Offset: {2}. Extents:{3}",
199 conn.RegionScene.RegionInfo.RegionName,
200 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
201
202 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
203 connectedYN = true;
204 break;
205 }
206 */
207
208 /*
209 // If we're one region over -x +y
210 //xxx
211 //xxx
212 //yxx
213 if ((((int)conn.X * (int)Constants.RegionSize) - conn.XEnd
214 == (regionConnections.X * (int)Constants.RegionSize))
215 && (((int)conn.Y * (int)Constants.RegionSize) - conn.YEnd
216 == (regionConnections.Y * (int)Constants.RegionSize)))
217 {
218 Vector3 offset = Vector3.Zero;
219 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
220 ((conn.X * (int)Constants.RegionSize)));
221 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
222 ((conn.Y * (int)Constants.RegionSize)));
223
224 Vector3 extents = Vector3.Zero;
225 extents.Y = regionConnections.YEnd + conn.YEnd;
226 extents.X = conn.XEnd + conn.XEnd;
227
228 m_log.DebugFormat("Scene: {0} to the northeast of Scene. Offset: {2}. Extents:{3}",
229 conn.RegionScene.RegionInfo.RegionName,
230 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
231
232 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
233
234
235 connectedYN = true;
236 break;
237 }
238 */
239
240 /*
241 // If we're one region over -x y
242 //xxx
243 //yxx
244 //xxx
245 if ((((int)conn.X * (int)Constants.RegionSize) - conn.XEnd
246 == (regionConnections.X * (int)Constants.RegionSize))
247 && (((int)conn.Y * (int)Constants.RegionSize)
248 == (regionConnections.Y * (int)Constants.RegionSize)))
249 {
250 Vector3 offset = Vector3.Zero;
251 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
252 ((conn.X * (int)Constants.RegionSize)));
253 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
254 ((conn.Y * (int)Constants.RegionSize)));
255
256 Vector3 extents = Vector3.Zero;
257 extents.Y = regionConnections.YEnd;
258 extents.X = conn.XEnd + conn.XEnd;
259
260 m_log.DebugFormat("Scene: {0} to the east of Scene{1} Offset: {2}. Extents:{3}",
261 conn.RegionScene.RegionInfo.RegionName,
262 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
263
264 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
265
266 connectedYN = true;
267 break;
268 }
269 */
270
271 /*
272 // If we're one region over -x -y
273 //yxx
274 //xxx
275 //xxx
276 if ((((int)conn.X * (int)Constants.RegionSize) - conn.XEnd
277 == (regionConnections.X * (int)Constants.RegionSize))
278 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
279 == (regionConnections.Y * (int)Constants.RegionSize)))
280 {
281 Vector3 offset = Vector3.Zero;
282 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
283 ((conn.X * (int)Constants.RegionSize)));
284 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
285 ((conn.Y * (int)Constants.RegionSize)));
286
287 Vector3 extents = Vector3.Zero;
288 extents.Y = regionConnections.YEnd + conn.YEnd;
289 extents.X = conn.XEnd + conn.XEnd;
290
291 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}",
292 conn.RegionScene.RegionInfo.RegionName,
293 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
294
295 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, extents);
296
297 connectedYN = true;
298 break;
299 }
300 */
301 #endregion
302
303 // If we're one region over +x y
304 //xxx
305 //xxy
306 //xxx
307
308
309 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd
310 >= (regionConnections.X * (int)Constants.RegionSize))
311 && (((int)conn.Y * (int)Constants.RegionSize)
312 >= (regionConnections.Y * (int)Constants.RegionSize)))
313 {
314 connectedYN = DoWorkForOneRegionOverPlusXY(conn, regionConnections, scene);
315 break;
316 }
317
318 // If we're one region over x +y
319 //xyx
320 //xxx
321 //xxx
322 if ((((int)conn.X * (int)Constants.RegionSize)
323 >= (regionConnections.X * (int)Constants.RegionSize))
324 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
325 >= (regionConnections.Y * (int)Constants.RegionSize)))
326 {
327 connectedYN = DoWorkForOneRegionOverXPlusY(conn, regionConnections, scene);
328 break;
329 }
330
331 // If we're one region over +x +y
332 //xxy
333 //xxx
334 //xxx
335 if ((((int)conn.X * (int)Constants.RegionSize) + conn.YEnd
336 >= (regionConnections.X * (int)Constants.RegionSize))
337 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
338 >= (regionConnections.Y * (int)Constants.RegionSize)))
339 {
340 connectedYN = DoWorkForOneRegionOverPlusXPlusY(conn, regionConnections, scene);
341 break;
342
343 }
344 }
345
346 // If !connectYN means that this region is a root region
347 if (!connectedYN)
348 {
349 DoWorkForRootRegion(regionConnections, scene);
350
351 }
352 }
353 // Set up infinite borders around the entire AABB of the combined ConnectedRegions
354 AdjustLargeRegionBounds();
355 }
356
357 private bool DoWorkForOneRegionOverPlusXY(RegionConnections conn, RegionConnections regionConnections, Scene scene)
358 {
359 Vector3 offset = Vector3.Zero;
360 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
361 ((conn.X * (int)Constants.RegionSize)));
362 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
363 ((conn.Y * (int)Constants.RegionSize)));
364
365 Vector3 extents = Vector3.Zero;
366 extents.Y = conn.YEnd;
367 extents.X = conn.XEnd + regionConnections.XEnd;
368
369 conn.UpdateExtents(extents);
370
371 m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}",
372 conn.RegionScene.RegionInfo.RegionName,
373 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
374
375 scene.BordersLocked = true;
376 conn.RegionScene.BordersLocked = true;
377
378 RegionData ConnectedRegion = new RegionData();
379 ConnectedRegion.Offset = offset;
380 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
381 ConnectedRegion.RegionScene = scene;
382 conn.ConnectedRegions.Add(ConnectedRegion);
383
384 // Inform root region Physics about the extents of this region
385 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
386
387 // Inform Child region that it needs to forward it's terrain to the root region
388 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
389
390 // Extend the borders as appropriate
391 lock (conn.RegionScene.EastBorders)
392 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
393
394 lock (conn.RegionScene.NorthBorders)
395 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
396
397 lock (conn.RegionScene.SouthBorders)
398 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
399
400 lock (scene.WestBorders)
401 {
402
403
404 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
405
406 // Trigger auto teleport to root region
407 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
408 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
409 }
410
411 // Reset Terrain.. since terrain loads before we get here, we need to load
412 // it again so it loads in the root region
413
414 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
415
416 // Unlock borders
417 conn.RegionScene.BordersLocked = false;
418 scene.BordersLocked = false;
419
420 // Create a client event forwarder and add this region's events to the root region.
421 if (conn.ClientEventForwarder != null)
422 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
423
424 return true;
425 }
426
427 private bool DoWorkForOneRegionOverXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene)
428 {
429 Vector3 offset = Vector3.Zero;
430 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
431 ((conn.X * (int)Constants.RegionSize)));
432 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
433 ((conn.Y * (int)Constants.RegionSize)));
434
435 Vector3 extents = Vector3.Zero;
436 extents.Y = regionConnections.YEnd + conn.YEnd;
437 extents.X = conn.XEnd;
438 conn.UpdateExtents(extents);
439
440 scene.BordersLocked = true;
441 conn.RegionScene.BordersLocked = true;
442
443 RegionData ConnectedRegion = new RegionData();
444 ConnectedRegion.Offset = offset;
445 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
446 ConnectedRegion.RegionScene = scene;
447 conn.ConnectedRegions.Add(ConnectedRegion);
448
449 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}",
450 conn.RegionScene.RegionInfo.RegionName,
451 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
452
453 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
454 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
455
456 lock (conn.RegionScene.NorthBorders)
457 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
458 lock (conn.RegionScene.EastBorders)
459 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
460 lock (conn.RegionScene.WestBorders)
461 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
462 lock (scene.SouthBorders)
463 {
464 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
465 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
466 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
467 }
468
469 // Reset Terrain.. since terrain normally loads first.
470 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
471 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
472 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
473
474 scene.BordersLocked = false;
475 conn.RegionScene.BordersLocked = false;
476 if (conn.ClientEventForwarder != null)
477 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
478 return true;
479 }
480
481 private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene)
482 {
483 Vector3 offset = Vector3.Zero;
484 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
485 ((conn.X * (int)Constants.RegionSize)));
486 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
487 ((conn.Y * (int)Constants.RegionSize)));
488
489 Vector3 extents = Vector3.Zero;
490 extents.Y = regionConnections.YEnd + conn.YEnd;
491 extents.X = regionConnections.XEnd + conn.XEnd;
492 conn.UpdateExtents(extents);
493
494 scene.BordersLocked = true;
495 conn.RegionScene.BordersLocked = true;
496
497 RegionData ConnectedRegion = new RegionData();
498 ConnectedRegion.Offset = offset;
499 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
500 ConnectedRegion.RegionScene = scene;
501
502 conn.ConnectedRegions.Add(ConnectedRegion);
503
504 m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}",
505 conn.RegionScene.RegionInfo.RegionName,
506 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
507
508 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
509 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
510 lock (conn.RegionScene.NorthBorders)
511 {
512 if (conn.RegionScene.NorthBorders.Count == 1)// && 2)
513 {
514 //compound border
515 // already locked above
516 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
517
518 lock (conn.RegionScene.EastBorders)
519 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
520 lock (conn.RegionScene.WestBorders)
521 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
522 }
523 }
524
525 lock (scene.SouthBorders)
526 {
527 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
528 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
529 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
530 }
531
532 lock (conn.RegionScene.EastBorders)
533 {
534 if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
535 {
536
537 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
538 lock (conn.RegionScene.NorthBorders)
539 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
540 lock (conn.RegionScene.SouthBorders)
541 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
542
543
544 }
545 }
546
547 lock (scene.WestBorders)
548 {
549 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
550 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
551 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
552 }
553
554 /*
555 else
556 {
557 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
558 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
559 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
560 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
561 }
562 */
563
564
565 // Reset Terrain.. since terrain normally loads first.
566 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
567 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
568 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
569 scene.BordersLocked = false;
570 conn.RegionScene.BordersLocked = false;
571
572 if (conn.ClientEventForwarder != null)
573 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
574
575 return true;
576
577 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents);
578
579 }
580
581 private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene)
582 {
583 RegionData rdata = new RegionData();
584 rdata.Offset = Vector3.Zero;
585 rdata.RegionId = scene.RegionInfo.originRegionID;
586 rdata.RegionScene = scene;
587 // save it's land channel
588 regionConnections.RegionLandChannel = scene.LandChannel;
589
590 // Substitue our landchannel
591 RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel,
592 regionConnections.ConnectedRegions);
593 scene.LandChannel = lnd;
594 // Forward the permissions modules of each of the connected regions to the root region
595 lock (m_regions)
596 {
597 foreach (RegionData r in regionConnections.ConnectedRegions)
598 {
599 ForwardPermissionRequests(regionConnections, r.RegionScene);
600 }
601 }
602 // Create the root region's Client Event Forwarder
603 regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections);
604
605 // Sets up the CoarseLocationUpdate forwarder for this root region
606 scene.EventManager.OnNewPresence += SetCourseLocationDelegate;
607
608 // Adds this root region to a dictionary of regions that are connectable
609 m_regions.Add(scene.RegionInfo.originRegionID, regionConnections);
610 }
611
612 private void SetCourseLocationDelegate(ScenePresence presence)
613 {
614 presence.SetSendCourseLocationMethod(SendCourseLocationUpdates);
615 }
616
617 private void SendCourseLocationUpdates(UUID sceneId, ScenePresence presence)
618 {
619 RegionConnections connectiondata = null;
620 lock (m_regions)
621 {
622 if (m_regions.ContainsKey(sceneId))
623 connectiondata = m_regions[sceneId];
624 else
625 return;
626 }
627
628 List<ScenePresence> avatars = connectiondata.RegionScene.GetAvatars();
629 List<Vector3> CoarseLocations = new List<Vector3>();
630 List<UUID> AvatarUUIDs = new List<UUID>();
631 for (int i = 0; i < avatars.Count; i++)
632 {
633 if (avatars[i].UUID != presence.UUID)
634 {
635 if (avatars[i].ParentID != 0)
636 {
637 // sitting avatar
638 SceneObjectPart sop = connectiondata.RegionScene.GetSceneObjectPart(avatars[i].ParentID);
639 if (sop != null)
640 {
641 CoarseLocations.Add(sop.AbsolutePosition + avatars[i].AbsolutePosition);
642 AvatarUUIDs.Add(avatars[i].UUID);
643 }
644 else
645 {
646 // we can't find the parent.. ! arg!
647 CoarseLocations.Add(avatars[i].AbsolutePosition);
648 AvatarUUIDs.Add(avatars[i].UUID);
649 }
650 }
651 else
652 {
653 CoarseLocations.Add(avatars[i].AbsolutePosition);
654 AvatarUUIDs.Add(avatars[i].UUID);
655 }
656 }
657 }
658 DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence);
659 }
660
661 private void DistributeCourseLocationUpdates(List<Vector3> locations, List<UUID> uuids,
662 RegionConnections connectiondata, ScenePresence rootPresence)
663 {
664 RegionData[] rdata = connectiondata.ConnectedRegions.ToArray();
665 //List<IClientAPI> clients = new List<IClientAPI>();
666 Dictionary<Vector2, RegionCourseLocationStruct> updates = new Dictionary<Vector2, RegionCourseLocationStruct>();
667
668 // Root Region entry
669 RegionCourseLocationStruct rootupdatedata = new RegionCourseLocationStruct();
670 rootupdatedata.Locations = new List<Vector3>();
671 rootupdatedata.Uuids = new List<UUID>();
672 rootupdatedata.Offset = Vector2.Zero;
673
674 rootupdatedata.UserAPI = rootPresence.ControllingClient;
675
676 if (rootupdatedata.UserAPI != null)
677 updates.Add(Vector2.Zero, rootupdatedata);
678
679 //Each Region needs an entry or we will end up with dead minimap dots
680 foreach (RegionData regiondata in rdata)
681 {
682 Vector2 offset = new Vector2(regiondata.Offset.X, regiondata.Offset.Y);
683 RegionCourseLocationStruct updatedata = new RegionCourseLocationStruct();
684 updatedata.Locations = new List<Vector3>();
685 updatedata.Uuids = new List<UUID>();
686 updatedata.Offset = offset;
687
688 if (offset == Vector2.Zero)
689 updatedata.UserAPI = rootPresence.ControllingClient;
690 else
691 updatedata.UserAPI = LocateUsersChildAgentIClientAPI(offset, rootPresence.UUID, rdata);
692
693 if (updatedata.UserAPI != null)
694 updates.Add(offset, updatedata);
695 }
696
697 // go over the locations and assign them to an IClientAPI
698 for (int i = 0; i < locations.Count; i++)
699 //{locations[i]/(int) Constants.RegionSize;
700 {
701 Vector3 pPosition = new Vector3((int)locations[i].X / (int)Constants.RegionSize,
702 (int)locations[i].Y / (int)Constants.RegionSize, locations[i].Z);
703 Vector2 offset = new Vector2(pPosition.X*(int) Constants.RegionSize,
704 pPosition.Y*(int) Constants.RegionSize);
705
706 if (!updates.ContainsKey(offset))
707 {
708 // This shouldn't happen
709 RegionCourseLocationStruct updatedata = new RegionCourseLocationStruct();
710 updatedata.Locations = new List<Vector3>();
711 updatedata.Uuids = new List<UUID>();
712 updatedata.Offset = offset;
713
714 if (offset == Vector2.Zero)
715 updatedata.UserAPI = rootPresence.ControllingClient;
716 else
717 updatedata.UserAPI = LocateUsersChildAgentIClientAPI(offset, rootPresence.UUID, rdata);
718
719 updates.Add(offset,updatedata);
720 }
721
722 updates[offset].Locations.Add(locations[i]);
723 updates[offset].Uuids.Add(uuids[i]);
724 }
725
726 // Send out the CoarseLocationupdates from their respective client connection based on where the avatar is
727 foreach (Vector2 offset in updates.Keys)
728 {
729 if (updates[offset].UserAPI != null)
730 {
731 updates[offset].UserAPI.SendCoarseLocationUpdate(updates[offset].Uuids,updates[offset].Locations);
732 }
733 }
734 }
735
736 /// <summary>
737 /// Locates a the Client of a particular region in an Array of RegionData based on offset
738 /// </summary>
739 /// <param name="offset"></param>
740 /// <param name="uUID"></param>
741 /// <param name="rdata"></param>
742 /// <returns>IClientAPI or null</returns>
743 private IClientAPI LocateUsersChildAgentIClientAPI(Vector2 offset, UUID uUID, RegionData[] rdata)
744 {
745 IClientAPI returnclient = null;
746 foreach (RegionData r in rdata)
747 {
748 if (r.Offset.X == offset.X && r.Offset.Y == offset.Y)
749 {
750 return r.RegionScene.SceneGraph.GetControllingClient(uUID);
751 }
752 }
753
754 return returnclient;
755 }
756
757 public void PostInitialise()
758 {
759 }
760
761 /// <summary>
762 /// TODO:
763 /// </summary>
764 /// <param name="rdata"></param>
765 public void UnCombineRegion(RegionData rdata)
766 {
767 lock (m_regions)
768 {
769 if (m_regions.ContainsKey(rdata.RegionId))
770 {
771 // uncombine root region and virtual regions
772 }
773 else
774 {
775 foreach (RegionConnections r in m_regions.Values)
776 {
777 foreach (RegionData rd in r.ConnectedRegions)
778 {
779 if (rd.RegionId == rdata.RegionId)
780 {
781 // uncombine virtual region
782 }
783 }
784 }
785 }
786 }
787 }
788
789 // Create a set of infinite borders around the whole aabb of the combined island.
790 private void AdjustLargeRegionBounds()
791 {
792 lock (m_regions)
793 {
794 foreach (RegionConnections rconn in m_regions.Values)
795 {
796 Vector3 offset = Vector3.Zero;
797 rconn.RegionScene.BordersLocked = true;
798 foreach (RegionData rdata in rconn.ConnectedRegions)
799 {
800 if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X;
801 if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y;
802 }
803
804 lock (rconn.RegionScene.NorthBorders)
805 {
806 Border northBorder = null;
807 // If we don't already have an infinite border, create one.
808 if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder))
809 {
810 northBorder = new Border();
811 rconn.RegionScene.NorthBorders.Add(northBorder);
812 }
813
814 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,
815 offset.Y + (int) Constants.RegionSize); //<---
816 northBorder.CrossDirection = Cardinals.N;
817 }
818
819 lock (rconn.RegionScene.SouthBorders)
820 {
821 Border southBorder = null;
822 // If we don't already have an infinite border, create one.
823 if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder))
824 {
825 southBorder = new Border();
826 rconn.RegionScene.SouthBorders.Add(southBorder);
827 }
828 southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
829 southBorder.CrossDirection = Cardinals.S;
830 }
831
832 lock (rconn.RegionScene.EastBorders)
833 {
834 Border eastBorder = null;
835 // If we don't already have an infinite border, create one.
836 if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder))
837 {
838 eastBorder = new Border();
839 rconn.RegionScene.EastBorders.Add(eastBorder);
840 }
841 eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize);
842 //<---
843 eastBorder.CrossDirection = Cardinals.E;
844 }
845
846 lock (rconn.RegionScene.WestBorders)
847 {
848 Border westBorder = null;
849 // If we don't already have an infinite border, create one.
850 if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder))
851 {
852 westBorder = new Border();
853 rconn.RegionScene.WestBorders.Add(westBorder);
854
855 }
856 westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
857 westBorder.CrossDirection = Cardinals.W;
858 }
859
860 rconn.RegionScene.BordersLocked = false;
861 }
862 }
863 }
864
865 /// <summary>
866 /// Try and get an Infinite border out of a listT of borders
867 /// </summary>
868 /// <param name="borders"></param>
869 /// <param name="oborder"></param>
870 /// <returns></returns>
871 public static bool TryGetInfiniteBorder(List<Border> borders, out Border oborder)
872 {
873 // Warning! Should be locked before getting here!
874 foreach (Border b in borders)
875 {
876 if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue)
877 {
878 oborder = b;
879 return true;
880 }
881 }
882 oborder = null;
883 return false;
884 }
885
886 public RegionData GetRegionFromPosition(Vector3 pPosition)
887 {
888 pPosition = pPosition/(int) Constants.RegionSize;
889 int OffsetX = (int) pPosition.X;
890 int OffsetY = (int) pPosition.Y;
891 foreach (RegionConnections regConn in m_regions.Values)
892 {
893 foreach (RegionData reg in regConn.ConnectedRegions)
894 {
895 if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY)
896 return reg;
897 }
898 }
899 return new RegionData();
900 }
901
902 public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion)
903 {
904 if (BigRegion.PermissionModule == null)
905 BigRegion.PermissionModule = new RegionCombinerPermissionModule(BigRegion.RegionScene);
906
907 VirtualRegion.Permissions.OnBypassPermissions += BigRegion.PermissionModule.BypassPermissions;
908 VirtualRegion.Permissions.OnSetBypassPermissions += BigRegion.PermissionModule.SetBypassPermissions;
909 VirtualRegion.Permissions.OnPropagatePermissions += BigRegion.PermissionModule.PropagatePermissions;
910 VirtualRegion.Permissions.OnGenerateClientFlags += BigRegion.PermissionModule.GenerateClientFlags;
911 VirtualRegion.Permissions.OnAbandonParcel += BigRegion.PermissionModule.CanAbandonParcel;
912 VirtualRegion.Permissions.OnReclaimParcel += BigRegion.PermissionModule.CanReclaimParcel;
913 VirtualRegion.Permissions.OnDeedParcel += BigRegion.PermissionModule.CanDeedParcel;
914 VirtualRegion.Permissions.OnDeedObject += BigRegion.PermissionModule.CanDeedObject;
915 VirtualRegion.Permissions.OnIsGod += BigRegion.PermissionModule.IsGod;
916 VirtualRegion.Permissions.OnDuplicateObject += BigRegion.PermissionModule.CanDuplicateObject;
917 VirtualRegion.Permissions.OnDeleteObject += BigRegion.PermissionModule.CanDeleteObject; //MAYBE FULLY IMPLEMENTED
918 VirtualRegion.Permissions.OnEditObject += BigRegion.PermissionModule.CanEditObject; //MAYBE FULLY IMPLEMENTED
919 VirtualRegion.Permissions.OnEditParcel += BigRegion.PermissionModule.CanEditParcel; //MAYBE FULLY IMPLEMENTED
920 VirtualRegion.Permissions.OnInstantMessage += BigRegion.PermissionModule.CanInstantMessage;
921 VirtualRegion.Permissions.OnInventoryTransfer += BigRegion.PermissionModule.CanInventoryTransfer; //NOT YET IMPLEMENTED
922 VirtualRegion.Permissions.OnIssueEstateCommand += BigRegion.PermissionModule.CanIssueEstateCommand; //FULLY IMPLEMENTED
923 VirtualRegion.Permissions.OnMoveObject += BigRegion.PermissionModule.CanMoveObject; //MAYBE FULLY IMPLEMENTED
924 VirtualRegion.Permissions.OnObjectEntry += BigRegion.PermissionModule.CanObjectEntry;
925 VirtualRegion.Permissions.OnReturnObject += BigRegion.PermissionModule.CanReturnObject; //NOT YET IMPLEMENTED
926 VirtualRegion.Permissions.OnRezObject += BigRegion.PermissionModule.CanRezObject; //MAYBE FULLY IMPLEMENTED
927 VirtualRegion.Permissions.OnRunConsoleCommand += BigRegion.PermissionModule.CanRunConsoleCommand;
928 VirtualRegion.Permissions.OnRunScript += BigRegion.PermissionModule.CanRunScript; //NOT YET IMPLEMENTED
929 VirtualRegion.Permissions.OnCompileScript += BigRegion.PermissionModule.CanCompileScript;
930 VirtualRegion.Permissions.OnSellParcel += BigRegion.PermissionModule.CanSellParcel;
931 VirtualRegion.Permissions.OnTakeObject += BigRegion.PermissionModule.CanTakeObject;
932 VirtualRegion.Permissions.OnTakeCopyObject += BigRegion.PermissionModule.CanTakeCopyObject;
933 VirtualRegion.Permissions.OnTerraformLand += BigRegion.PermissionModule.CanTerraformLand;
934 VirtualRegion.Permissions.OnLinkObject += BigRegion.PermissionModule.CanLinkObject; //NOT YET IMPLEMENTED
935 VirtualRegion.Permissions.OnDelinkObject += BigRegion.PermissionModule.CanDelinkObject; //NOT YET IMPLEMENTED
936 VirtualRegion.Permissions.OnBuyLand += BigRegion.PermissionModule.CanBuyLand; //NOT YET IMPLEMENTED
937 VirtualRegion.Permissions.OnViewNotecard += BigRegion.PermissionModule.CanViewNotecard; //NOT YET IMPLEMENTED
938 VirtualRegion.Permissions.OnViewScript += BigRegion.PermissionModule.CanViewScript; //NOT YET IMPLEMENTED
939 VirtualRegion.Permissions.OnEditNotecard += BigRegion.PermissionModule.CanEditNotecard; //NOT YET IMPLEMENTED
940 VirtualRegion.Permissions.OnEditScript += BigRegion.PermissionModule.CanEditScript; //NOT YET IMPLEMENTED
941 VirtualRegion.Permissions.OnCreateObjectInventory += BigRegion.PermissionModule.CanCreateObjectInventory; //NOT IMPLEMENTED HERE
942 VirtualRegion.Permissions.OnEditObjectInventory += BigRegion.PermissionModule.CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED
943 VirtualRegion.Permissions.OnCopyObjectInventory += BigRegion.PermissionModule.CanCopyObjectInventory; //NOT YET IMPLEMENTED
944 VirtualRegion.Permissions.OnDeleteObjectInventory += BigRegion.PermissionModule.CanDeleteObjectInventory; //NOT YET IMPLEMENTED
945 VirtualRegion.Permissions.OnResetScript += BigRegion.PermissionModule.CanResetScript;
946 VirtualRegion.Permissions.OnCreateUserInventory += BigRegion.PermissionModule.CanCreateUserInventory; //NOT YET IMPLEMENTED
947 VirtualRegion.Permissions.OnCopyUserInventory += BigRegion.PermissionModule.CanCopyUserInventory; //NOT YET IMPLEMENTED
948 VirtualRegion.Permissions.OnEditUserInventory += BigRegion.PermissionModule.CanEditUserInventory; //NOT YET IMPLEMENTED
949 VirtualRegion.Permissions.OnDeleteUserInventory += BigRegion.PermissionModule.CanDeleteUserInventory; //NOT YET IMPLEMENTED
950 VirtualRegion.Permissions.OnTeleport += BigRegion.PermissionModule.CanTeleport; //NOT YET IMPLEMENTED
951 VirtualRegion.Permissions.OnUseObjectReturn += BigRegion.PermissionModule.CanUseObjectReturn; //NOT YET IMPLEMENTED
952 }
953
954 #region console commands
955 public void FixPhantoms(string module, string[] cmdparams)
956 {
957 List<Scene> scenes = new List<Scene>(m_startingScenes.Values);
958 foreach (Scene s in scenes)
959 {
960 s.ForEachSOG(delegate(SceneObjectGroup e)
961 {
962 e.AbsolutePosition = e.AbsolutePosition;
963 }
964 );
965 }
966 }
967 #endregion
968 }
969}