aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/world
diff options
context:
space:
mode:
authorjhurliman2007-03-07 05:09:18 +0000
committerjhurliman2007-03-07 05:09:18 +0000
commit0b6f8a02a7d0927031bf812429770d6ecc5f483a (patch)
tree6795f255e730e5cdfcf79191a0fd64734951d691 /src/world
parentNEVER COMMIT WITHOUT A TEST COMPILE! (diff)
downloadopensim-SC-0b6f8a02a7d0927031bf812429770d6ecc5f483a.zip
opensim-SC-0b6f8a02a7d0927031bf812429770d6ecc5f483a.tar.gz
opensim-SC-0b6f8a02a7d0927031bf812429770d6ecc5f483a.tar.bz2
opensim-SC-0b6f8a02a7d0927031bf812429770d6ecc5f483a.tar.xz
* Updating libsecondlife.dll to the latest version with a working LayerData function
* Reformatting some source files * Adding a try/catch sanity check around a phoning home check to osgrid.org * Updating the MSVC project file * Converted LayerData generation to use the functions built in to libsecondlife * Removing unused BitPack.cs and TerrainDecoder.cs files * Added a basic terrain generator (hills algorithm)
Diffstat (limited to 'src/world')
-rw-r--r--src/world/Avatar.cs4
-rw-r--r--src/world/HeightmapGenHills.cs122
-rw-r--r--src/world/TerrainDecoder.cs683
-rw-r--r--src/world/World.cs137
4 files changed, 203 insertions, 743 deletions
diff --git a/src/world/Avatar.cs b/src/world/Avatar.cs
index 26b2002..9d8d7d2 100644
--- a/src/world/Avatar.cs
+++ b/src/world/Avatar.cs
@@ -226,8 +226,8 @@ namespace OpenSim.world
226 handshake.RegionInfo.TerrainStartHeight10 = 10; 226 handshake.RegionInfo.TerrainStartHeight10 = 10;
227 handshake.RegionInfo.TerrainStartHeight11 = 10; 227 handshake.RegionInfo.TerrainStartHeight11 = 10;
228 handshake.RegionInfo.SimAccess = 13; 228 handshake.RegionInfo.SimAccess = 13;
229 handshake.RegionInfo.WaterHeight = 5; 229 handshake.RegionInfo.WaterHeight = 20.0f;
230 handshake.RegionInfo.RegionFlags = 72458694; 230 handshake.RegionInfo.RegionFlags = 72458694; // TODO: WTF sirs? Use an enum!
231 handshake.RegionInfo.SimName = _enc.GetBytes(OpenSim_Main.cfg.RegionName + "\0"); 231 handshake.RegionInfo.SimName = _enc.GetBytes(OpenSim_Main.cfg.RegionName + "\0");
232 handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000"); 232 handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
233 handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975"); 233 handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975");
diff --git a/src/world/HeightmapGenHills.cs b/src/world/HeightmapGenHills.cs
new file mode 100644
index 0000000..12af005
--- /dev/null
+++ b/src/world/HeightmapGenHills.cs
@@ -0,0 +1,122 @@
1using System;
2
3namespace libsecondlife
4{
5 public class HeightmapGenHills
6 {
7 private Random Rand = new Random();
8 private int NumHills;
9 private float HillMin;
10 private float HillMax;
11 private bool Island;
12 private float[] heightmap;
13
14 public float[] GenerateHeightmap(int numHills, float hillMin, float hillMax, bool island)
15 {
16 NumHills = numHills;
17 HillMin = hillMin;
18 HillMax = hillMax;
19 Island = island;
20
21 heightmap = new float[256 * 256];
22
23 for (int i = 0; i < numHills; i++)
24 {
25 AddHill();
26 }
27
28 Normalize();
29
30 return heightmap;
31 }
32
33 private void AddHill()
34 {
35 float x, y;
36 float radius = RandomRange(HillMin, HillMax);
37
38 if (Island)
39 {
40 // Which direction from the center of the map the hill is placed
41 float theta = RandomRange(0, 6.28f);
42
43 // How far from the center of the map to place the hill. The radius
44 // is subtracted from the range to prevent any part of the hill from
45 // reaching the edge of the map
46 float distance = RandomRange(radius / 2.0f, 128.0f - radius);
47
48 x = 128.0f + (float)Math.Cos(theta) * distance;
49 y = 128.0f + (float)Math.Sin(theta) * distance;
50 }
51 else
52 {
53 x = RandomRange(-radius, 256.0f + radius);
54 y = RandomRange(-radius, 256.0f + radius);
55 }
56
57 float radiusSq = radius * radius;
58 float distSq;
59 float height;
60
61 int xMin = (int)(x - radius) - 1;
62 int xMax = (int)(x + radius) + 1;
63 if (xMin < 0) xMin = 0;
64 if (xMax > 255) xMax = 255;
65
66 int yMin = (int)(y - radius) - 1;
67 int yMax = (int)(y + radius) + 1;
68 if (yMin < 0) yMin = 0;
69 if (yMax > 255) yMax = 255;
70
71 // Loop through each affected cell and determine the height at that point
72 for (int v = yMin; v <= yMax; ++v)
73 {
74 float fv = (float)v;
75
76 for (int h = xMin; h <= xMax; ++h)
77 {
78 float fh = (float)h;
79
80 // Determine how far from the center of this hill this point is
81 distSq = (x - fh) * (x - fh) + (y - fv) * (y - fv);
82 height = radiusSq - distSq;
83
84 // Don't add negative hill values
85 if (height > 0.0f) heightmap[h + v * 256] += height;
86 }
87 }
88 }
89
90 private void Normalize()
91 {
92 float min = heightmap[0];
93 float max = heightmap[0];
94
95 for (int x = 0; x < 256; x++)
96 {
97 for (int y = 0; y < 256; y++)
98 {
99 if (heightmap[x + y * 256] < min) min = heightmap[x + y * 256];
100 if (heightmap[x + y * 256] > max) max = heightmap[x + y * 256];
101 }
102 }
103
104 // Avoid a rare divide by zero
105 if (min != max)
106 {
107 for (int x = 0; x < 256; x++)
108 {
109 for (int y = 0; y < 256; y++)
110 {
111 heightmap[x + y * 256] = ((heightmap[x + y * 256] - min) / (max - min)) * (HillMax - HillMin);
112 }
113 }
114 }
115 }
116
117 private float RandomRange(float min, float max)
118 {
119 return (float)Rand.NextDouble() * (max - min) + min;
120 }
121 }
122}
diff --git a/src/world/TerrainDecoder.cs b/src/world/TerrainDecoder.cs
deleted file mode 100644
index 1a34826..0000000
--- a/src/world/TerrainDecoder.cs
+++ /dev/null
@@ -1,683 +0,0 @@
1/*
2* Copyright (c) OpenSim project, http://sim.opensecondlife.org/
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are met:
6* * Redistributions of source code must retain the above copyright
7* notice, this list of conditions and the following disclaimer.
8* * Redistributions in binary form must reproduce the above copyright
9* notice, this list of conditions and the following disclaimer in the
10* documentation and/or other materials provided with the distribution.
11* * Neither the name of the <organization> nor the
12* names of its contributors may be used to endorse or promote products
13* derived from this software without specific prior written permission.
14*
15* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
16* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
19* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*
26*/
27
28using System;
29using System.Collections.Generic;
30//using libsecondlife;
31using libsecondlife.Packets;
32
33namespace OpenSim
34{
35 /// <summary>
36 /// Description of TerrainDecoder.
37 /// </summary>
38 public class TerrainDecode
39 {
40
41 public enum LayerType : byte
42 {
43 Land = 0x4C,
44 Water = 0x57,
45 Wind = 0x37,
46 Cloud = 0x38
47 }
48
49 public struct GroupHeader
50 {
51 public int Stride;
52 public int PatchSize;
53 public LayerType Type;
54 }
55
56 public struct PatchHeader
57 {
58 public float DCOffset;
59 public int Range;
60 public int QuantWBits;
61 public int PatchIDs;
62 public uint WordBits;
63 }
64
65 public class Patch
66 {
67 public float[] Heightmap;
68 }
69
70
71 /// <summary>
72 ///
73 /// </summary>
74 /// <param name="simulator"></param>
75 /// <param name="x"></param>
76 /// <param name="y"></param>
77 /// <param name="width"></param>
78 /// <param name="data"></param>
79 // public delegate void LandPatchCallback(Simulator simulator, int x, int y, int width, float[] data);
80
81
82 /// <summary>
83 ///
84 /// </summary>
85 //public event LandPatchCallback OnLandPatch;
86
87 private Random RandomClass = new Random();
88
89 private const byte END_OF_PATCHES = 97;
90 private const int PATCHES_PER_EDGE = 16;
91 private const float OO_SQRT2 = 0.7071067811865475244008443621049f;
92
93 //private SecondLife Client;
94 private Dictionary<ulong, Patch[]> SimPatches = new Dictionary<ulong, Patch[]>();
95 private float[] DequantizeTable16 = new float[16 * 16];
96 private float[] DequantizeTable32 = new float[32 * 32];
97 private float[] ICosineTable16 = new float[16 * 16];
98 private float[] ICosineTable32 = new float[32 * 32];
99 private int[] DeCopyMatrix16 = new int[16 * 16];
100 private int[] DeCopyMatrix32 = new int[32 * 32];
101
102
103 /// <summary>
104 ///
105 /// </summary>
106 /// <param name="client"></param>
107 public TerrainDecode()
108 {
109
110 // Initialize the decompression tables
111 BuildDequantizeTable16();
112 BuildDequantizeTable32();
113 SetupICosines16();
114 SetupICosines32();
115 BuildDecopyMatrix16();
116 BuildDecopyMatrix32();
117
118 }
119
120
121 private void BuildDequantizeTable16()
122 {
123 for (int j = 0; j < 16; j++)
124 {
125 for (int i = 0; i < 16; i++)
126 {
127 DequantizeTable16[j * 16 + i] = 1.0f + 2.0f * (float)(i + j);
128 }
129 }
130 }
131
132 private void BuildDequantizeTable32()
133 {
134 for (int j = 0; j < 32; j++)
135 {
136 for (int i = 0; i < 32; i++)
137 {
138 DequantizeTable32[j * 32 + i] = 1.0f + 2.0f * (float)(i + j);
139 }
140 }
141 }
142
143 private void SetupICosines16()
144 {
145 const float hposz = (float)Math.PI * 0.5f / 16.0f;
146
147 for (int u = 0; u < 16; u++)
148 {
149 for (int n = 0; n < 16; n++)
150 {
151 ICosineTable16[u * 16 + n] = (float)Math.Cos((2.0f * (float)n + 1.0f) * (float)u * hposz);
152 }
153 }
154 }
155
156 private void SetupICosines32()
157 {
158 const float hposz = (float)Math.PI * 0.5f / 32.0f;
159
160 for (int u = 0; u < 32; u++)
161 {
162 for (int n = 0; n < 32; n++)
163 {
164 ICosineTable32[u * 32 + n] = (float)Math.Cos((2.0f * (float)n + 1.0f) * (float)u * hposz);
165 }
166 }
167 }
168
169 private void BuildDecopyMatrix16()
170 {
171 bool diag = false;
172 bool right = true;
173 int i = 0;
174 int j = 0;
175 int count = 0;
176
177 while (i < 16 && j < 16)
178 {
179 DeCopyMatrix16[j * 16 + i] = count++;
180
181 if (!diag)
182 {
183 if (right)
184 {
185 if (i < 16 - 1) i++;
186 else j++;
187
188 right = false;
189 diag = true;
190 }
191 else
192 {
193 if (j < 16 - 1) j++;
194 else i++;
195
196 right = true;
197 diag = true;
198 }
199 }
200 else
201 {
202 if (right)
203 {
204 i++;
205 j--;
206 if (i == 16 - 1 || j == 0) diag = false;
207 }
208 else
209 {
210 i--;
211 j++;
212 if (j == 16 - 1 || i == 0) diag = false;
213 }
214 }
215 }
216 }
217
218 private void BuildDecopyMatrix32()
219 {
220 bool diag = false;
221 bool right = true;
222 int i = 0;
223 int j = 0;
224 int count = 0;
225
226 while (i < 32 && j < 32)
227 {
228 DeCopyMatrix32[j * 32 + i] = count++;
229
230 if (!diag)
231 {
232 if (right)
233 {
234 if (i < 32 - 1) i++;
235 else j++;
236
237 right = false;
238 diag = true;
239 }
240 else
241 {
242 if (j < 32 - 1) j++;
243 else i++;
244
245 right = true;
246 diag = true;
247 }
248 }
249 else
250 {
251 if (right)
252 {
253 i++;
254 j--;
255 if (i == 32 - 1 || j == 0) diag = false;
256 }
257 else
258 {
259 i--;
260 j++;
261 if (j == 32 - 1 || i == 0) diag = false;
262 }
263 }
264 }
265 }
266
267 private void EncodePatchHeader(BitPacker bitpack, PatchHeader header)
268 {
269 bitpack.PackBits(header.QuantWBits,8);
270
271 if (header.QuantWBits == END_OF_PATCHES)
272 return;
273
274 bitpack.PackFloat(header.DCOffset);
275 bitpack.PackBits(header.Range,16);
276 bitpack.PackBits(header.PatchIDs,10);
277
278 }
279
280 public void DCTLine16(float[] In, float[] Out, int line)
281 {
282 int N =16;
283 int lineSize = line * 16;
284
285 for(int k = 0; k < N;k++)
286 {
287 float sum = 0.0f;
288 for(int n = 0; n < N; n++)
289 {
290 float num = (float)(Math.PI*k*(2.0f*n+1)/(2*N));
291 float cosine = (float)Math.Cos(num);
292 float product = In[lineSize +n] * cosine;
293 sum += product;
294 }
295
296 float alpha;
297 if(k == 0)
298 {
299 alpha = (float)(1.0f/Math.Sqrt(2));
300 }
301 else
302 {
303 alpha = 1;
304 }
305 Out[lineSize + k] =(float)( sum * alpha );
306
307 }
308 }
309 public void DCTColumn16(float[] In, float[] Out, int Column)
310 {
311 int N =16;
312 int uSize;
313
314 for(int k = 0; k < N; k++){
315 float sum = 0.0f;
316 for(int n = 0; n < N; n++)
317 {
318 uSize = n * 16;
319 float num = (float)(Math.PI*k*(2.0f*n+1)/(2*N));
320 float cosine = (float)Math.Cos(num);
321 float product = In[uSize + Column] * cosine;
322 sum += product;
323 }
324
325 float alpha;
326 if(k == 0)
327 {
328 alpha = (float)(1.0f/Math.Sqrt(2));
329 }
330 else
331 {
332 alpha = 1;
333 }
334 Out[16 * k + Column] = (float)( sum * alpha * (2.0f /N));
335
336 }
337 }
338
339 private void EncodePatch(int[] patches, BitPacker bitpack, int size)
340 {
341 int lastnum =0;
342 for(int n = 0; n < size * size; n++)
343 {
344 if(patches[n]!=0)
345 lastnum=n;
346 }
347 for (int n = 0; n < lastnum+1; n++)
348 {
349 if(patches[n] != 0)
350 {
351 bitpack.PackBits(1,1); //value or EOB
352 bitpack.PackBits(1,1); //value
353 if(patches[n] > 0)
354 {
355
356 bitpack.PackBits(0,1); // positive
357 bitpack.PackBits(patches[n],13);
358
359 }
360 else
361 {
362 bitpack.PackBits(1,1); // negative
363
364 int temp = patches[n] * -1;
365 bitpack.PackBits(temp,13);
366
367 }
368 }
369 else
370 {
371 bitpack.PackBits(0,1); // no value
372 }
373 }
374
375 bitpack.PackBits(1,1); //value or EOB
376 bitpack.PackBits(0,1); // EOB
377 }
378
379 public int[] CompressPatch(float[] patches)
380 {
381 int size = 16;
382 float[] block = new float[size * size];
383 int[] output = new int[size * size];
384 int prequant = (139 >> 4) + 2;
385 int quantize = 1 << prequant;
386 float ooq = 1.0f / (float)quantize;
387 float mult = ooq * (float)1;
388 float addval = mult * (float)(1 << (prequant - 1)) + 20.4989f;
389
390 if (size == 16)
391 {
392 for (int n = 0; n < 16 * 16; n++)
393 {
394 block[n] = (float)((patches[n] - addval)/ mult);
395 }
396
397 float[] ftemp = new float[32 * 32];
398
399 for (int o = 0; o < 16; o++)
400 this.DCTColumn16(block, ftemp, o);
401 for (int o = 0; o < 16; o++)
402 this.DCTLine16(ftemp, block, o);
403 }
404
405 for (int j = 0; j < block.Length; j++)
406 {
407 output[DeCopyMatrix16[j]] = (int)(block[j] / DequantizeTable16[j]);
408 }
409
410 return output;
411 }
412
413 public Packet CreateLayerPacket(float[] heightmap, int minX, int minY, int maxX, int maxY)
414 {
415 //int minX = 0, maxX = 2, minY = 0, maxY = 1; //these should be passed to this function
416 LayerDataPacket layer = new LayerDataPacket();
417 byte[] Encoded = new byte[2048];
418 layer.LayerID.Type = 76;
419 GroupHeader header = new GroupHeader();
420 header.Stride = 264;
421 header.PatchSize = 16;
422 header.Type = LayerType.Land;
423 BitPacker newpack = new BitPacker(Encoded,0);
424 newpack.PackBits(header.Stride,16);
425 newpack.PackBits(header.PatchSize,8);
426 newpack.PackBits((int)header.Type,8);
427
428
429 float[] height;
430 for(int y = minY; y< maxY; y++)
431 {
432 for(int x = minX ; x < maxX ; x++)
433 {
434 height = new float[256];
435 Array.Copy(heightmap, (4096 *y) +(x *256), height, 0, 256);
436
437 this.CreatePatch(height, newpack, x, y);
438 }
439 }
440
441 PatchHeader headers = new PatchHeader();
442 headers.QuantWBits = END_OF_PATCHES;
443 this.EncodePatchHeader(newpack, headers);
444
445 int lastused=0;
446 for(int i = 0; i < 2048 ; i++)
447 {
448 if(Encoded[i] !=0)
449 lastused = i;
450 }
451
452 byte[] data = new byte[lastused+1];
453 Array.Copy(Encoded, data, lastused+1);
454 layer.LayerData.Data =data;
455
456 return(layer);
457 }
458 public void CreatePatch(float[] heightmap, BitPacker newpack, int x, int y)
459 {
460 PatchHeader header = new PatchHeader();
461 header.DCOffset = 20.4989f;
462 header.QuantWBits = 139;
463 header.Range = 1;
464 header.PatchIDs = (y & 0x1F);
465 header.PatchIDs += x <<5 ;
466
467 this.EncodePatchHeader(newpack, header);
468
469 int[] newpatch = this.CompressPatch(heightmap);
470 this.EncodePatch(newpatch, newpack, 16);
471
472 }
473 }
474
475 //***************************************************
476 public class BitPacker
477 {
478 private const int MAX_BITS = 8;
479
480 private byte[] Data;
481 public int bytePos;
482 public int bitPos;
483
484 /// <summary>
485 /// Default constructor, initialize the bit packer / bit unpacker
486 /// with a byte array and starting position
487 /// </summary>
488 /// <param name="data">Byte array to pack bits in to or unpack from</param>
489 /// <param name="pos">Starting position in the byte array</param>
490 public BitPacker(byte[] data, int pos)
491 {
492 Data = data;
493 bytePos = pos;
494 }
495
496 /// <summary>
497 /// Pack a floating point value in to the data
498 /// </summary>
499 /// <param name="data">Floating point value to pack</param>
500 public void PackFloat(float data)
501 {
502 byte[] input = BitConverter.GetBytes(data);
503 PackBitArray(input, 32);
504 }
505
506 /// <summary>
507 /// Pack part or all of an integer in to the data
508 /// </summary>
509 /// <param name="data">Integer containing the data to pack</param>
510 /// <param name="totalCount">Number of bits of the integer to pack</param>
511 public void PackBits(int data, int totalCount)
512 {
513 byte[] input = BitConverter.GetBytes(data);
514 PackBitArray(input, totalCount);
515 }
516
517 /// <summary>
518 /// Unpacking a floating point value from the data
519 /// </summary>
520 /// <returns>Unpacked floating point value</returns>
521 public float UnpackFloat()
522 {
523 byte[] output = UnpackBitsArray(32);
524
525 if (!BitConverter.IsLittleEndian) Array.Reverse(output);
526 return BitConverter.ToSingle(output, 0);
527 }
528
529 /// <summary>
530 /// Unpack a variable number of bits from the data in to integer format
531 /// </summary>
532 /// <param name="totalCount">Number of bits to unpack</param>
533 /// <returns>An integer containing the unpacked bits</returns>
534 /// <remarks>This function is only useful up to 32 bits</remarks>
535 public int UnpackBits(int totalCount)
536 {
537 byte[] output = UnpackBitsArray(totalCount);
538
539 if (!BitConverter.IsLittleEndian) Array.Reverse(output);
540 return BitConverter.ToInt32(output, 0);
541 }
542
543 private void PackBitArray(byte[] data, int totalCount)
544 {
545 int count = 0;
546 int curBytePos = 0;
547 int curBitPos = 0;
548
549 while (totalCount > 0)
550 {
551 if (totalCount > (MAX_BITS ))
552 {
553 count = MAX_BITS ;
554 totalCount -= MAX_BITS ;
555 }
556 else
557 {
558 count = totalCount;
559 totalCount = 0;
560 }
561
562 while (count > 0)
563 {
564 switch(count)
565 {
566 case 1:
567 if ((data[curBytePos] & (0x01)) != 0)
568 {
569 Data[bytePos] |= (byte)(0x80 >> bitPos);
570 }
571 break;
572 case 2:
573 if ((data[curBytePos] & (0x02)) != 0)
574 {
575 Data[bytePos] |= (byte)(0x80 >> bitPos);
576 }
577 break;
578 case 3:
579 if ((data[curBytePos] & (0x04)) != 0)
580 {
581 Data[bytePos] |= (byte)(0x80 >> bitPos);
582 }
583 break;
584 case 4:
585 if ((data[curBytePos] & (0x08)) != 0)
586 {
587 Data[bytePos] |= (byte)(0x80 >> bitPos);
588 }
589 break;
590 case 5:
591 if ((data[curBytePos] & (0x10)) != 0)
592 {
593 Data[bytePos] |= (byte)(0x80 >> bitPos);
594 }
595 break;
596 case 6:
597 if ((data[curBytePos] & (0x20)) != 0)
598 {
599 Data[bytePos] |= (byte)(0x80 >> bitPos);
600 }
601 break;
602 case 7:
603 if ((data[curBytePos] & (0x40)) != 0)
604 {
605 Data[bytePos] |= (byte)(0x80 >> bitPos);
606 }
607 break;
608 case 8:
609 if ((data[curBytePos] & (0x80)) != 0)
610 {
611 Data[bytePos] |= (byte)(0x80 >> bitPos);
612 }
613 break;
614 }
615
616 bitPos++;
617 --count;
618 ++curBitPos;
619
620 if (bitPos >= MAX_BITS)
621 {
622 bitPos = 0;
623 ++bytePos;
624 }
625 if (curBitPos >= MAX_BITS)
626 {
627 curBitPos = 0;
628 ++curBytePos;
629 }
630 }
631 }
632 }
633
634
635 private byte[] UnpackBitsArray(int totalCount)
636 {
637 int count = 0;
638 byte[] output = new byte[4];
639 int curBytePos = 0;
640 int curBitPos = 0;
641
642 while (totalCount > 0)
643 {
644 if (totalCount > MAX_BITS)
645 {
646 count = MAX_BITS;
647 totalCount -= MAX_BITS;
648 }
649 else
650 {
651 count = totalCount;
652 totalCount = 0;
653 }
654
655 while (count > 0)
656 {
657 // Shift the previous bits
658 output[curBytePos] <<= 1;
659
660 // Grab one bit
661 if ((Data[bytePos] & (0x80 >> bitPos++)) != 0)
662 ++output[curBytePos];
663
664 --count;
665 ++curBitPos;
666
667 if (bitPos >= MAX_BITS)
668 {
669 bitPos = 0;
670 ++bytePos;
671 }
672 if (curBitPos >= MAX_BITS)
673 {
674 curBitPos = 0;
675 ++curBytePos;
676 }
677 }
678 }
679
680 return output;
681 }
682 }
683}
diff --git a/src/world/World.cs b/src/world/World.cs
index 83788cd..158ddc2 100644
--- a/src/world/World.cs
+++ b/src/world/World.cs
@@ -1,9 +1,9 @@
1using System; 1using System;
2using System.Threading; 2using System.Threading;
3using libsecondlife;
4using libsecondlife.Packets;
5using System.Collections.Generic; 3using System.Collections.Generic;
6using System.Text; 4using System.Text;
5using libsecondlife;
6using libsecondlife.Packets;
7 7
8namespace OpenSim.world 8namespace OpenSim.world
9{ 9{
@@ -12,77 +12,98 @@ namespace OpenSim.world
12 public Dictionary<libsecondlife.LLUUID, Entity> Entities; 12 public Dictionary<libsecondlife.LLUUID, Entity> Entities;
13 public float[] LandMap; 13 public float[] LandMap;
14 public ScriptEngine Scripts; 14 public ScriptEngine Scripts;
15 public TerrainDecode terrainengine = new TerrainDecode(); 15 public uint _localNumber = 0;
16 public uint _localNumber=0; 16 public PhysicsEngine physics;
17 public PhysicsEngine physics; 17
18 18 private libsecondlife.TerrainManager TerrainManager;
19 private Random Rand = new Random(); 19 private Random Rand = new Random();
20 20
21 public World() 21 public World()
22 { 22 {
23 OpenSim_Main.localcons.WriteLine("World.cs - creating new entitities instance"); 23 OpenSim_Main.localcons.WriteLine("World.cs - creating new entitities instance");
24 Entities = new Dictionary<libsecondlife.LLUUID, Entity>(); 24 Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
25
26 OpenSim_Main.localcons.WriteLine("World.cs - creating LandMap");
27 TerrainManager = new TerrainManager(new SecondLife());
28 }
25 29
26 OpenSim_Main.localcons.WriteLine("World.cs - creating LandMap"); 30 public void InitLoop()
27 terrainengine = new TerrainDecode(); 31 {
28 LandMap = new float[65536]; 32 OpenSim_Main.localcons.WriteLine("World.cs:StartLoop() - Initialising physics");
29 33 this.physics = new PhysicsEngine();
34 physics.Startup();
30 } 35 }
31 36
32 public void InitLoop() { 37 public void DoStuff()
33 OpenSim_Main.localcons.WriteLine("World.cs:StartLoop() - Initialising physics"); 38 {
34 this.physics = new PhysicsEngine(); 39 lock (this)
35 physics.Startup(); 40 {
36 } 41 physics.DoStuff(this);
37 42 this.Update();
38 public void DoStuff() { 43 }
39 lock(this) { 44 }
40 physics.DoStuff(this);
41 this.Update();
42 }
43 }
44 45
45 public void Update() { 46 public void Update()
47 {
46 foreach (libsecondlife.LLUUID UUID in Entities.Keys) 48 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
47 { 49 {
48 if(Entities[UUID].needupdate) { 50 if (Entities[UUID].needupdate)
49 Entities[UUID].update(); 51 {
50 52 Entities[UUID].update();
51 if(Entities[UUID] is Avatar) { 53
52 Avatar avatar=(Avatar)Entities[UUID]; 54 if (Entities[UUID] is Avatar)
53 if((avatar.oldpos!=avatar.position) || (avatar.oldvel!=avatar.velocity) || avatar.walking) { 55 {
54 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = Entities[UUID].CreateTerseBlock(); 56 Avatar avatar = (Avatar)Entities[UUID];
55 foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) { 57 if ((avatar.oldpos != avatar.position) || (avatar.oldvel != avatar.velocity) || avatar.walking)
56 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket(); 58 {
57 terse.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; // FIXME 59 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = Entities[UUID].CreateTerseBlock();
58 terse.RegionData.TimeDilation = 0; 60 foreach (OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values)
59 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; 61 {
60 terse.ObjectData[0] = terseBlock; 62 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
61 client.OutPacket(terse); 63 terse.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; // FIXME
62 } 64 terse.RegionData.TimeDilation = 0;
63 }} 65 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
64 } 66 terse.ObjectData[0] = terseBlock;
67 client.OutPacket(terse);
68 }
69 }
70 }
71 }
65 } 72 }
66 } 73 }
67 74
68 public void SendLayerData(OpenSimClient RemoteClient) { 75 public void SendLayerData(OpenSimClient RemoteClient)
69 for(int x=0; x<16; x=x+4) for(int y=0; y<16; y++){ 76 {
70 Packet layerpack=this.terrainengine.CreateLayerPacket(LandMap, x,y,x+4,y+1); 77 int[] patches = new int[4];
71 RemoteClient.OutPacket(layerpack);
72 }
73 }
74 78
75 public void AddViewerAgent(OpenSimClient AgentClient) { 79 for (int y = 0; y < 16; y++)
76 OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent"); 80 {
77 Avatar NewAvatar = new Avatar(AgentClient); 81 for (int x = 0; x < 16; x = x + 4)
78 OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Adding new avatar to world"); 82 {
79 this.Entities.Add(AgentClient.AgentID, NewAvatar); 83 patches[0] = x + 0 + y * 16;
80 OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Starting RegionHandshake "); 84 patches[1] = x + 1 + y * 16;
81 NewAvatar.SendRegionHandshake(this); 85 patches[2] = x + 2 + y * 16;
82 this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user 86 patches[3] = x + 3 + y * 16;
83 }
84 87
85 public bool Backup() { 88 Packet layerpack = TerrainManager.CreateLandPacket(LandMap, patches);
89 RemoteClient.OutPacket(layerpack);
90 }
91 }
92 }
93
94 public void AddViewerAgent(OpenSimClient AgentClient)
95 {
96 OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
97 Avatar NewAvatar = new Avatar(AgentClient);
98 OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Adding new avatar to world");
99 this.Entities.Add(AgentClient.AgentID, NewAvatar);
100 OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Starting RegionHandshake ");
101 NewAvatar.SendRegionHandshake(this);
102 this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user
103 }
104
105 public bool Backup()
106 {
86 /* TODO: Save the current world entities state. */ 107 /* TODO: Save the current world entities state. */
87 108
88 return false; 109 return false;