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