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