├── .gitignore
├── Assets
└── OctoMapSharp
│ ├── Bit.cs
│ ├── BitExtensions.cs
│ ├── BitStream.cs
│ ├── Int24.cs
│ ├── Int48.cs
│ └── OctoMap.cs
├── LICENSE
├── Packages
└── manifest.json
├── ProjectSettings
├── AudioManager.asset
├── ClusterInputManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshAreas.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── PresetManager.asset
├── ProjectSettings.asset
├── ProjectVersion.txt
├── QualitySettings.asset
├── TagManager.asset
├── TimeManager.asset
└── UnityConnectSettings.asset
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | [Ll]ibrary/
2 | [Tt]emp/
3 | [Oo]bj/
4 | [Bb]uild/
5 | [Bb]uilds/
6 | Assets/AssetStoreTools*
7 |
8 | # Visual Studio cache directory
9 | .vs/
10 | .idea/
11 |
12 | # Autogenerated VS/MD/Consulo solution and project files
13 | ExportedObj/
14 | .consulo/
15 | *.csproj
16 | *.unityproj
17 | *.sln
18 | *.suo
19 | *.tmp
20 | *.user
21 | *.userprefs
22 | *.pidb
23 | *.booproj
24 | *.svd
25 | *.pdb
26 | *.opendb
27 |
28 | # Unity3D generated meta files
29 | *.meta
30 |
31 | # Unity3D Generated File On Crash Reports
32 | sysinfo.txt
33 |
34 | # Builds
35 | *.apk
36 | *.unitypackage
37 | Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll
38 |
--------------------------------------------------------------------------------
/Assets/OctoMapSharp/Bit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OctoMapSharp
4 | {
5 | [Serializable]
6 | public struct Bit
7 | {
8 | private byte value;
9 |
10 | private Bit(int value)
11 | {
12 | this.value = (byte)(value & 1);
13 | }
14 |
15 | public static implicit operator Bit(int value)
16 | {
17 | return new Bit(value);
18 | }
19 |
20 | public static implicit operator Bit(bool value)
21 | {
22 | return new Bit(value ? 1 : 0);
23 | }
24 |
25 | public static implicit operator int (Bit bit)
26 | {
27 | return bit.value;
28 | }
29 |
30 | public static implicit operator byte (Bit bit)
31 | {
32 | return (byte)bit.value;
33 | }
34 |
35 | public static implicit operator bool (Bit bit)
36 | {
37 | return bit.value == 1;
38 | }
39 |
40 | public static Bit operator &(Bit x, Bit y)
41 | {
42 | return x.value & y.value;
43 | }
44 |
45 | public static Bit operator |(Bit x, Bit y)
46 | {
47 | return x.value | y.value;
48 | }
49 |
50 | public static Bit operator ^(Bit x, Bit y)
51 | {
52 | return x.value ^ y.value;
53 | }
54 |
55 | public static Bit operator ~(Bit bit)
56 | {
57 | return (~(bit.value) & 1);
58 | }
59 |
60 | public static implicit operator string (Bit bit)
61 | {
62 | return bit.value.ToString();
63 | }
64 |
65 | public int AsInt()
66 | {
67 | return this.value;
68 | }
69 |
70 | public bool AsBool()
71 | {
72 | return this.value == 1;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Assets/OctoMapSharp/BitExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace OctoMapSharp
2 | {
3 | public static class BitExtensions
4 | {
5 |
6 | #region GetBit
7 |
8 | public static Bit GetBit(this byte n, int index)
9 | {
10 | return n >> index;
11 | }
12 |
13 | public static Bit GetBit(this sbyte n, int index)
14 | {
15 | return n >> index;
16 | }
17 |
18 | public static Bit GetBit(this short n, int index)
19 | {
20 | return n >> index;
21 | }
22 |
23 | public static Bit GetBit(this ushort n, int index)
24 | {
25 | return n >> index;
26 | }
27 |
28 | public static Bit GetBit(this int n, int index)
29 | {
30 | return n >> index;
31 | }
32 |
33 | public static Bit GetBit(this uint n, int index)
34 | {
35 | return (byte)(n >> index);
36 | }
37 |
38 | public static Bit GetBit(this long n, int index)
39 | {
40 | return (byte)(n >> index);
41 | }
42 |
43 | public static Bit GetBit(this ulong n, int index)
44 | {
45 | return (byte)(n >> index);
46 | }
47 |
48 | #endregion
49 |
50 | #region CircularShift
51 |
52 | public static byte CircularShift(this byte n, int bits, bool leftShift)
53 | {
54 | if (leftShift)
55 | {
56 | n = (byte)(n << bits | n >> (8 - bits));
57 | }
58 | else
59 | {
60 | n = (byte)(n >> bits | n << (8 - bits));
61 | }
62 | return n;
63 | }
64 |
65 | public static sbyte CircularShift(this sbyte n, int bits, bool leftShift)
66 | {
67 | if (leftShift)
68 | {
69 | n = (sbyte)(n << bits | n >> (8 - bits));
70 | }
71 | else
72 | {
73 | n = (sbyte)(n >> bits | n << (8 - bits));
74 | }
75 | return n;
76 | }
77 |
78 | public static short CircularShift(this short n, int bits, bool leftShift)
79 | {
80 | if (leftShift)
81 | {
82 | n = (short)(n << bits | n >> (16 - bits));
83 | }
84 | else
85 | {
86 | n = (short)(n >> bits | n << (16 - bits));
87 | }
88 | return n;
89 | }
90 |
91 | public static ushort CircularShift(this ushort n, int bits, bool leftShift)
92 | {
93 | if (leftShift)
94 | {
95 | n = (ushort)(n << bits | n >> (16 - bits));
96 | }
97 | else
98 | {
99 | n = (ushort)(n >> bits | n << (16 - bits));
100 | }
101 | return n;
102 | }
103 |
104 | public static int CircularShift(this int n, int bits, bool leftShift)
105 | {
106 | if (leftShift)
107 | {
108 | n = (n << bits | n >> (32 - bits));
109 | }
110 | else
111 | {
112 | n = (n >> bits | n << (32 - bits));
113 | }
114 | return n;
115 | }
116 |
117 | public static uint CircularShift(this uint n, int bits, bool leftShift)
118 | {
119 | if (leftShift)
120 | {
121 | n = (uint)(n << bits | n >> (32 - bits));
122 | }
123 | else
124 | {
125 | n = (uint)(n >> bits | n << (32 - bits));
126 | }
127 | return n;
128 | }
129 |
130 | public static long CircularShift(this long n, int bits, bool leftShift)
131 | {
132 | if (leftShift)
133 | {
134 | n = (n << bits | n >> (64 - bits));
135 | }
136 | else
137 | {
138 | n = (n >> bits | n << (64 - bits));
139 | }
140 | return n;
141 | }
142 |
143 | public static ulong CircularShift(this ulong n, int bits, bool leftShift)
144 | {
145 | if (leftShift)
146 | {
147 | n = (ulong)(n << bits | n >> (64 - bits));
148 | }
149 | else
150 | {
151 | n = (ulong)(n >> bits | n << (64 - bits));
152 | }
153 | return n;
154 | }
155 |
156 | #endregion
157 |
158 | #region Reverse
159 |
160 | public static byte ReverseBits(this byte b)
161 | {
162 | return (byte)(((b & 1) << 7) + ((((b >> 1) & 1) << 6)) + (((b >> 2) & 1) << 5) + (((b >> 3) & 1) << 4) + (((b >> 4) & 1) << 3) +(((b >> 5) & 1) << 2) +(((b >> 6) & 1) << 1) + ((b >> 7)&1));
163 | }
164 |
165 | #endregion
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/Assets/OctoMapSharp/BitStream.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 |
6 | namespace OctoMapSharp
7 | {
8 | ///
9 | /// Stream wrapper to use bit-level operations
10 | ///
11 | public class BitStream
12 | {
13 | private long offset { get; set; }
14 | private int bit { get; set; }
15 | private bool MSB { get; set; }
16 | private Stream stream;
17 | private Encoding encoding;
18 |
19 | ///
20 | /// Allows the auto increase in size when needed
21 | ///
22 | public bool AutoIncreaseStream { get; set; }
23 |
24 | ///
25 | /// Get the stream length
26 | ///
27 | public long Length
28 | {
29 | get
30 | {
31 | return stream.Length;
32 | }
33 | }
34 |
35 | ///
36 | /// Get the current bit position in the stream
37 | ///
38 | public long BitPosition
39 | {
40 | get
41 | {
42 | return bit;
43 | }
44 | }
45 |
46 | ///
47 | /// Check if offset is inside the stream length
48 | ///
49 | private bool ValidPosition
50 | {
51 | get
52 | {
53 | return offset < Length;
54 | }
55 | }
56 |
57 | #region Constructors
58 |
59 | ///
60 | /// Creates a using a Stream
61 | ///
62 | /// Stream to use
63 | /// true if Most Significant Bit will be used, if false LSB will be used
64 | public BitStream(Stream stream, bool MSB = false)
65 | {
66 | this.stream = new MemoryStream();
67 | stream.CopyTo(this.stream);
68 | this.MSB = MSB;
69 | offset = 0;
70 | bit = 0;
71 | encoding = Encoding.UTF8;
72 | AutoIncreaseStream = false;
73 | }
74 |
75 | ///
76 | /// Creates a using a Stream
77 | ///
78 | /// Stream to use
79 | /// Encoding to use with chars
80 | /// true if Most Significant Bit will be used, if false LSB will be used
81 | public BitStream(Stream stream, Encoding encoding, bool MSB = false)
82 | {
83 | this.stream = new MemoryStream();
84 | stream.CopyTo(this.stream);
85 | this.MSB = MSB;
86 | offset = 0;
87 | bit = 0;
88 | this.encoding = encoding;
89 | AutoIncreaseStream = false;
90 | }
91 |
92 | ///
93 | /// Creates a using a byte[]
94 | ///
95 | /// byte[] to use
96 | /// true if Most Significant Bit will be used, if false LSB will be used
97 | public BitStream(byte[] buffer, bool MSB = false)
98 | {
99 | this.stream = new MemoryStream();
100 | MemoryStream m = new MemoryStream(buffer);
101 | m.CopyTo(this.stream);
102 | this.MSB = MSB;
103 | offset = 0;
104 | bit = 0;
105 | encoding = Encoding.UTF8;
106 | AutoIncreaseStream = false;
107 | }
108 |
109 | ///
110 | /// Creates a using a byte[]
111 | ///
112 | /// byte[] to use
113 | /// Encoding to use with chars
114 | /// true if Most Significant Bit will be used, if false LSB will be used
115 | public BitStream(byte[] buffer, Encoding encoding, bool MSB = false)
116 | {
117 | this.stream = new MemoryStream();
118 | MemoryStream m = new MemoryStream(buffer);
119 | m.CopyTo(this.stream);
120 | this.MSB = MSB;
121 | offset = 0;
122 | bit = 0;
123 | this.encoding = encoding;
124 | AutoIncreaseStream = false;
125 | }
126 |
127 | ///
128 | /// Creates a using a byte[]
129 | ///
130 | /// byte[] to use
131 | /// true if Most Significant Bit will be used, if false LSB will be used
132 | public static BitStream Create(byte[] buffer, bool MSB = false)
133 | {
134 | return new BitStream(buffer, MSB);
135 | }
136 |
137 | ///
138 | /// Creates a using a byte[]
139 | ///
140 | /// byte[] to use
141 | /// Encoding to use with chars/param>
142 | /// true if Most Significant Bit will be used, if false LSB will be used
143 | public static BitStream Create(byte[] buffer, Encoding encoding, bool MSB = false)
144 | {
145 | return new BitStream(buffer, encoding, MSB);
146 | }
147 |
148 | ///
149 | /// Creates a using a file path, throws IOException if file doesn't exists or path is not a file
150 | ///
151 | /// File path
152 | /// Encoding of the file, if null default will be used
153 | ///
154 | public static BitStream CreateFromFile(string path, Encoding encoding = null)
155 | {
156 | if (!File.Exists(path))
157 | {
158 | throw new IOException("File doesn't exists!");
159 | }
160 | if(File.GetAttributes(path) == FileAttributes.Directory)
161 | {
162 | throw new IOException("Path is a directory!");
163 | }
164 | if (encoding == null)
165 | {
166 | encoding = Encoding.UTF8;
167 | }
168 | return new BitStream(File.ReadAllBytes(path), encoding);
169 | }
170 |
171 | #endregion
172 |
173 | #region Methods
174 |
175 | ///
176 | /// Seek to the specified offset and check if it is a valid position for reading in the stream
177 | ///
178 | /// offset on the stream
179 | /// bit position
180 | /// true if offset is valid to do reading, false otherwise
181 | public bool this[long offset, int bit]
182 | {
183 | get
184 | {
185 | Seek(offset, bit);
186 | return ValidPosition;
187 | }
188 | //set {
189 | // Seek(offset, bit);
190 | //}
191 | private set { }
192 | }
193 |
194 | ///
195 | /// Seek through the stream selecting the offset and bit using
196 | ///
197 | /// offset on the stream
198 | /// bit position
199 | public void Seek(long offset, int bit)
200 | {
201 | if (offset > Length)
202 | {
203 | this.offset = Length;
204 | }
205 | else
206 | {
207 | if (offset >= 0)
208 | {
209 | this.offset = offset;
210 | }
211 | else
212 | {
213 | offset = 0;
214 | }
215 | }
216 | if (bit >= 8)
217 | {
218 | int n = (int)(bit / 8);
219 | this.offset += n;
220 | this.bit = bit % 8;
221 | }
222 | else
223 | {
224 | this.bit = bit;
225 | }
226 | stream.Seek(offset, SeekOrigin.Begin);
227 | }
228 |
229 | ///
230 | /// Advances the stream by one bit
231 | ///
232 | public void AdvanceBit()
233 | {
234 | bit = (bit + 1) % 8;
235 | if (bit == 0)
236 | {
237 | offset++;
238 | }
239 | }
240 |
241 | ///
242 | /// Returns the stream by one bit
243 | ///
244 | public void ReturnBit()
245 | {
246 | bit = ((bit - 1) == -1 ? 7 : bit - 1);
247 | if (bit == 7)
248 | {
249 | offset--;
250 | }
251 | if(offset < 0)
252 | {
253 | offset = 0;
254 | }
255 | }
256 |
257 | ///
258 | /// Get the edited stream
259 | ///
260 | /// Modified stream
261 | public Stream GetStream()
262 | {
263 | return stream;
264 | }
265 |
266 | ///
267 | /// Get the stream data as a byte[]
268 | ///
269 | /// Stream as byte[]
270 | public byte[] GetStreamData()
271 | {
272 | stream.Seek(0, SeekOrigin.Begin);
273 | MemoryStream s = new MemoryStream();
274 | stream.CopyTo(s);
275 | Seek(offset, bit);
276 | return s.ToArray();
277 | }
278 |
279 | ///
280 | /// Get the used for chars and strings
281 | ///
282 | /// used
283 | public Encoding GetEncoding()
284 | {
285 | return encoding;
286 | }
287 |
288 | ///
289 | /// Set the that will be used for chars and strings
290 | ///
291 | /// to use
292 | public void SetEncoding(Encoding encoding)
293 | {
294 | this.encoding = encoding;
295 | }
296 |
297 | ///
298 | /// Changes the length of the stream, if new length is less than current length stream data will be truncated
299 | ///
300 | /// New stream length
301 | /// return true if stream changed length, false if it wasn't possible
302 | public bool ChangeLength(long length)
303 | {
304 | if (stream.CanSeek && stream.CanWrite)
305 | {
306 | stream.SetLength(length);
307 | return true;
308 | }
309 | else
310 | {
311 | return false;
312 | }
313 | }
314 |
315 | ///
316 | /// Cuts the from the specified offset and given length, will throw an exception when length + offset is higher than stream's length, offset and bit will be set to 0
317 | ///
318 | /// Offset to start
319 | /// Length of the new
320 | public void CutStream(long offset, long length)
321 | {
322 | byte[] data = GetStreamData();
323 | byte[] buffer = new byte[length];
324 | Array.Copy(data, offset, buffer, 0, length);
325 | this.stream = new MemoryStream();
326 | MemoryStream m = new MemoryStream(buffer);
327 | this.stream = new MemoryStream();
328 | m.CopyTo(this.stream);
329 | this.offset = 0;
330 | bit = 0;
331 | }
332 |
333 | ///
334 | /// Copies the current buffer to another
335 | ///
336 | /// to copy buffer
337 | public void CopyStreamTo(Stream stream)
338 | {
339 | Seek(0, 0);
340 | stream.SetLength(this.stream.Length);
341 | this.stream.CopyTo(stream);
342 | }
343 |
344 | ///
345 | /// Copies the current buffer to another
346 | ///
347 | /// to copy buffer
348 | public void CopyStreamTo(BitStream stream)
349 | {
350 | Seek(0, 0);
351 | stream.ChangeLength(this.stream.Length);
352 | this.stream.CopyTo(stream.stream);
353 | stream.Seek(0, 0);
354 | }
355 |
356 | ///
357 | /// Saves current buffer into a file
358 | ///
359 | /// File to write data, if it exists it will be overwritten
360 | public void SaveStreamAsFile(string filename)
361 | {
362 | File.WriteAllBytes(filename, GetStreamData());
363 | }
364 |
365 | ///
366 | /// Returns the current content of the stream as a
367 | ///
368 | /// containing current data
369 | public MemoryStream CloneAsMemoryStream()
370 | {
371 | return new MemoryStream(GetStreamData());
372 | }
373 |
374 | ///
375 | /// Returns the current content of the stream as a
376 | ///
377 | /// containing current data
378 | public BufferedStream CloneAsBufferedStream()
379 | {
380 | BufferedStream bs = new BufferedStream(stream);
381 | StreamWriter sw = new StreamWriter(bs);
382 | sw.Write(GetStreamData());
383 | bs.Seek(0, SeekOrigin.Begin);
384 | return bs;
385 | }
386 |
387 |
388 | ///
389 | /// Checks if the will be in a valid position on its last bit read/write
390 | ///
391 | /// Number of bits it will advance
392 | /// true if will be inside the stream length
393 | private bool ValidPositionWhen(int bits)
394 | {
395 | long o = offset;
396 | int b = bit;
397 | b = (b + 1) % 8;
398 | if (b == 0)
399 | {
400 | o++;
401 | }
402 | return o < Length;
403 | }
404 |
405 |
406 | #endregion
407 |
408 | #region BitRead/Write
409 |
410 | ///
411 | /// Read current position bit and advances the position within the stream by one bit
412 | ///
413 | /// Returns the current position bit as 0 or 1
414 | public Bit ReadBit()
415 | {
416 | if (!ValidPosition)
417 | {
418 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
419 | }
420 | stream.Seek(offset, SeekOrigin.Begin);
421 | byte value;
422 | if (!MSB)
423 | {
424 | value = (byte)((stream.ReadByte() >> (bit)) & 1);
425 | }
426 | else
427 | {
428 | value = (byte)((stream.ReadByte() >> (7 - bit)) & 1);
429 | }
430 | AdvanceBit();
431 | stream.Seek(offset, SeekOrigin.Begin);
432 | return value;
433 | }
434 |
435 | ///
436 | /// Read from current position the specified number of bits
437 | ///
438 | /// Bits to read
439 | /// [] containing read bits
440 | public Bit[] ReadBits(int length)
441 | {
442 | Bit[] bits = new Bit[length];
443 | for(int i=0;i< length; i++)
444 | {
445 | bits[i] = ReadBit();
446 | }
447 | return bits;
448 | }
449 |
450 | ///
451 | /// Writes a bit in the current position
452 | ///
453 | /// Bit to write, it data is not 0 or 1 data = data & 1
454 | public void WriteBit(Bit data)
455 | {
456 | stream.Seek(offset, SeekOrigin.Begin);
457 | byte value = (byte)stream.ReadByte();
458 | stream.Seek(offset, SeekOrigin.Begin);
459 | if (!MSB)
460 | {
461 | value &= (byte)~(1 << bit);
462 | value |= (byte)(data << bit);
463 | }
464 | else
465 | {
466 | value &= (byte)~(1 << (7 - bit));
467 | value |= (byte)(data << (7 - bit));
468 | }
469 | if (ValidPosition)
470 | {
471 | stream.WriteByte(value);
472 | }
473 | else
474 | {
475 | if (AutoIncreaseStream)
476 | {
477 | if (ChangeLength(Length + (offset - Length) + 1))
478 | {
479 | stream.WriteByte(value);
480 | }
481 | else
482 | {
483 | throw new IOException("Cannot write in an offset bigger than the length of the stream");
484 | }
485 | }
486 | else
487 | {
488 | throw new IOException("Cannot write in an offset bigger than the length of the stream");
489 | }
490 | }
491 | AdvanceBit();
492 | stream.Seek(offset, SeekOrigin.Begin);
493 | }
494 |
495 | ///
496 | /// Write a sequence of bits into the stream
497 | ///
498 | /// [] to write
499 | public void WriteBits(ICollection bits)
500 | {
501 | foreach(Bit b in bits)
502 | {
503 | WriteBit(b);
504 | }
505 | }
506 |
507 | ///
508 | /// Write a sequence of bits into the stream
509 | ///
510 | /// [] to write
511 | /// Number of bits to write
512 | public void WriteBits(ICollection bits, int length)
513 | {
514 | Bit[] b = new Bit[bits.Count];
515 | bits.CopyTo(b, 0);
516 | for (int i=0;i< length;i++)
517 | {
518 | WriteBit(b[i]);
519 | }
520 | }
521 |
522 | ///
523 | /// Write a sequence of bits into the stream
524 | ///
525 | /// [] to write
526 | /// Offset to begin bit writing
527 | /// Number of bits to write
528 | public void WriteBits(Bit[] bits, int offset, int length)
529 | {
530 | for (int i = offset; i < length; i++)
531 | {
532 | WriteBit(bits[i]);
533 | }
534 | }
535 |
536 | #endregion
537 |
538 | #region Read
539 |
540 | ///
541 | /// Read from the current position bit the specified number of bits or bytes and creates a byte[]
542 | ///
543 | /// Number of bits or bytes
544 | /// if true will consider length as byte length, if false it will count the specified length of bits
545 | /// byte[] containing bytes created from current position
546 | public byte[] ReadBytes(long length, bool isBytes = false)
547 | {
548 | if (isBytes)
549 | {
550 | length *= 8;
551 | }
552 | List data = new List();
553 | for (long i = 0; i < length;)
554 | {
555 | byte value = 0;
556 | for (int p = 0; p < 8 && i < length; i++, p++)
557 | {
558 | if (!MSB)
559 | {
560 | value |= (byte)(ReadBit() << p);
561 | }
562 | else
563 | {
564 | value |= (byte)(ReadBit() << (7 - p));
565 | }
566 | }
567 | data.Add(value);
568 | }
569 | return data.ToArray();
570 | }
571 |
572 | ///
573 | /// Read a byte based on the current stream and bit position
574 | ///
575 | public byte ReadByte()
576 | {
577 | return ReadBytes(8)[0];
578 | }
579 |
580 | ///
581 | /// Read a byte made of specified number of bits (1-8)
582 | ///
583 | public byte ReadByte(int bits)
584 | {
585 | if (bits < 0)
586 | {
587 | bits = 0;
588 | }
589 | if(bits > 8)
590 | {
591 | bits = 8;
592 | }
593 | return ReadBytes(bits)[0];
594 | }
595 |
596 | ///
597 | /// Read a signed byte based on the current stream and bit position
598 | ///
599 | public sbyte ReadSByte()
600 | {
601 | return (sbyte)ReadBytes(8)[0];
602 | }
603 |
604 | ///
605 | /// Read a sbyte made of specified number of bits (1-8)
606 | ///
607 | public sbyte ReadSByte(int bits)
608 | {
609 | if (bits < 0)
610 | {
611 | bits = 0;
612 | }
613 | if (bits > 8)
614 | {
615 | bits = 8;
616 | }
617 | return (sbyte)ReadBytes(bits)[0];
618 | }
619 |
620 | ///
621 | /// Read a byte based on the current stream and bit position and check if it is 0
622 | ///
623 | public bool ReadBool()
624 | {
625 | return ReadBytes(8)[0] == 0 ? false : true;
626 | }
627 |
628 | ///
629 | /// Read a char based on the current stream and bit position and the encoding
630 | ///
631 | public char ReadChar()
632 | {
633 | return encoding.GetChars(ReadBytes(encoding.GetMaxByteCount(1) * 8))[0];
634 | }
635 |
636 | ///
637 | /// Read a string based on the current stream and bit position and the encoding
638 | ///
639 | /// Length of the string to read
640 | public string ReadString(int length)
641 | {
642 | int bitsPerChar = encoding.GetByteCount(" ") * 8;
643 | return encoding.GetString(ReadBytes(bitsPerChar*length));
644 | }
645 |
646 | ///
647 | /// Read a short based on the current stream and bit position
648 | ///
649 | public short ReadInt16()
650 | {
651 | short value = BitConverter.ToInt16(ReadBytes(16), 0);
652 | return value;
653 | }
654 |
655 | ///
656 | /// Read a 24bit value based on the current stream and bit position
657 | ///
658 | public Int24 ReadInt24()
659 | {
660 | byte[] bytes = ReadBytes(24);
661 | Array.Resize(ref bytes, 4);
662 | Int24 value = BitConverter.ToInt32(bytes, 0);
663 | return value;
664 | }
665 |
666 | ///
667 | /// Read an int based on the current stream and bit position
668 | ///
669 | public int ReadInt32()
670 | {
671 | int value = BitConverter.ToInt32(ReadBytes(32), 0);
672 | return value;
673 | }
674 |
675 | ///
676 | /// Read a 48bit value based on the current stream and bit position
677 | ///
678 | public Int48 ReadInt48()
679 | {
680 | byte[] bytes = ReadBytes(48);
681 | Array.Resize(ref bytes, 8);
682 | Int48 value = BitConverter.ToInt64(bytes, 0);
683 | return value;
684 | }
685 |
686 | ///
687 | /// Read a long based on the current stream and bit position
688 | ///
689 | public long ReadInt64()
690 | {
691 | long value = BitConverter.ToInt64(ReadBytes(64), 0);
692 | return value;
693 | }
694 |
695 | ///
696 | /// Read a ushort based on the current stream and bit position
697 | ///
698 | public ushort ReadUInt16()
699 | {
700 | ushort value = BitConverter.ToUInt16(ReadBytes(16), 0);
701 | return value;
702 | }
703 |
704 | ///
705 | /// Read an unsigned 24bit value based on the current stream and bit position
706 | ///
707 | public UInt24 ReadUInt24()
708 | {
709 | byte[] bytes = ReadBytes(24);
710 | Array.Resize(ref bytes, 4);
711 | UInt24 value = BitConverter.ToUInt32(bytes, 0);
712 | return value;
713 | }
714 |
715 | ///
716 | /// Read an uint based on the current stream and bit position
717 | ///
718 | public uint ReadUInt32()
719 | {
720 | uint value = BitConverter.ToUInt32(ReadBytes(32), 0);
721 | return value;
722 | }
723 |
724 | ///
725 | /// Read an unsigned 48bit value based on the current stream and bit position
726 | ///
727 | public UInt48 ReadUInt48()
728 | {
729 | byte[] bytes = ReadBytes(48);
730 | Array.Resize(ref bytes, 8);
731 | UInt48 value = BitConverter.ToUInt64(bytes, 0);
732 | return value;
733 | }
734 |
735 | ///
736 | /// Read an ulong based on the current stream and bit position
737 | ///
738 | public ulong ReadUInt64()
739 | {
740 | ulong value = BitConverter.ToUInt64(ReadBytes(64), 0);
741 | return value;
742 | }
743 |
744 | #endregion
745 |
746 | #region Write
747 |
748 | ///
749 | /// Writes as bits a byte[] by a specified number of bits or bytes
750 | ///
751 | /// byte[] to write
752 | /// Number of bits or bytes to use from the array
753 | /// if true will consider length as byte length, if false it will count the specified length of bits
754 | public void WriteBytes(byte[] data, long length, bool isBytes = false)
755 | {
756 | if (isBytes)
757 | {
758 | length *= 8;
759 | }
760 | int position = 0;
761 | for (long i = 0; i < length;)
762 | {
763 | byte value = 0;
764 | for (int p = 0; p < 8 && i < length; i++, p++)
765 | {
766 | if (!MSB)
767 | {
768 | value = (byte)((data[position] >> p) & 1);
769 | }
770 | else
771 | {
772 | value = (byte)((data[position] >> (7 - p)) & 1);
773 | }
774 | WriteBit(value);
775 | }
776 | position++;
777 | }
778 | }
779 |
780 | ///
781 | /// Write a byte value based on the current stream and bit position
782 | ///
783 | public void WriteByte(byte value)
784 | {
785 | WriteBytes(new byte[] { value }, 8);
786 | }
787 |
788 | ///
789 | /// Write a byte value based on the current stream and bit position
790 | ///
791 | public void WriteByte(byte value, int bits)
792 | {
793 | if (bits < 0)
794 | {
795 | bits = 0;
796 | }
797 | if (bits > 8)
798 | {
799 | bits = 8;
800 | }
801 | WriteBytes(new byte[] { value }, bits);
802 | }
803 |
804 | ///
805 | /// Write a byte value based on the current stream and bit position
806 | ///
807 | public void WriteSByte(sbyte value)
808 | {
809 | WriteBytes(new byte[] { (byte)value }, 8);
810 | }
811 |
812 | ///
813 | /// Write a byte value based on the current stream and bit position
814 | ///
815 | public void WriteSByte(sbyte value, int bits)
816 | {
817 | if (bits < 0)
818 | {
819 | bits = 0;
820 | }
821 | if (bits > 8)
822 | {
823 | bits = 8;
824 | }
825 | WriteBytes(new byte[] { (byte)value }, bits);
826 | }
827 |
828 | ///
829 | /// Write a bool value as 0:false, 1:true as byte based on the current stream and bit position
830 | ///
831 | public void WriteBool(bool value)
832 | {
833 | WriteBytes(new byte[] { value ? (byte)1 : (byte)0 }, 8);
834 | }
835 |
836 | ///
837 | /// Write a char value based on the encoding
838 | ///
839 | public void WriteChar(char value)
840 | {
841 | byte[] bytes = encoding.GetBytes(new char[] { value }, 0, 1);
842 | WriteBytes(bytes, bytes.Length*8);
843 | }
844 |
845 | ///
846 | /// Write a string based on the encoding
847 | ///
848 | public void WriteString(string value)
849 | {
850 | byte[] bytes = encoding.GetBytes(value);
851 | WriteBytes(bytes, bytes.Length * 8);
852 | }
853 |
854 | ///
855 | /// Write a short value based on the current stream and bit position
856 | ///
857 | public void WriteInt16(short value)
858 | {
859 | WriteBytes(BitConverter.GetBytes(value), 16);
860 | }
861 |
862 | ///
863 | /// Write a 24bit value based on the current stream and bit position
864 | ///
865 | public void WriteInt24(Int24 value)
866 | {
867 | WriteBytes(BitConverter.GetBytes((int) value), 24);
868 | }
869 |
870 | ///
871 | /// Write an int value based on the current stream and bit position
872 | ///
873 | public void WriteInt32(int value)
874 | {
875 | WriteBytes(BitConverter.GetBytes(value), 32);
876 | }
877 |
878 | ///
879 | /// Write a 48bit value based on the current stream and bit position
880 | ///
881 | public void WriteInt48(Int48 value)
882 | {
883 | WriteBytes(BitConverter.GetBytes((long) value), 48);
884 | }
885 |
886 | ///
887 | /// Write a long value based on the current stream and bit position
888 | ///
889 | public void WriteInt64(long value)
890 | {
891 | WriteBytes(BitConverter.GetBytes(value), 64);
892 | }
893 |
894 | ///
895 | /// Write an ushort value based on the current stream and bit position
896 | ///
897 | public void WriteUInt16(ushort value)
898 | {
899 | WriteBytes(BitConverter.GetBytes(value), 16);
900 | }
901 |
902 | ///
903 | /// Write an unsigned 24bit value based on the current stream and bit position
904 | ///
905 | public void WriteUInt24(UInt24 value)
906 | {
907 | WriteBytes(BitConverter.GetBytes((uint) value), 24);
908 | }
909 |
910 | ///
911 | /// Write an uint value based on the current stream and bit position
912 | ///
913 | public void WriteUInt32(uint value)
914 | {
915 | WriteBytes(BitConverter.GetBytes(value), 32);
916 | }
917 |
918 | ///
919 | /// Write an unsigned 48bit value based on the current stream and bit position
920 | ///
921 | public void WriteUInt48(UInt48 value)
922 | {
923 | WriteBytes(BitConverter.GetBytes((ulong) value), 48);
924 | }
925 |
926 | ///
927 | /// Write an ulong value based on the current stream and bit position
928 | ///
929 | public void WriteUInt64(ulong value)
930 | {
931 | WriteBytes(BitConverter.GetBytes(value), 64);
932 | }
933 |
934 | #endregion
935 |
936 | #region Shifts
937 |
938 | ///
939 | /// Do a bitwise shift on the current position of the stream on bit 0
940 | ///
941 | /// bits to shift
942 | /// true to left shift, false to right shift
943 | public void bitwiseShift(int bits, bool leftShift)
944 | {
945 | if (!ValidPositionWhen(8))
946 | {
947 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
948 | }
949 | Seek(offset, 0);
950 | if (bits != 0 && bits <= 7)
951 | {
952 | byte value = (byte)stream.ReadByte();
953 | if (leftShift)
954 | {
955 | value = (byte)(value << bits);
956 | }
957 | else
958 | {
959 | value = (byte)(value >> bits);
960 | }
961 | Seek(offset, 0);
962 | stream.WriteByte(value);
963 | }
964 | bit = 0;
965 | offset++;
966 | }
967 |
968 | ///
969 | /// Do a bitwise shift on the current position of the stream on current bit
970 | ///
971 | /// bits to shift
972 | /// true to left shift, false to right shift
973 | public void bitwiseShiftOnBit(int bits, bool leftShift)
974 | {
975 | if (!ValidPositionWhen(8))
976 | {
977 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
978 | }
979 | Seek(offset, bit);
980 | if (bits != 0 && bits <= 7)
981 | {
982 | byte value = ReadByte();
983 | if (leftShift)
984 | {
985 | value = (byte)(value << bits);
986 | }
987 | else
988 | {
989 | value = (byte)(value >> bits);
990 | }
991 | offset--;
992 | Seek(offset, bit);
993 | WriteByte(value);
994 | }
995 | offset++;
996 | }
997 |
998 | ///
999 | /// Do a circular shift on the current position of the stream on bit 0
1000 | ///
1001 | /// bits to shift
1002 | /// true to left shift, false to right shift
1003 | public void circularShift(int bits, bool leftShift)
1004 | {
1005 | if (!ValidPositionWhen(8))
1006 | {
1007 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1008 | }
1009 | Seek(offset, 0);
1010 | if (bits != 0 && bits <= 7)
1011 | {
1012 | byte value = (byte)stream.ReadByte();
1013 | if (leftShift)
1014 | {
1015 | value = (byte)(value << bits | value >> (8 - bits));
1016 | }
1017 | else
1018 | {
1019 | value = (byte)(value >> bits | value << (8 - bits));
1020 | }
1021 | Seek(offset, 0);
1022 | stream.WriteByte(value);
1023 | }
1024 | bit = 0;
1025 | offset++;
1026 | }
1027 |
1028 | ///
1029 | /// Do a circular shift on the current position of the stream on current bit
1030 | ///
1031 | /// bits to shift
1032 | /// true to left shift, false to right shift
1033 | public void circularShiftOnBit(int bits, bool leftShift)
1034 | {
1035 | if (!ValidPositionWhen(8))
1036 | {
1037 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1038 | }
1039 | Seek(offset, bit);
1040 | if (bits != 0 && bits <= 7)
1041 | {
1042 | byte value = ReadByte();
1043 | if (leftShift)
1044 | {
1045 | value = (byte)(value << bits | value >> (8 - bits));
1046 | }
1047 | else
1048 | {
1049 | value = (byte)(value >> bits | value << (8 - bits));
1050 | }
1051 | offset--;
1052 | Seek(offset, bit);
1053 | WriteByte(value);
1054 | }
1055 | offset++;
1056 | }
1057 |
1058 | #endregion
1059 |
1060 | #region Bitwise Operators
1061 |
1062 | ///
1063 | /// Apply an and operator on the current stream and bit position byte and advances one byte position
1064 | ///
1065 | /// Byte value to apply and
1066 | public void And(byte x)
1067 | {
1068 | if (!ValidPositionWhen(8))
1069 | {
1070 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1071 | }
1072 | Seek(offset, bit);
1073 | byte value = ReadByte();
1074 | offset--;
1075 | Seek(offset, bit);
1076 | WriteByte((byte)(value & x));
1077 | }
1078 |
1079 | ///
1080 | /// Apply an or operator on the current stream and bit position byte and advances one byte position
1081 | ///
1082 | /// Byte value to apply or
1083 | public void Or(byte x)
1084 | {
1085 | if (!ValidPositionWhen(8))
1086 | {
1087 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1088 | }
1089 | Seek(offset, bit);
1090 | byte value = ReadByte();
1091 | offset--;
1092 | Seek(offset, bit);
1093 | WriteByte((byte)(value | x));
1094 | }
1095 |
1096 | ///
1097 | /// Apply a xor operator on the current stream and bit position byte and advances one byte position
1098 | ///
1099 | /// Byte value to apply xor
1100 | public void Xor(byte x)
1101 | {
1102 | if (!ValidPositionWhen(8))
1103 | {
1104 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1105 | }
1106 | Seek(offset, bit);
1107 | byte value = ReadByte();
1108 | offset--;
1109 | Seek(offset, bit);
1110 | WriteByte((byte)(value ^ x));
1111 | }
1112 |
1113 | ///
1114 | /// Apply a not operator on the current stream and bit position byte and advances one byte position
1115 | ///
1116 | public void Not()
1117 | {
1118 | if (!ValidPositionWhen(8))
1119 | {
1120 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1121 | }
1122 | Seek(offset, bit);
1123 | byte value = ReadByte();
1124 | offset--;
1125 | Seek(offset, bit);
1126 | WriteByte((byte)(~value));
1127 | }
1128 |
1129 | ///
1130 | /// Apply an and operator on the current stream and bit position and advances one bit position
1131 | ///
1132 | /// Bit value to apply and
1133 | public void BitAnd(Bit x)
1134 | {
1135 | if (!ValidPosition)
1136 | {
1137 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1138 | }
1139 | Seek(offset, bit);
1140 | Bit value = ReadBit();
1141 | ReturnBit();
1142 | WriteBit(x & value);
1143 | }
1144 |
1145 | ///
1146 | /// Apply an or operator on the current stream and bit position and advances one bit position
1147 | ///
1148 | /// Bit value to apply or
1149 | public void BitOr(Bit x)
1150 | {
1151 | if (!ValidPosition)
1152 | {
1153 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1154 | }
1155 | Seek(offset, bit);
1156 | Bit value = ReadBit();
1157 | ReturnBit();
1158 | WriteBit(x | value);
1159 | }
1160 |
1161 | ///
1162 | /// Apply a xor operator on the current stream and bit position and advances one bit position
1163 | ///
1164 | /// Bit value to apply xor
1165 | public void BitXor(Bit x)
1166 | {
1167 | if (!ValidPosition)
1168 | {
1169 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1170 | }
1171 | Seek(offset, bit);
1172 | Bit value = ReadBit();
1173 | ReturnBit();
1174 | WriteBit(x ^ value);
1175 | }
1176 |
1177 | ///
1178 | /// Apply a not operator on the current stream and bit position and advances one bit position
1179 | ///
1180 | public void BitNot()
1181 | {
1182 | if (!ValidPosition)
1183 | {
1184 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1185 | }
1186 | Seek(offset, bit);
1187 | Bit value = ReadBit();
1188 | ReturnBit();
1189 | WriteBit(~value);
1190 | }
1191 |
1192 | ///
1193 | /// Reverses the bit order on the byte in the current position of the stream
1194 | ///
1195 | public void ReverseBits()
1196 | {
1197 | if (!ValidPosition)
1198 | {
1199 | throw new IOException("Cannot read in an offset bigger than the length of the stream");
1200 | }
1201 | Seek(offset, 0);
1202 | byte value = ReadByte();
1203 | offset--;
1204 | Seek(offset, 0);
1205 | WriteByte(value.ReverseBits());
1206 | }
1207 |
1208 | #endregion
1209 |
1210 | }
1211 | }
1212 |
--------------------------------------------------------------------------------
/Assets/OctoMapSharp/Int24.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OctoMapSharp
4 | {
5 | ///
6 | /// Represents a 24-bit signed integer
7 | ///
8 | [Serializable]
9 | public struct Int24
10 | {
11 | private byte b0, b1, b2;
12 | private Bit sign;
13 |
14 | private Int24(int value)
15 | {
16 | this.b0 = (byte)(value & 0xFF);
17 | this.b1 = (byte)((value >> 8) & 0xFF);
18 | this.b2 = (byte)((value >> 16) & 0x7F);
19 | this.sign = (byte)((value >> 23) & 1);
20 | }
21 |
22 | public static implicit operator Int24(int value)
23 | {
24 | return new Int24(value);
25 | }
26 |
27 | public static implicit operator int (Int24 i)
28 | {
29 | int value = (i.b0 | (i.b1 << 8) | (i.b2 << 16));
30 | return -(i.sign << 23) + value;
31 | }
32 |
33 | public Bit GetBit(int index)
34 | {
35 | return (this >> index);
36 | }
37 | }
38 |
39 | ///
40 | /// Represents a 24-bit unsigned integer
41 | ///
42 | [Serializable]
43 | public struct UInt24
44 | {
45 | private byte b0, b1, b2;
46 |
47 | private UInt24(uint value)
48 | {
49 | this.b0 = (byte)(value & 0xFF);
50 | this.b1 = (byte)((value >> 8) & 0xFF);
51 | this.b2 = (byte)((value >> 16) & 0xFF);
52 | }
53 |
54 | public static implicit operator UInt24(uint value)
55 | {
56 | return new UInt24(value);
57 | }
58 |
59 | public static implicit operator uint (UInt24 i)
60 | {
61 | return (uint)(i.b0 | (i.b1 << 8) | (i.b2 << 16));
62 | }
63 |
64 | public Bit GetBit(int index)
65 | {
66 | return (byte)(this >> index);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Assets/OctoMapSharp/Int48.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OctoMapSharp
4 | {
5 | ///
6 | /// Represents a 48-bit signed integer
7 | ///
8 | [Serializable]
9 | public struct Int48
10 | {
11 | private byte b0, b1, b2, b3, b4, b5;
12 | private Bit sign;
13 |
14 | private Int48(long value)
15 | {
16 | this.b0 = (byte)(value & 0xFF);
17 | this.b1 = (byte)((value >> 8) & 0xFF);
18 | this.b2 = (byte)((value >> 16) & 0xFF);
19 | this.b3 = (byte)((value >> 24) & 0xFF);
20 | this.b4 = (byte)((value >> 32) & 0xFF);
21 | this.b5 = (byte)((value >> 40) & 0x7F);
22 | this.sign = (byte)((value >> 47) & 1);
23 | }
24 |
25 | public static implicit operator Int48(long value)
26 | {
27 | return new Int48(value);
28 | }
29 |
30 | public static implicit operator long (Int48 i)
31 | {
32 | long value = i.b0 + (i.b1 << 8) + (i.b2 << 16) + ((long)i.b3 << 24) + ((long)i.b4 << 32) + ((long)i.b5 << 40);
33 | return -((long)i.sign << 47) + value;
34 | }
35 |
36 | public Bit GetBit(int index)
37 | {
38 | return (byte)(this >> index);
39 | }
40 | }
41 |
42 | ///
43 | /// Represents a 48-bit unsigned integer
44 | ///
45 | [Serializable]
46 | public struct UInt48
47 | {
48 | private byte b0, b1, b2, b3, b4, b5;
49 |
50 | private UInt48(ulong value)
51 | {
52 | this.b0 = (byte)(value & 0xFF);
53 | this.b1 = (byte)((value >> 8) & 0xFF);
54 | this.b2 = (byte)((value >> 16) & 0xFF);
55 | this.b3 = (byte)((value >> 24) & 0xFF);
56 | this.b4 = (byte)((value >> 32) & 0xFF);
57 | this.b5 = (byte)((value >> 40) & 0xFF);
58 | }
59 |
60 | public static implicit operator UInt48(ulong value)
61 | {
62 | return new UInt48(value);
63 | }
64 |
65 | public static implicit operator ulong (UInt48 i)
66 | {
67 | ulong value = (i.b0 + ((ulong)i.b1 << 8) + ((ulong)i.b2 << 16) + ((ulong)i.b3 << 24) + ((ulong)i.b4 << 32) + ((ulong)i.b5 << 40));
68 | return value;
69 | }
70 |
71 | public Bit GetBit(int index)
72 | {
73 | return (byte)(this >> index);
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/Assets/OctoMapSharp/OctoMap.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | namespace OctoMapSharp
5 | {
6 | public class OctoMapRaw
7 | {
8 | ///
9 | /// An array containing the centre position of every occupied node in the OctoMap
10 | ///
11 | public Vector3[] Positions { get; }
12 | ///
13 | /// An array containing the size of every occupied node in the OctoMap
14 | ///
15 | public float[] Sizes { get; }
16 |
17 | ///
18 | /// Constructor for the OctoMapRaw. Sets the public properties of the instance.
19 | ///
20 | /// The array of node positions
21 | /// The array of node sizes
22 | public OctoMapRaw(Vector3[] positions, float[] sizes)
23 | {
24 | Positions = positions;
25 | Sizes = sizes;
26 | }
27 | }
28 |
29 | public class OctoMapCompact
30 | {
31 | ///
32 | /// The number of occupied voxels within the octomap.
33 | ///
34 | public uint OccupiedVoxelCount { get; set; }
35 |
36 | ///
37 | /// The origin position of the OctoMap. Individual node positions are derived from this root position.
38 | ///
39 | public Vector3 RootNodePosition { get; set; }
40 |
41 | ///
42 | /// The size of the root node.
43 | ///
44 | public float RootNodeSize { get; set; }
45 |
46 | ///
47 | /// The minimum size a node can get when traversing through the OctoMap.
48 | ///
49 | public float MinimumNodeSize { get; set; }
50 |
51 | ///
52 | /// The compact BitStream containing all the parent-child relationships in the OctoMap.
53 | ///
54 | public byte[] BitStream { get; set; }
55 |
56 | ///
57 | /// Constructor for the compact OctoMap. Sets the public properties of the class.
58 | ///
59 | /// The number of occupied voxels within the octomap
60 | /// The position of the root node
61 | /// The size of the root node
62 | /// The minimum node size within the octomap
63 | /// The compact bitstream
64 | public OctoMapCompact(uint occupiedVoxelCount, Vector3 rootNodePosition, float rootNodeSize, float minimumNodeSize, byte[] bitStream)
65 | {
66 | OccupiedVoxelCount = occupiedVoxelCount;
67 | RootNodePosition = rootNodePosition;
68 | RootNodeSize = rootNodeSize;
69 | MinimumNodeSize = minimumNodeSize;
70 | BitStream = bitStream;
71 | }
72 | }
73 |
74 | public class OctoMap
75 | {
76 | ///
77 | /// A node within the OctoMap which can contain a pointer to an array of child nodes.
78 | /// Can also contain additional per-node information.
79 | ///
80 | private struct OctoMapNode
81 | {
82 | ///
83 | /// The index of the dictionary entry in '_nodeChildren' which contains an array of indexes to this nodes children.
84 | ///
85 | public uint? ChildArrayId { get; set; }
86 |
87 | ///
88 | /// The most basic way of representing a nodes occupancy: binary. -1 is unoccupied, 0 is unknown, 1 is occupied.
89 | ///
90 | public int Occupied { get; set; }
91 | }
92 |
93 | ///
94 | /// The number of occupied voxels within the octomap
95 | ///
96 | private uint _occupiedVoxelCount;
97 |
98 | ///
99 | /// Is true if the octomap has changed in some way since the last time 'HasChanged()' was called.
100 | ///
101 | private bool _hasChanged;
102 |
103 | ///
104 | /// The origin position of the OctoMap. Individual node positions are derived from this root position.
105 | ///
106 | private Vector3 _rootNodePosition;
107 |
108 | ///
109 | /// The current size of the root node which can increase if data is added.
110 | ///
111 | private float _rootNodeSize;
112 |
113 | ///
114 | /// The minimum size a node can get when traversing through the OctoMap.
115 | ///
116 | private readonly float _minimumNodeSize;
117 |
118 | ///
119 | /// Each node in the OctoMap along with an unique index accessor.
120 | ///
121 | private readonly Dictionary _nodes;
122 |
123 | ///
124 | /// Nodes with children have an entry in this dictionary with the value containing an array of node IDs.
125 | ///
126 | private readonly Dictionary _nodeChildren;
127 |
128 | ///
129 | /// The accessor index for the root node.
130 | ///
131 | private uint _rootNodeId;
132 |
133 | ///
134 | /// The current highest index in the nodes dictionary, used to keep every index unique.
135 | /// This solution works because potential duplicate indexes will only occur when we get near to
136 | /// the max uint value, but long before this happens the memory consumption will be the big issue.
137 | ///
138 | private uint _nodeHighestIndex;
139 |
140 | ///
141 | /// The current highest index in the node children dictionary, used to keep every index unique.
142 | ///
143 | private uint _nodeChildrenHighestIndex;
144 |
145 | ///
146 | /// Initialise an empty OctoMap.
147 | ///
148 | /// The starting position of the root node of the OctoMap.
149 | /// The starting size of the root node of the OctoMap.
150 | /// The minimum size of a node.
151 | public OctoMap(Vector3 startingRootNodePosition, float startingRootNodeSize, float minimumNodeSize)
152 | {
153 | _nodes = new Dictionary();
154 | _nodeChildren = new Dictionary();
155 |
156 | _rootNodePosition = startingRootNodePosition;
157 | _rootNodeSize = startingRootNodeSize;
158 | _minimumNodeSize = minimumNodeSize;
159 |
160 | _rootNodeId = _nodeHighestIndex++;
161 | _nodes[_rootNodeId] = new OctoMapNode();
162 | }
163 |
164 | ///
165 | /// Initialize an OctoMap from a compact instance.
166 | ///
167 | /// The compact instance that the OctoMap will be created from.
168 | public OctoMap(OctoMapCompact octoMapCompact)
169 | {
170 | _nodes = new Dictionary();
171 | _nodeChildren = new Dictionary();
172 |
173 | _rootNodePosition = octoMapCompact.RootNodePosition;
174 | _rootNodeSize = octoMapCompact.RootNodeSize;
175 | _minimumNodeSize = octoMapCompact.MinimumNodeSize;
176 | _occupiedVoxelCount = octoMapCompact.OccupiedVoxelCount;
177 |
178 | BitStream bitStream = new BitStream(octoMapCompact.BitStream);
179 |
180 | OctoMapNode rootNode = new OctoMapNode();
181 | _rootNodeId = _nodeHighestIndex++;
182 | _nodes.Add(_rootNodeId, rootNode);
183 |
184 | BuildOctoMapFromBitStreamRecursive(bitStream, _rootNodeId);
185 | }
186 |
187 | #region Compact bit stream
188 |
189 | ///
190 | /// Converts the OctoMap in memory to a compact bitstream data structure.
191 | ///
192 | /// The compact bitstream.
193 | public OctoMapCompact ConvertToOctoMapCompact()
194 | {
195 | // Number of bytes will be number of child node arrays multiplied by 2
196 | // (each item in the array is a node with children and each node takes up 2 bytes)
197 | int streamLength = _nodeChildren.Count * 2;
198 |
199 | BitStream bitStream = new BitStream(new byte[streamLength]);
200 | ConvertToBitStreamRecursive(bitStream, _rootNodeId);
201 | return new OctoMapCompact(_occupiedVoxelCount, _rootNodePosition, _rootNodeSize, _minimumNodeSize, bitStream.GetStreamData());
202 | }
203 |
204 | ///
205 | /// Recursive function that traverses through node children and writes the relationships to a compact bit stream.
206 | ///
207 | /// The bitstream to write to.
208 | /// The node ID the current recursive traversal is on.
209 | private void ConvertToBitStreamRecursive(BitStream bitStream, uint currentNodeId)
210 | {
211 | OctoMapNode currentNode = _nodes[currentNodeId];
212 | if (currentNode.ChildArrayId != null)
213 | {
214 | // Build up the current nodes bit stream based on status of its children
215 | for (int i = 0; i < 8; i++)
216 | {
217 | OctoMapNode childNode = _nodes[_nodeChildren[currentNode.ChildArrayId.Value][i]];
218 | if (childNode.ChildArrayId != null) // INNER NODE
219 | {
220 | bitStream.WriteBit(1);
221 | bitStream.WriteBit(1);
222 | }
223 | else if (CheckNodeFree(childNode)) // FREE
224 | {
225 | bitStream.WriteBit(1);
226 | bitStream.WriteBit(0);
227 | }
228 | else if (CheckNodeOccupied(childNode)) // OCCUPIED
229 | {
230 | bitStream.WriteBit(0);
231 | bitStream.WriteBit(1);
232 | }
233 | else // UNKNOWN
234 | {
235 | bitStream.WriteBit(0);
236 | bitStream.WriteBit(0);
237 | }
238 | }
239 |
240 | for (int i = 0; i < 8; i++)
241 | {
242 | uint childId = _nodeChildren[currentNode.ChildArrayId.Value][i];
243 | ConvertToBitStreamRecursive(bitStream, childId);
244 | }
245 | }
246 | }
247 |
248 | ///
249 | /// Builds the node and child nodes dictionaries by traversing through the compact bitstream.
250 | ///
251 | /// The bitstream to traverse
252 | /// The node ID the current recursive traversal is on.
253 | private void BuildOctoMapFromBitStreamRecursive(BitStream bitStream, uint currentNodeId)
254 | {
255 | // Create child nodes of this current node
256 | uint[] childIdArray = new uint[8];
257 | for (int i = 0; i < 8; i++)
258 | {
259 | uint childNodeId = _nodeHighestIndex++;
260 | _nodes.Add(childNodeId, new OctoMapNode());
261 | childIdArray[i] = childNodeId;
262 | }
263 |
264 | // Add child ids to dictionary
265 | uint childArrayId = _nodeChildrenHighestIndex++;
266 | _nodeChildren.Add(childArrayId, childIdArray);
267 |
268 | // Create node and add child array linkage
269 | OctoMapNode currentNode = _nodes[currentNodeId];
270 | currentNode.ChildArrayId = childArrayId;
271 | _nodes[currentNodeId] = currentNode;
272 |
273 | // Correctly set the state of each of the children created
274 | List innerNodeChildren = new List();
275 | for (int i = 0; i < 8; i++)
276 | {
277 | int firstBit = bitStream.ReadBit().AsInt();
278 | int secondBit = bitStream.ReadBit().AsInt();
279 |
280 | OctoMapNode childNode;
281 | if (firstBit == 1 && secondBit == 1) // INNER NODE
282 | {
283 | innerNodeChildren.Add(childIdArray[i]);
284 | }
285 | else if (firstBit == 0 && secondBit == 1) // OCCUPIED
286 | {
287 | childNode = _nodes[childIdArray[i]];
288 | _nodes[childIdArray[i]] = IncreaseNodeOccupation(childNode);
289 | }
290 | else if (firstBit == 1 && secondBit == 0) // FREE
291 | {
292 | childNode = _nodes[childIdArray[i]];
293 | _nodes[childIdArray[i]] = DecreaseNodeOccupation(childNode);
294 | }
295 |
296 | // else UNKNOWN
297 | }
298 |
299 | // Now loop through each child that is an inner node
300 | for (int i = 0; i < innerNodeChildren.Count; i++)
301 | {
302 | BuildOctoMapFromBitStreamRecursive(bitStream, innerNodeChildren[i]);
303 | }
304 | }
305 |
306 | #endregion
307 |
308 | #region Query OctoMap
309 |
310 | ///
311 | /// Check if a Ray intersects any nodes in the OctoMap and returns the smallest node that it intersects.
312 | ///
313 | /// The ray that will be used in the intersection query.
314 | /// A nullable vector3 that is the centre of the node that it hit (if it hit anything).
315 | public Vector3? GetRayIntersection(Ray ray)
316 | {
317 | return GetRayIntersectionRecursive(ref ray, _rootNodeSize, _rootNodePosition, _rootNodeId);
318 | }
319 |
320 | ///
321 | /// Recursive function that traverses through nodes in order to check for a ray intersection.
322 | ///
323 | /// The ray that will be used in the intersection query.
324 | /// The node size the current recursive traversal is on.
325 | /// The node centre the current recursive traversal is on.
326 | /// The node ID the current recursive traversal is on.
327 | ///
328 | private Vector3? GetRayIntersectionRecursive(ref Ray ray, float currentNodeSize, Vector3 currentNodeCentre,
329 | uint currentNodeId)
330 | {
331 | // Check if the ray intersects the current nodes bounds
332 | Bounds bounds = new Bounds(currentNodeCentre,
333 | new Vector3(currentNodeSize, currentNodeSize, currentNodeSize));
334 | if (!bounds.IntersectRay(ray))
335 | {
336 | return null;
337 | }
338 |
339 | // If the ray intersects the current node, check if the current node is occupied
340 | OctoMapNode currentNode = _nodes[currentNodeId];
341 | if (CheckNodeOccupied(currentNode))
342 | {
343 | return currentNodeCentre;
344 | }
345 |
346 | // If the ray intersects the current node but the node is not occupied, check its children if it has any
347 | if (currentNode.ChildArrayId != null)
348 | {
349 | for (int i = 0; i < 8; i++)
350 | {
351 | uint childId = _nodeChildren[currentNode.ChildArrayId.Value][i];
352 | float newNodeSize = currentNodeSize / 2;
353 | Vector3 newNodeCentre = GetBestFitChildNodeCentre(i, newNodeSize, currentNodeCentre);
354 |
355 | Vector3? intersectedNodeCentre =
356 | GetRayIntersectionRecursive(ref ray, newNodeSize, newNodeCentre, childId);
357 | if (intersectedNodeCentre != null)
358 | {
359 | return intersectedNodeCentre;
360 | }
361 | }
362 | }
363 |
364 | return null;
365 | }
366 |
367 | #endregion
368 |
369 | #region Contribute To The Octomap
370 |
371 | ///
372 | /// Adds a point to the OctoMap which will mark a specific node as occupied.
373 | ///
374 | /// The 3D point to add to the OctoMap.
375 | public void AddPoint(Vector3 point)
376 | {
377 | int growCount = 0;
378 | while (true)
379 | {
380 | // Check if the root node encompasses this point. If it does, start the recursive adding process
381 | Bounds bounds = new Bounds(_rootNodePosition, new Vector3(_rootNodeSize, _rootNodeSize, _rootNodeSize));
382 | if (bounds.Contains(point))
383 | {
384 | AddPointRecursive(ref point, _rootNodeSize, _rootNodePosition, _rootNodeId);
385 | _hasChanged = true;
386 | return;
387 | }
388 |
389 | // If the root node doesn't encompass the point, grow the OctoMap
390 | GrowOctomap(point - _rootNodePosition);
391 | growCount++;
392 |
393 | if (growCount > 20)
394 | {
395 | Debug.Log("Aborted add operation as it seemed to be going on forever (" + (growCount - 1) +
396 | ") attempts at growing the OctoMap.");
397 | return;
398 | }
399 | }
400 | }
401 |
402 | ///
403 | /// The recursive function that adds a new point to the OctoMap.
404 | ///
405 | /// The point to add to the OctoMap.
406 | /// The node size the current recursive traversal is on.
407 | /// The node centre the current recursive traversal is on.
408 | /// The node ID the current recursive traversal is on.
409 | private void AddPointRecursive(ref Vector3 point, float currentNodeSize, Vector3 currentNodeCentre,
410 | uint currentNodeId)
411 | {
412 | OctoMapNode node = _nodes[currentNodeId];
413 |
414 | // If we're at the deepest level possible, this current node becomes a leaf node.
415 | if (currentNodeSize < _minimumNodeSize)
416 | {
417 | // If not already occupied increment the counter
418 | if (!CheckNodeOccupied(_nodes[currentNodeId]))
419 | {
420 | _occupiedVoxelCount++;
421 | }
422 | _nodes[currentNodeId] = IncreaseNodeOccupation(node);
423 | return;
424 | }
425 |
426 | // If the node doesn't encompass this point, return out early
427 | Bounds bounds = new Bounds(currentNodeCentre,
428 | new Vector3(currentNodeSize, currentNodeSize, currentNodeSize));
429 | if (!bounds.Contains(point))
430 | return;
431 |
432 | // If this node doesn't have any children, new children need to be generated
433 | if (node.ChildArrayId == null)
434 | {
435 | node.ChildArrayId = GenerateChildren();
436 | _nodes[currentNodeId] = node;
437 | }
438 |
439 | Debug.Assert(_nodes[currentNodeId].ChildArrayId != null);
440 |
441 | // Now handle the new object we're adding now
442 | int bestFitChild = BestFitChildIndex(point, currentNodeCentre);
443 | uint childNodeId = _nodeChildren[node.ChildArrayId.Value][bestFitChild];
444 |
445 | float newNodeSize = currentNodeSize / 2;
446 | Vector3 newNodeCentre = GetBestFitChildNodeCentre(bestFitChild, newNodeSize, currentNodeCentre);
447 |
448 | AddPointRecursive(ref point, newNodeSize, newNodeCentre, childNodeId);
449 |
450 | // Loop through all children and check if they all share the same occupied state
451 | bool childrenOccupancy = false;
452 | for (int i = 0; i < 8; i++)
453 | {
454 | OctoMapNode child = _nodes[_nodeChildren[node.ChildArrayId.Value][i]];
455 | if (child.ChildArrayId != null)
456 | {
457 | return;
458 | }
459 |
460 | bool occupancy = CheckNodeOccupied(child);
461 |
462 | if (i == 0)
463 | {
464 | childrenOccupancy = occupancy;
465 | }
466 | else
467 | {
468 | if (occupancy != childrenOccupancy)
469 | {
470 | return;
471 | }
472 | }
473 | }
474 |
475 | // If the code reaches here that means all the children share the same state
476 | // Remove all the child nodes
477 | for (int i = 0; i < 8; i++)
478 | {
479 | var childArrayId = _nodes[currentNodeId].ChildArrayId;
480 | if (childArrayId != null)
481 | {
482 | uint childId = _nodeChildren[childArrayId.Value][i];
483 | _nodes.Remove(childId);
484 | _occupiedVoxelCount--;
485 | }
486 | else
487 | {
488 | Debug.Log("Failed to remove node from node dictionary");
489 | }
490 | }
491 |
492 | var arrayId = _nodes[currentNodeId].ChildArrayId;
493 | if (arrayId != null)
494 | {
495 | // Remove the node children array
496 | _nodeChildren.Remove(arrayId.Value);
497 | _occupiedVoxelCount++;
498 | }
499 | else
500 | {
501 | Debug.Log("Failed to remove child array from child dictionary.");
502 | }
503 |
504 | // Set the current nodes occupancy state to that of its children
505 | OctoMapNode currentNode = _nodes[currentNodeId];
506 | currentNode.ChildArrayId = null;
507 | currentNode = childrenOccupancy ? IncreaseNodeOccupation(currentNode) : DecreaseNodeOccupation(currentNode);
508 |
509 | _nodes[currentNodeId] = currentNode;
510 | }
511 |
512 | ///
513 | /// Adds a ray to the OctoMap which will set any nodes along its path to free.
514 | ///
515 | /// The origin of the ray
516 | /// The 3D point that the ray has hit
517 | public void AddRayToOctoMap(Vector3 originPoint, Vector3 recordedPoint)
518 | {
519 | Ray ray = new Ray(originPoint, (recordedPoint - originPoint).normalized);
520 | AddRayToOctoMap(ray, recordedPoint, _rootNodeSize, _rootNodePosition, _rootNodeId);
521 | }
522 |
523 | ///
524 | /// The recursive function that adds any intersecting nodes along this ray to the octomap
525 | ///
526 | /// The ray that will be used to check intersections against
527 | /// The recorded point that the ray hit
528 | /// The node size the current recursive traversal is on.
529 | /// The node centre the current recursive traversal is on.
530 | /// The node ID the current recursive traversal is on.
531 | private void AddRayToOctoMap(Ray ray, Vector3 recordedPoint, float currentNodeSize, Vector3 currentNodeCentre,
532 | uint currentNodeId)
533 | {
534 | OctoMapNode currentNode = _nodes[currentNodeId];
535 |
536 | // If this node is a leaf node
537 | if (currentNodeSize < _minimumNodeSize)
538 | {
539 | // Do not check this ray against the node that shares the same centre as the registered point
540 | if (recordedPoint == currentNodeCentre)
541 | {
542 | return;
543 | }
544 |
545 | // Mark this leaf node as free
546 | _nodes[currentNodeId] = DecreaseNodeOccupation(currentNode);
547 | return;
548 | }
549 |
550 | // Generate some children if the current node doesn't have any
551 | if (currentNode.ChildArrayId == null)
552 | {
553 | currentNode.ChildArrayId = GenerateChildren();
554 | _nodes[currentNodeId] = currentNode;
555 | }
556 |
557 | // Recursively call this function on each of this current nodes children
558 | for (int i = 0; i < 8; i++)
559 | {
560 | uint childId = _nodeChildren[currentNode.ChildArrayId.Value][i];
561 | float newNodeSize = currentNodeSize / 2;
562 | Vector3 newNodeCentre = GetBestFitChildNodeCentre(i, newNodeSize, currentNodeCentre);
563 |
564 | Bounds bounds = new Bounds(newNodeCentre, new Vector3(newNodeSize, newNodeSize, newNodeSize));
565 | if (bounds.IntersectRay(ray))
566 | {
567 | AddRayToOctoMap(ray, recordedPoint, newNodeSize, newNodeCentre, childId);
568 | }
569 | }
570 | }
571 |
572 | #endregion
573 |
574 | #region Get Nodes
575 |
576 | ///
577 | /// Returns a list of the octomap leaf nodes with each node having a position and size
578 | ///
579 | /// The list of octomap nodes
580 | public OctoMapRaw GetOctoMapNodes()
581 | {
582 | List positions = new List();
583 | List sizes = new List();
584 | GatherOctoMapNodes(positions, sizes, _rootNodeSize, _rootNodePosition, _rootNodeId);
585 | return new OctoMapRaw(positions.ToArray(), sizes.ToArray());
586 | }
587 |
588 | ///
589 | /// Recursively traverses though the octomap in order to find leaf nodes and then adds them to a list
590 | ///
591 | /// The list of node of node centre positions
592 | /// The list of node sizes
593 | /// The node size the current recursive traversal is on.
594 | /// The node centre the current recursive traversal is on.
595 | /// The node ID the current recursive traversal is on.
596 | private void GatherOctoMapNodes(List positions, List sizes, float currentNodeSize,
597 | Vector3 currentNodeCentre,
598 | uint currentNodeId)
599 | {
600 | OctoMapNode currentNode = _nodes[currentNodeId];
601 | if (CheckNodeOccupied(currentNode))
602 | {
603 | positions.Add(currentNodeCentre);
604 | sizes.Add(currentNodeSize);
605 | }
606 |
607 | if (currentNode.ChildArrayId != null)
608 | {
609 | for (int i = 0; i < 8; i++)
610 | {
611 | uint childId = _nodeChildren[currentNode.ChildArrayId.Value][i];
612 | float newNodeSize = currentNodeSize / 2;
613 | Vector3 newNodeCentre = GetBestFitChildNodeCentre(i, newNodeSize, currentNodeCentre);
614 | GatherOctoMapNodes(positions, sizes, newNodeSize, newNodeCentre, childId);
615 | }
616 | }
617 | }
618 |
619 | #endregion
620 |
621 | #region Node Evaluation
622 |
623 | ///
624 | /// Sets the occupied state of a node to 1. Can be extended further.
625 | ///
626 | /// The node to set the occupied state on
627 | /// The same node but with the occupied state changed
628 | private static OctoMapNode IncreaseNodeOccupation(OctoMapNode octoMapNode)
629 | {
630 | octoMapNode.Occupied = 1;
631 | return octoMapNode;
632 | }
633 |
634 | ///
635 | /// Sets the occupied state of a node to -1. Can be extended further.
636 | ///
637 | /// The node to set the occupied state on
638 | /// The same node but with the occupied state changed
639 | private static OctoMapNode DecreaseNodeOccupation(OctoMapNode octoMapNode)
640 | {
641 | octoMapNode.Occupied = -1;
642 | return octoMapNode;
643 | }
644 |
645 | ///
646 | /// Returns true or false depending on whether a specific node is occupied. Can be extended further.
647 | ///
648 | /// The node that will be checked
649 | /// True or false depending on whether a specific node is occupied.
650 | private static bool CheckNodeOccupied(OctoMapNode octoMapNode)
651 | {
652 | return octoMapNode.Occupied >= 1;
653 | }
654 |
655 | ///
656 | /// Returns true or false depending on whether a specific node is not occupied. Can be extended further.
657 | ///
658 | /// The node that will be checked
659 | /// True or false depending on whether a specific node is not occupied.
660 | private static bool CheckNodeFree(OctoMapNode octoMapNode)
661 | {
662 | return octoMapNode.Occupied <= -1;
663 | }
664 |
665 | #endregion
666 |
667 | #region Helper Functions
668 |
669 | ///
670 | /// Expand the root node to encompass any additional added points by specifying the direction that it needs
671 | ///
672 | /// The direction that the OctoMap needs to grow in
673 | private void GrowOctomap(Vector3 direction)
674 | {
675 | int xDirection = direction.x >= 0 ? 1 : -1;
676 | int yDirection = direction.y >= 0 ? 1 : -1;
677 | int zDirection = direction.z >= 0 ? 1 : -1;
678 |
679 | uint oldRoot = _rootNodeId;
680 | float half = _rootNodeSize / 2;
681 |
682 | _rootNodeSize = _rootNodeSize * 2;
683 | _rootNodePosition =
684 | _rootNodePosition + new Vector3(xDirection * half, yDirection * half, zDirection * half);
685 |
686 | // Create a new, bigger octomap root node
687 | _rootNodeId = _nodeHighestIndex++;
688 | _nodes.Add(_rootNodeId, new OctoMapNode());
689 |
690 | // Create 7 new octomap children to go with the old root as children of the new root
691 | int rootPos = GetRootPosIndex(xDirection, yDirection, zDirection);
692 | uint[] childIds = new uint[8];
693 | for (int i = 0; i < 8; i++)
694 | {
695 | if (i == rootPos)
696 | {
697 | childIds[i] = oldRoot;
698 | }
699 | else
700 | {
701 | uint childNodeId = _nodeHighestIndex++;
702 | _nodes.Add(childNodeId, new OctoMapNode());
703 | childIds[i] = childNodeId;
704 | }
705 | }
706 |
707 | // Add child ids to dict
708 | uint childId = _nodeChildrenHighestIndex++;
709 | _nodeChildren.Add(childId, childIds);
710 |
711 | // Attach the new children to the new root node
712 | OctoMapNode node = _nodes[_rootNodeId];
713 | node.ChildArrayId = childId;
714 | _nodes[_rootNodeId] = node;
715 | }
716 |
717 | ///
718 | /// This function generates 8 new nodes, adds them to the dictionaries, and returns the accessor index of item
719 | ///
720 | /// The accessor index of the new node child dictionary item
721 | private uint GenerateChildren()
722 | {
723 | uint[] childIdArray = new uint[8];
724 | for (int i = 0; i < 8; i++)
725 | {
726 | uint childNodeId = _nodeHighestIndex++;
727 | _nodes.Add(childNodeId, new OctoMapNode());
728 | childIdArray[i] = childNodeId;
729 | }
730 |
731 | uint childArrayId = _nodeChildrenHighestIndex++;
732 | _nodeChildren.Add(childArrayId, childIdArray); // Add child ids
733 | return childArrayId;
734 | }
735 |
736 | ///
737 | /// Used when growing the octomap. Works out where the old root node would fit inside a new, larger root node.
738 | ///
739 | /// The XDir that the child is in
740 | /// The YDir that the child is in
741 | /// The ZDir that the child is in
742 | /// The array index that this child in this direction has
743 | private static int GetRootPosIndex(int xDir, int yDir, int zDir)
744 | {
745 | int result = xDir > 0 ? 1 : 0;
746 | if (yDir < 0) result += 4;
747 | if (zDir > 0) result += 2;
748 | return result;
749 | }
750 |
751 | ///
752 | /// Returns the index of the child that is the best fit for a point within a specific node
753 | ///
754 | /// The point that will be checked
755 | /// The node that the point will be checked against
756 | /// The index that of the child
757 | private static int BestFitChildIndex(Vector3 point, Vector3 currentNodeCentre)
758 | {
759 | return (point.x <= currentNodeCentre.x ? 0 : 1) + (point.y >= currentNodeCentre.y ? 0 : 4) +
760 | (point.z <= currentNodeCentre.z ? 0 : 2);
761 | }
762 |
763 | ///
764 | /// Returns the position of a child of a specific node at a specific index
765 | ///
766 | /// The child index of the node
767 | /// The size of the child node
768 | /// The position of the parent node
769 | /// The position of the child
770 | private static Vector3 GetBestFitChildNodeCentre(int childIndex, float childSize, Vector3 parentPosition)
771 | {
772 | float quarter = childSize / 4f;
773 |
774 | switch (childIndex)
775 | {
776 | case 0:
777 | return parentPosition + new Vector3(-quarter, quarter, -quarter);
778 | case 1:
779 | return parentPosition + new Vector3(quarter, quarter, -quarter);
780 | case 2:
781 | return parentPosition + new Vector3(-quarter, quarter, quarter);
782 | case 3:
783 | return parentPosition + new Vector3(quarter, quarter, quarter);
784 | case 4:
785 | return parentPosition + new Vector3(-quarter, -quarter, -quarter);
786 | case 5:
787 | return parentPosition + new Vector3(quarter, -quarter, -quarter);
788 | case 6:
789 | return parentPosition + new Vector3(-quarter, -quarter, quarter);
790 | case 7:
791 | return parentPosition + new Vector3(quarter, -quarter, quarter);
792 | }
793 |
794 | Debug.Log("Failed to determine best fit child node centre.");
795 | return Vector3.zero;
796 | }
797 |
798 | #endregion
799 |
800 | #region Public Accessors
801 |
802 | ///
803 | /// Returns the number of occupied voxels within the octomap.
804 | ///
805 | /// The number of voxels that are occupied within the octomap.
806 | public uint GetOccupiedVoxelCount()
807 | {
808 | return _occupiedVoxelCount;
809 | }
810 |
811 | ///
812 | /// Returns true if the octomap has changed in some way (one or more new points have been added) since the last time this function was called.
813 | ///
814 | ///
815 | public bool HasChanged()
816 | {
817 | bool hasChanged = _hasChanged;
818 | _hasChanged = false;
819 | return hasChanged;
820 | }
821 |
822 | #endregion
823 | }
824 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Alex Scott
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Packages/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "com.unity.ads": "2.0.8",
4 | "com.unity.analytics": "2.0.16",
5 | "com.unity.package-manager-ui": "1.9.11",
6 | "com.unity.purchasing": "2.0.3",
7 | "com.unity.textmeshpro": "1.2.4",
8 | "com.unity.modules.ai": "1.0.0",
9 | "com.unity.modules.animation": "1.0.0",
10 | "com.unity.modules.assetbundle": "1.0.0",
11 | "com.unity.modules.audio": "1.0.0",
12 | "com.unity.modules.cloth": "1.0.0",
13 | "com.unity.modules.director": "1.0.0",
14 | "com.unity.modules.imageconversion": "1.0.0",
15 | "com.unity.modules.imgui": "1.0.0",
16 | "com.unity.modules.jsonserialize": "1.0.0",
17 | "com.unity.modules.particlesystem": "1.0.0",
18 | "com.unity.modules.physics": "1.0.0",
19 | "com.unity.modules.physics2d": "1.0.0",
20 | "com.unity.modules.screencapture": "1.0.0",
21 | "com.unity.modules.terrain": "1.0.0",
22 | "com.unity.modules.terrainphysics": "1.0.0",
23 | "com.unity.modules.tilemap": "1.0.0",
24 | "com.unity.modules.ui": "1.0.0",
25 | "com.unity.modules.uielements": "1.0.0",
26 | "com.unity.modules.umbra": "1.0.0",
27 | "com.unity.modules.unityanalytics": "1.0.0",
28 | "com.unity.modules.unitywebrequest": "1.0.0",
29 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
30 | "com.unity.modules.unitywebrequestaudio": "1.0.0",
31 | "com.unity.modules.unitywebrequesttexture": "1.0.0",
32 | "com.unity.modules.unitywebrequestwww": "1.0.0",
33 | "com.unity.modules.vehicles": "1.0.0",
34 | "com.unity.modules.video": "1.0.0",
35 | "com.unity.modules.vr": "1.0.0",
36 | "com.unity.modules.wind": "1.0.0",
37 | "com.unity.modules.xr": "1.0.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!11 &1
4 | AudioManager:
5 | m_ObjectHideFlags: 0
6 | m_Volume: 1
7 | Rolloff Scale: 1
8 | Doppler Factor: 1
9 | Default Speaker Mode: 2
10 | m_SampleRate: 0
11 | m_DSPBufferSize: 1024
12 | m_VirtualVoiceCount: 512
13 | m_RealVoiceCount: 32
14 | m_SpatializerPlugin:
15 | m_AmbisonicDecoderPlugin:
16 | m_DisableAudio: 0
17 | m_VirtualizeEffects: 1
18 |
--------------------------------------------------------------------------------
/ProjectSettings/ClusterInputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!236 &1
4 | ClusterInputManager:
5 | m_ObjectHideFlags: 0
6 | m_Inputs: []
7 |
--------------------------------------------------------------------------------
/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!55 &1
4 | PhysicsManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_Gravity: {x: 0, y: -9.81, z: 0}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_BounceThreshold: 2
10 | m_SleepThreshold: 0.005
11 | m_DefaultContactOffset: 0.01
12 | m_DefaultSolverIterations: 6
13 | m_DefaultSolverVelocityIterations: 1
14 | m_QueriesHitBackfaces: 0
15 | m_QueriesHitTriggers: 1
16 | m_EnableAdaptiveForce: 0
17 | m_ClothInterCollisionDistance: 0
18 | m_ClothInterCollisionStiffness: 0
19 | m_ContactsGeneration: 1
20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
21 | m_AutoSimulation: 1
22 | m_AutoSyncTransforms: 1
23 | m_ClothInterCollisionSettingsToggle: 0
24 | m_ContactPairsMode: 0
25 | m_BroadphaseType: 0
26 | m_WorldBounds:
27 | m_Center: {x: 0, y: 0, z: 0}
28 | m_Extent: {x: 250, y: 250, z: 250}
29 | m_WorldSubdivisions: 8
30 |
--------------------------------------------------------------------------------
/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1045 &1
4 | EditorBuildSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Scenes:
8 | - enabled: 1
9 | path: Assets/Scenes/SampleScene.unity
10 | guid: 99c9720ab356a0642a771bea13969a05
11 | m_configObjects: {}
12 |
--------------------------------------------------------------------------------
/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!159 &1
4 | EditorSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_ExternalVersionControlSupport: Visible Meta Files
8 | m_SerializationMode: 2
9 | m_LineEndingsForNewScripts: 2
10 | m_DefaultBehaviorMode: 0
11 | m_SpritePackerMode: 0
12 | m_SpritePackerPaddingPower: 1
13 | m_EtcTextureCompressorBehavior: 1
14 | m_EtcTextureFastCompressor: 1
15 | m_EtcTextureNormalCompressor: 2
16 | m_EtcTextureBestCompressor: 4
17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef
18 | m_ProjectGenerationRootNamespace:
19 | m_UserGeneratedProjectSuffix:
20 | m_CollabEditorSettings:
21 | inProgressEnabled: 1
22 | m_EnableTextureStreamingInPlayMode: 1
23 |
--------------------------------------------------------------------------------
/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!30 &1
4 | GraphicsSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 12
7 | m_Deferred:
8 | m_Mode: 1
9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
10 | m_DeferredReflections:
11 | m_Mode: 1
12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
13 | m_ScreenSpaceShadows:
14 | m_Mode: 1
15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
16 | m_LegacyDeferred:
17 | m_Mode: 1
18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
19 | m_DepthNormals:
20 | m_Mode: 1
21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
22 | m_MotionVectors:
23 | m_Mode: 1
24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
25 | m_LightHalo:
26 | m_Mode: 1
27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
28 | m_LensFlare:
29 | m_Mode: 1
30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
31 | m_AlwaysIncludedShaders:
32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
38 | m_PreloadedShaders: []
39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
40 | type: 0}
41 | m_CustomRenderPipeline: {fileID: 0}
42 | m_TransparencySortMode: 0
43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1}
44 | m_DefaultRenderingPath: 1
45 | m_DefaultMobileRenderingPath: 1
46 | m_TierSettings: []
47 | m_LightmapStripping: 0
48 | m_FogStripping: 0
49 | m_InstancingStripping: 0
50 | m_LightmapKeepPlain: 1
51 | m_LightmapKeepDirCombined: 1
52 | m_LightmapKeepDynamicPlain: 1
53 | m_LightmapKeepDynamicDirCombined: 1
54 | m_LightmapKeepShadowMask: 1
55 | m_LightmapKeepSubtractive: 1
56 | m_FogKeepLinear: 1
57 | m_FogKeepExp: 1
58 | m_FogKeepExp2: 1
59 | m_AlbedoSwatchInfos: []
60 | m_LightsUseLinearIntensity: 0
61 | m_LightsUseColorTemperature: 0
62 |
--------------------------------------------------------------------------------
/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!13 &1
4 | InputManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Axes:
8 | - serializedVersion: 3
9 | m_Name: Horizontal
10 | descriptiveName:
11 | descriptiveNegativeName:
12 | negativeButton: left
13 | positiveButton: right
14 | altNegativeButton: a
15 | altPositiveButton: d
16 | gravity: 3
17 | dead: 0.001
18 | sensitivity: 3
19 | snap: 1
20 | invert: 0
21 | type: 0
22 | axis: 0
23 | joyNum: 0
24 | - serializedVersion: 3
25 | m_Name: Vertical
26 | descriptiveName:
27 | descriptiveNegativeName:
28 | negativeButton: down
29 | positiveButton: up
30 | altNegativeButton: s
31 | altPositiveButton: w
32 | gravity: 3
33 | dead: 0.001
34 | sensitivity: 3
35 | snap: 1
36 | invert: 0
37 | type: 0
38 | axis: 0
39 | joyNum: 0
40 | - serializedVersion: 3
41 | m_Name: Fire1
42 | descriptiveName:
43 | descriptiveNegativeName:
44 | negativeButton:
45 | positiveButton: left ctrl
46 | altNegativeButton:
47 | altPositiveButton: mouse 0
48 | gravity: 1000
49 | dead: 0.001
50 | sensitivity: 1000
51 | snap: 0
52 | invert: 0
53 | type: 0
54 | axis: 0
55 | joyNum: 0
56 | - serializedVersion: 3
57 | m_Name: Fire2
58 | descriptiveName:
59 | descriptiveNegativeName:
60 | negativeButton:
61 | positiveButton: left alt
62 | altNegativeButton:
63 | altPositiveButton: mouse 1
64 | gravity: 1000
65 | dead: 0.001
66 | sensitivity: 1000
67 | snap: 0
68 | invert: 0
69 | type: 0
70 | axis: 0
71 | joyNum: 0
72 | - serializedVersion: 3
73 | m_Name: Fire3
74 | descriptiveName:
75 | descriptiveNegativeName:
76 | negativeButton:
77 | positiveButton: left shift
78 | altNegativeButton:
79 | altPositiveButton: mouse 2
80 | gravity: 1000
81 | dead: 0.001
82 | sensitivity: 1000
83 | snap: 0
84 | invert: 0
85 | type: 0
86 | axis: 0
87 | joyNum: 0
88 | - serializedVersion: 3
89 | m_Name: Jump
90 | descriptiveName:
91 | descriptiveNegativeName:
92 | negativeButton:
93 | positiveButton: space
94 | altNegativeButton:
95 | altPositiveButton:
96 | gravity: 1000
97 | dead: 0.001
98 | sensitivity: 1000
99 | snap: 0
100 | invert: 0
101 | type: 0
102 | axis: 0
103 | joyNum: 0
104 | - serializedVersion: 3
105 | m_Name: Mouse X
106 | descriptiveName:
107 | descriptiveNegativeName:
108 | negativeButton:
109 | positiveButton:
110 | altNegativeButton:
111 | altPositiveButton:
112 | gravity: 0
113 | dead: 0
114 | sensitivity: 0.1
115 | snap: 0
116 | invert: 0
117 | type: 1
118 | axis: 0
119 | joyNum: 0
120 | - serializedVersion: 3
121 | m_Name: Mouse Y
122 | descriptiveName:
123 | descriptiveNegativeName:
124 | negativeButton:
125 | positiveButton:
126 | altNegativeButton:
127 | altPositiveButton:
128 | gravity: 0
129 | dead: 0
130 | sensitivity: 0.1
131 | snap: 0
132 | invert: 0
133 | type: 1
134 | axis: 1
135 | joyNum: 0
136 | - serializedVersion: 3
137 | m_Name: Mouse ScrollWheel
138 | descriptiveName:
139 | descriptiveNegativeName:
140 | negativeButton:
141 | positiveButton:
142 | altNegativeButton:
143 | altPositiveButton:
144 | gravity: 0
145 | dead: 0
146 | sensitivity: 0.1
147 | snap: 0
148 | invert: 0
149 | type: 1
150 | axis: 2
151 | joyNum: 0
152 | - serializedVersion: 3
153 | m_Name: Horizontal
154 | descriptiveName:
155 | descriptiveNegativeName:
156 | negativeButton:
157 | positiveButton:
158 | altNegativeButton:
159 | altPositiveButton:
160 | gravity: 0
161 | dead: 0.19
162 | sensitivity: 1
163 | snap: 0
164 | invert: 0
165 | type: 2
166 | axis: 0
167 | joyNum: 0
168 | - serializedVersion: 3
169 | m_Name: Vertical
170 | descriptiveName:
171 | descriptiveNegativeName:
172 | negativeButton:
173 | positiveButton:
174 | altNegativeButton:
175 | altPositiveButton:
176 | gravity: 0
177 | dead: 0.19
178 | sensitivity: 1
179 | snap: 0
180 | invert: 1
181 | type: 2
182 | axis: 1
183 | joyNum: 0
184 | - serializedVersion: 3
185 | m_Name: Fire1
186 | descriptiveName:
187 | descriptiveNegativeName:
188 | negativeButton:
189 | positiveButton: joystick button 0
190 | altNegativeButton:
191 | altPositiveButton:
192 | gravity: 1000
193 | dead: 0.001
194 | sensitivity: 1000
195 | snap: 0
196 | invert: 0
197 | type: 0
198 | axis: 0
199 | joyNum: 0
200 | - serializedVersion: 3
201 | m_Name: Fire2
202 | descriptiveName:
203 | descriptiveNegativeName:
204 | negativeButton:
205 | positiveButton: joystick button 1
206 | altNegativeButton:
207 | altPositiveButton:
208 | gravity: 1000
209 | dead: 0.001
210 | sensitivity: 1000
211 | snap: 0
212 | invert: 0
213 | type: 0
214 | axis: 0
215 | joyNum: 0
216 | - serializedVersion: 3
217 | m_Name: Fire3
218 | descriptiveName:
219 | descriptiveNegativeName:
220 | negativeButton:
221 | positiveButton: joystick button 2
222 | altNegativeButton:
223 | altPositiveButton:
224 | gravity: 1000
225 | dead: 0.001
226 | sensitivity: 1000
227 | snap: 0
228 | invert: 0
229 | type: 0
230 | axis: 0
231 | joyNum: 0
232 | - serializedVersion: 3
233 | m_Name: Jump
234 | descriptiveName:
235 | descriptiveNegativeName:
236 | negativeButton:
237 | positiveButton: joystick button 3
238 | altNegativeButton:
239 | altPositiveButton:
240 | gravity: 1000
241 | dead: 0.001
242 | sensitivity: 1000
243 | snap: 0
244 | invert: 0
245 | type: 0
246 | axis: 0
247 | joyNum: 0
248 | - serializedVersion: 3
249 | m_Name: Submit
250 | descriptiveName:
251 | descriptiveNegativeName:
252 | negativeButton:
253 | positiveButton: return
254 | altNegativeButton:
255 | altPositiveButton: joystick button 0
256 | gravity: 1000
257 | dead: 0.001
258 | sensitivity: 1000
259 | snap: 0
260 | invert: 0
261 | type: 0
262 | axis: 0
263 | joyNum: 0
264 | - serializedVersion: 3
265 | m_Name: Submit
266 | descriptiveName:
267 | descriptiveNegativeName:
268 | negativeButton:
269 | positiveButton: enter
270 | altNegativeButton:
271 | altPositiveButton: space
272 | gravity: 1000
273 | dead: 0.001
274 | sensitivity: 1000
275 | snap: 0
276 | invert: 0
277 | type: 0
278 | axis: 0
279 | joyNum: 0
280 | - serializedVersion: 3
281 | m_Name: Cancel
282 | descriptiveName:
283 | descriptiveNegativeName:
284 | negativeButton:
285 | positiveButton: escape
286 | altNegativeButton:
287 | altPositiveButton: joystick button 1
288 | gravity: 1000
289 | dead: 0.001
290 | sensitivity: 1000
291 | snap: 0
292 | invert: 0
293 | type: 0
294 | axis: 0
295 | joyNum: 0
296 |
--------------------------------------------------------------------------------
/ProjectSettings/NavMeshAreas.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!126 &1
4 | NavMeshProjectSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | areas:
8 | - name: Walkable
9 | cost: 1
10 | - name: Not Walkable
11 | cost: 1
12 | - name: Jump
13 | cost: 2
14 | - name:
15 | cost: 1
16 | - name:
17 | cost: 1
18 | - name:
19 | cost: 1
20 | - name:
21 | cost: 1
22 | - name:
23 | cost: 1
24 | - name:
25 | cost: 1
26 | - name:
27 | cost: 1
28 | - name:
29 | cost: 1
30 | - name:
31 | cost: 1
32 | - name:
33 | cost: 1
34 | - name:
35 | cost: 1
36 | - name:
37 | cost: 1
38 | - name:
39 | cost: 1
40 | - name:
41 | cost: 1
42 | - name:
43 | cost: 1
44 | - name:
45 | cost: 1
46 | - name:
47 | cost: 1
48 | - name:
49 | cost: 1
50 | - name:
51 | cost: 1
52 | - name:
53 | cost: 1
54 | - name:
55 | cost: 1
56 | - name:
57 | cost: 1
58 | - name:
59 | cost: 1
60 | - name:
61 | cost: 1
62 | - name:
63 | cost: 1
64 | - name:
65 | cost: 1
66 | - name:
67 | cost: 1
68 | - name:
69 | cost: 1
70 | - name:
71 | cost: 1
72 | m_LastAgentTypeID: -887442657
73 | m_Settings:
74 | - serializedVersion: 2
75 | agentTypeID: 0
76 | agentRadius: 0.5
77 | agentHeight: 2
78 | agentSlope: 45
79 | agentClimb: 0.75
80 | ledgeDropHeight: 0
81 | maxJumpAcrossDistance: 0
82 | minRegionArea: 2
83 | manualCellSize: 0
84 | cellSize: 0.16666667
85 | manualTileSize: 0
86 | tileSize: 256
87 | accuratePlacement: 0
88 | debug:
89 | m_Flags: 0
90 | m_SettingNames:
91 | - Humanoid
92 |
--------------------------------------------------------------------------------
/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!149 &1
4 | NetworkManager:
5 | m_ObjectHideFlags: 0
6 | m_DebugLevel: 0
7 | m_Sendrate: 15
8 | m_AssetToPrefab: {}
9 |
--------------------------------------------------------------------------------
/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!19 &1
4 | Physics2DSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 3
7 | m_Gravity: {x: 0, y: -9.81}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_VelocityIterations: 8
10 | m_PositionIterations: 3
11 | m_VelocityThreshold: 1
12 | m_MaxLinearCorrection: 0.2
13 | m_MaxAngularCorrection: 8
14 | m_MaxTranslationSpeed: 100
15 | m_MaxRotationSpeed: 360
16 | m_BaumgarteScale: 0.2
17 | m_BaumgarteTimeOfImpactScale: 0.75
18 | m_TimeToSleep: 0.5
19 | m_LinearSleepTolerance: 0.01
20 | m_AngularSleepTolerance: 2
21 | m_DefaultContactOffset: 0.01
22 | m_AutoSimulation: 1
23 | m_QueriesHitTriggers: 1
24 | m_QueriesStartInColliders: 1
25 | m_ChangeStopsCallbacks: 0
26 | m_CallbacksOnDisable: 1
27 | m_AutoSyncTransforms: 1
28 | m_AlwaysShowColliders: 0
29 | m_ShowColliderSleep: 1
30 | m_ShowColliderContacts: 0
31 | m_ShowColliderAABB: 0
32 | m_ContactArrowScale: 0.2
33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
38 |
--------------------------------------------------------------------------------
/ProjectSettings/PresetManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1386491679 &1
4 | PresetManager:
5 | m_ObjectHideFlags: 0
6 | m_DefaultList:
7 | - type:
8 | m_NativeTypeID: 108
9 | m_ManagedTypePPtr: {fileID: 0}
10 | m_ManagedTypeFallback:
11 | defaultPresets:
12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea,
13 | type: 2}
14 | - type:
15 | m_NativeTypeID: 1020
16 | m_ManagedTypePPtr: {fileID: 0}
17 | m_ManagedTypeFallback:
18 | defaultPresets:
19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6,
20 | type: 2}
21 | - type:
22 | m_NativeTypeID: 1006
23 | m_ManagedTypePPtr: {fileID: 0}
24 | m_ManagedTypeFallback:
25 | defaultPresets:
26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9,
27 | type: 2}
28 |
--------------------------------------------------------------------------------
/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!129 &1
4 | PlayerSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 15
7 | productGUID: efefad388870749448829f266eccb6e2
8 | AndroidProfiler: 0
9 | AndroidFilterTouchesWhenObscured: 0
10 | AndroidEnableSustainedPerformanceMode: 0
11 | defaultScreenOrientation: 4
12 | targetDevice: 2
13 | useOnDemandResources: 0
14 | accelerometerFrequency: 60
15 | companyName: DefaultCompany
16 | productName: OctoMapSharpApp
17 | defaultCursor: {fileID: 0}
18 | cursorHotspot: {x: 0, y: 0}
19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
20 | m_ShowUnitySplashScreen: 1
21 | m_ShowUnitySplashLogo: 1
22 | m_SplashScreenOverlayOpacity: 1
23 | m_SplashScreenAnimation: 1
24 | m_SplashScreenLogoStyle: 1
25 | m_SplashScreenDrawMode: 0
26 | m_SplashScreenBackgroundAnimationZoom: 1
27 | m_SplashScreenLogoAnimationZoom: 1
28 | m_SplashScreenBackgroundLandscapeAspect: 1
29 | m_SplashScreenBackgroundPortraitAspect: 1
30 | m_SplashScreenBackgroundLandscapeUvs:
31 | serializedVersion: 2
32 | x: 0
33 | y: 0
34 | width: 1
35 | height: 1
36 | m_SplashScreenBackgroundPortraitUvs:
37 | serializedVersion: 2
38 | x: 0
39 | y: 0
40 | width: 1
41 | height: 1
42 | m_SplashScreenLogos: []
43 | m_VirtualRealitySplashScreen: {fileID: 0}
44 | m_HolographicTrackingLossScreen: {fileID: 0}
45 | defaultScreenWidth: 1024
46 | defaultScreenHeight: 768
47 | defaultScreenWidthWeb: 960
48 | defaultScreenHeightWeb: 600
49 | m_StereoRenderingPath: 0
50 | m_ActiveColorSpace: 0
51 | m_MTRendering: 1
52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000
53 | iosShowActivityIndicatorOnLoading: -1
54 | androidShowActivityIndicatorOnLoading: -1
55 | iosAppInBackgroundBehavior: 0
56 | displayResolutionDialog: 1
57 | iosAllowHTTPDownload: 1
58 | allowedAutorotateToPortrait: 1
59 | allowedAutorotateToPortraitUpsideDown: 1
60 | allowedAutorotateToLandscapeRight: 1
61 | allowedAutorotateToLandscapeLeft: 1
62 | useOSAutorotation: 1
63 | use32BitDisplayBuffer: 1
64 | preserveFramebufferAlpha: 0
65 | disableDepthAndStencilBuffers: 0
66 | androidBlitType: 0
67 | defaultIsNativeResolution: 1
68 | macRetinaSupport: 1
69 | runInBackground: 1
70 | captureSingleScreen: 0
71 | muteOtherAudioSources: 0
72 | Prepare IOS For Recording: 0
73 | Force IOS Speakers When Recording: 0
74 | deferSystemGesturesMode: 0
75 | hideHomeButton: 0
76 | submitAnalytics: 1
77 | usePlayerLog: 1
78 | bakeCollisionMeshes: 0
79 | forceSingleInstance: 0
80 | resizableWindow: 0
81 | useMacAppStoreValidation: 0
82 | macAppStoreCategory: public.app-category.games
83 | gpuSkinning: 1
84 | graphicsJobs: 0
85 | xboxPIXTextureCapture: 0
86 | xboxEnableAvatar: 0
87 | xboxEnableKinect: 0
88 | xboxEnableKinectAutoTracking: 0
89 | xboxEnableFitness: 0
90 | visibleInBackground: 1
91 | allowFullscreenSwitch: 1
92 | graphicsJobMode: 0
93 | fullscreenMode: 1
94 | xboxSpeechDB: 0
95 | xboxEnableHeadOrientation: 0
96 | xboxEnableGuest: 0
97 | xboxEnablePIXSampling: 0
98 | metalFramebufferOnly: 0
99 | n3dsDisableStereoscopicView: 0
100 | n3dsEnableSharedListOpt: 1
101 | n3dsEnableVSync: 0
102 | xboxOneResolution: 0
103 | xboxOneSResolution: 0
104 | xboxOneXResolution: 3
105 | xboxOneMonoLoggingLevel: 0
106 | xboxOneLoggingLevel: 1
107 | xboxOneDisableEsram: 0
108 | xboxOnePresentImmediateThreshold: 0
109 | switchQueueCommandMemory: 0
110 | videoMemoryForVertexBuffers: 0
111 | psp2PowerMode: 0
112 | psp2AcquireBGM: 1
113 | vulkanEnableSetSRGBWrite: 0
114 | vulkanUseSWCommandBuffers: 0
115 | m_SupportedAspectRatios:
116 | 4:3: 1
117 | 5:4: 1
118 | 16:10: 1
119 | 16:9: 1
120 | Others: 1
121 | bundleVersion: 0.1
122 | preloadedAssets: []
123 | metroInputSource: 0
124 | wsaTransparentSwapchain: 0
125 | m_HolographicPauseOnTrackingLoss: 1
126 | xboxOneDisableKinectGpuReservation: 0
127 | xboxOneEnable7thCore: 0
128 | vrSettings:
129 | cardboard:
130 | depthFormat: 0
131 | enableTransitionView: 0
132 | daydream:
133 | depthFormat: 0
134 | useSustainedPerformanceMode: 0
135 | enableVideoLayer: 0
136 | useProtectedVideoMemory: 0
137 | minimumSupportedHeadTracking: 0
138 | maximumSupportedHeadTracking: 1
139 | hololens:
140 | depthFormat: 1
141 | depthBufferSharingEnabled: 0
142 | oculus:
143 | sharedDepthBuffer: 0
144 | dashSupport: 0
145 | enable360StereoCapture: 0
146 | protectGraphicsMemory: 0
147 | useHDRDisplay: 0
148 | m_ColorGamuts: 00000000
149 | targetPixelDensity: 30
150 | resolutionScalingMode: 0
151 | androidSupportedAspectRatio: 1
152 | androidMaxAspectRatio: 2.1
153 | applicationIdentifier: {}
154 | buildNumber: {}
155 | AndroidBundleVersionCode: 1
156 | AndroidMinSdkVersion: 16
157 | AndroidTargetSdkVersion: 0
158 | AndroidPreferredInstallLocation: 1
159 | aotOptions:
160 | stripEngineCode: 1
161 | iPhoneStrippingLevel: 0
162 | iPhoneScriptCallOptimization: 0
163 | ForceInternetPermission: 0
164 | ForceSDCardPermission: 0
165 | CreateWallpaper: 0
166 | APKExpansionFiles: 0
167 | keepLoadedShadersAlive: 0
168 | StripUnusedMeshComponents: 1
169 | VertexChannelCompressionMask: 4054
170 | iPhoneSdkVersion: 988
171 | iOSTargetOSVersionString: 8.0
172 | tvOSSdkVersion: 0
173 | tvOSRequireExtendedGameController: 0
174 | tvOSTargetOSVersionString: 9.0
175 | uIPrerenderedIcon: 0
176 | uIRequiresPersistentWiFi: 0
177 | uIRequiresFullScreen: 1
178 | uIStatusBarHidden: 1
179 | uIExitOnSuspend: 0
180 | uIStatusBarStyle: 0
181 | iPhoneSplashScreen: {fileID: 0}
182 | iPhoneHighResSplashScreen: {fileID: 0}
183 | iPhoneTallHighResSplashScreen: {fileID: 0}
184 | iPhone47inSplashScreen: {fileID: 0}
185 | iPhone55inPortraitSplashScreen: {fileID: 0}
186 | iPhone55inLandscapeSplashScreen: {fileID: 0}
187 | iPhone58inPortraitSplashScreen: {fileID: 0}
188 | iPhone58inLandscapeSplashScreen: {fileID: 0}
189 | iPadPortraitSplashScreen: {fileID: 0}
190 | iPadHighResPortraitSplashScreen: {fileID: 0}
191 | iPadLandscapeSplashScreen: {fileID: 0}
192 | iPadHighResLandscapeSplashScreen: {fileID: 0}
193 | appleTVSplashScreen: {fileID: 0}
194 | appleTVSplashScreen2x: {fileID: 0}
195 | tvOSSmallIconLayers: []
196 | tvOSSmallIconLayers2x: []
197 | tvOSLargeIconLayers: []
198 | tvOSLargeIconLayers2x: []
199 | tvOSTopShelfImageLayers: []
200 | tvOSTopShelfImageLayers2x: []
201 | tvOSTopShelfImageWideLayers: []
202 | tvOSTopShelfImageWideLayers2x: []
203 | iOSLaunchScreenType: 0
204 | iOSLaunchScreenPortrait: {fileID: 0}
205 | iOSLaunchScreenLandscape: {fileID: 0}
206 | iOSLaunchScreenBackgroundColor:
207 | serializedVersion: 2
208 | rgba: 0
209 | iOSLaunchScreenFillPct: 100
210 | iOSLaunchScreenSize: 100
211 | iOSLaunchScreenCustomXibPath:
212 | iOSLaunchScreeniPadType: 0
213 | iOSLaunchScreeniPadImage: {fileID: 0}
214 | iOSLaunchScreeniPadBackgroundColor:
215 | serializedVersion: 2
216 | rgba: 0
217 | iOSLaunchScreeniPadFillPct: 100
218 | iOSLaunchScreeniPadSize: 100
219 | iOSLaunchScreeniPadCustomXibPath:
220 | iOSUseLaunchScreenStoryboard: 0
221 | iOSLaunchScreenCustomStoryboardPath:
222 | iOSDeviceRequirements: []
223 | iOSURLSchemes: []
224 | iOSBackgroundModes: 0
225 | iOSMetalForceHardShadows: 0
226 | metalEditorSupport: 1
227 | metalAPIValidation: 1
228 | iOSRenderExtraFrameOnPause: 0
229 | appleDeveloperTeamID:
230 | iOSManualSigningProvisioningProfileID:
231 | tvOSManualSigningProvisioningProfileID:
232 | iOSManualSigningProvisioningProfileType: 0
233 | tvOSManualSigningProvisioningProfileType: 0
234 | appleEnableAutomaticSigning: 0
235 | iOSRequireARKit: 0
236 | appleEnableProMotion: 0
237 | vulkanEditorSupport: 0
238 | clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea
239 | templatePackageId: com.unity.3d@1.0.2
240 | templateDefaultScene: Assets/Scenes/SampleScene.unity
241 | AndroidTargetArchitectures: 5
242 | AndroidSplashScreenScale: 0
243 | androidSplashScreen: {fileID: 0}
244 | AndroidKeystoreName:
245 | AndroidKeyaliasName:
246 | AndroidBuildApkPerCpuArchitecture: 0
247 | AndroidTVCompatibility: 1
248 | AndroidIsGame: 1
249 | AndroidEnableTango: 0
250 | androidEnableBanner: 1
251 | androidUseLowAccuracyLocation: 0
252 | m_AndroidBanners:
253 | - width: 320
254 | height: 180
255 | banner: {fileID: 0}
256 | androidGamepadSupportLevel: 0
257 | resolutionDialogBanner: {fileID: 0}
258 | m_BuildTargetIcons: []
259 | m_BuildTargetPlatformIcons: []
260 | m_BuildTargetBatching:
261 | - m_BuildTarget: Standalone
262 | m_StaticBatching: 1
263 | m_DynamicBatching: 0
264 | - m_BuildTarget: tvOS
265 | m_StaticBatching: 1
266 | m_DynamicBatching: 0
267 | - m_BuildTarget: Android
268 | m_StaticBatching: 1
269 | m_DynamicBatching: 0
270 | - m_BuildTarget: iPhone
271 | m_StaticBatching: 1
272 | m_DynamicBatching: 0
273 | - m_BuildTarget: WebGL
274 | m_StaticBatching: 0
275 | m_DynamicBatching: 0
276 | m_BuildTargetGraphicsAPIs:
277 | - m_BuildTarget: AndroidPlayer
278 | m_APIs: 0b00000015000000
279 | m_Automatic: 1
280 | - m_BuildTarget: iOSSupport
281 | m_APIs: 10000000
282 | m_Automatic: 1
283 | - m_BuildTarget: AppleTVSupport
284 | m_APIs: 10000000
285 | m_Automatic: 0
286 | - m_BuildTarget: WebGLSupport
287 | m_APIs: 0b000000
288 | m_Automatic: 1
289 | m_BuildTargetVRSettings:
290 | - m_BuildTarget: Standalone
291 | m_Enabled: 0
292 | m_Devices:
293 | - Oculus
294 | - OpenVR
295 | m_BuildTargetEnableVuforiaSettings: []
296 | openGLRequireES31: 0
297 | openGLRequireES31AEP: 0
298 | m_TemplateCustomTags: {}
299 | mobileMTRendering:
300 | Android: 1
301 | iPhone: 1
302 | tvOS: 1
303 | m_BuildTargetGroupLightmapEncodingQuality: []
304 | m_BuildTargetGroupLightmapSettings: []
305 | playModeTestRunnerEnabled: 0
306 | runPlayModeTestAsEditModeTest: 0
307 | actionOnDotNetUnhandledException: 1
308 | enableInternalProfiler: 0
309 | logObjCUncaughtExceptions: 1
310 | enableCrashReportAPI: 0
311 | cameraUsageDescription:
312 | locationUsageDescription:
313 | microphoneUsageDescription:
314 | switchNetLibKey:
315 | switchSocketMemoryPoolSize: 6144
316 | switchSocketAllocatorPoolSize: 128
317 | switchSocketConcurrencyLimit: 14
318 | switchScreenResolutionBehavior: 2
319 | switchUseCPUProfiler: 0
320 | switchApplicationID: 0x01004b9000490000
321 | switchNSODependencies:
322 | switchTitleNames_0:
323 | switchTitleNames_1:
324 | switchTitleNames_2:
325 | switchTitleNames_3:
326 | switchTitleNames_4:
327 | switchTitleNames_5:
328 | switchTitleNames_6:
329 | switchTitleNames_7:
330 | switchTitleNames_8:
331 | switchTitleNames_9:
332 | switchTitleNames_10:
333 | switchTitleNames_11:
334 | switchTitleNames_12:
335 | switchTitleNames_13:
336 | switchTitleNames_14:
337 | switchPublisherNames_0:
338 | switchPublisherNames_1:
339 | switchPublisherNames_2:
340 | switchPublisherNames_3:
341 | switchPublisherNames_4:
342 | switchPublisherNames_5:
343 | switchPublisherNames_6:
344 | switchPublisherNames_7:
345 | switchPublisherNames_8:
346 | switchPublisherNames_9:
347 | switchPublisherNames_10:
348 | switchPublisherNames_11:
349 | switchPublisherNames_12:
350 | switchPublisherNames_13:
351 | switchPublisherNames_14:
352 | switchIcons_0: {fileID: 0}
353 | switchIcons_1: {fileID: 0}
354 | switchIcons_2: {fileID: 0}
355 | switchIcons_3: {fileID: 0}
356 | switchIcons_4: {fileID: 0}
357 | switchIcons_5: {fileID: 0}
358 | switchIcons_6: {fileID: 0}
359 | switchIcons_7: {fileID: 0}
360 | switchIcons_8: {fileID: 0}
361 | switchIcons_9: {fileID: 0}
362 | switchIcons_10: {fileID: 0}
363 | switchIcons_11: {fileID: 0}
364 | switchIcons_12: {fileID: 0}
365 | switchIcons_13: {fileID: 0}
366 | switchIcons_14: {fileID: 0}
367 | switchSmallIcons_0: {fileID: 0}
368 | switchSmallIcons_1: {fileID: 0}
369 | switchSmallIcons_2: {fileID: 0}
370 | switchSmallIcons_3: {fileID: 0}
371 | switchSmallIcons_4: {fileID: 0}
372 | switchSmallIcons_5: {fileID: 0}
373 | switchSmallIcons_6: {fileID: 0}
374 | switchSmallIcons_7: {fileID: 0}
375 | switchSmallIcons_8: {fileID: 0}
376 | switchSmallIcons_9: {fileID: 0}
377 | switchSmallIcons_10: {fileID: 0}
378 | switchSmallIcons_11: {fileID: 0}
379 | switchSmallIcons_12: {fileID: 0}
380 | switchSmallIcons_13: {fileID: 0}
381 | switchSmallIcons_14: {fileID: 0}
382 | switchManualHTML:
383 | switchAccessibleURLs:
384 | switchLegalInformation:
385 | switchMainThreadStackSize: 1048576
386 | switchPresenceGroupId:
387 | switchLogoHandling: 0
388 | switchReleaseVersion: 0
389 | switchDisplayVersion: 1.0.0
390 | switchStartupUserAccount: 0
391 | switchTouchScreenUsage: 0
392 | switchSupportedLanguagesMask: 0
393 | switchLogoType: 0
394 | switchApplicationErrorCodeCategory:
395 | switchUserAccountSaveDataSize: 0
396 | switchUserAccountSaveDataJournalSize: 0
397 | switchApplicationAttribute: 0
398 | switchCardSpecSize: -1
399 | switchCardSpecClock: -1
400 | switchRatingsMask: 0
401 | switchRatingsInt_0: 0
402 | switchRatingsInt_1: 0
403 | switchRatingsInt_2: 0
404 | switchRatingsInt_3: 0
405 | switchRatingsInt_4: 0
406 | switchRatingsInt_5: 0
407 | switchRatingsInt_6: 0
408 | switchRatingsInt_7: 0
409 | switchRatingsInt_8: 0
410 | switchRatingsInt_9: 0
411 | switchRatingsInt_10: 0
412 | switchRatingsInt_11: 0
413 | switchLocalCommunicationIds_0:
414 | switchLocalCommunicationIds_1:
415 | switchLocalCommunicationIds_2:
416 | switchLocalCommunicationIds_3:
417 | switchLocalCommunicationIds_4:
418 | switchLocalCommunicationIds_5:
419 | switchLocalCommunicationIds_6:
420 | switchLocalCommunicationIds_7:
421 | switchParentalControl: 0
422 | switchAllowsScreenshot: 1
423 | switchAllowsVideoCapturing: 1
424 | switchAllowsRuntimeAddOnContentInstall: 0
425 | switchDataLossConfirmation: 0
426 | switchSupportedNpadStyles: 3
427 | switchNativeFsCacheSize: 32
428 | switchIsHoldTypeHorizontal: 0
429 | switchSupportedNpadCount: 8
430 | switchSocketConfigEnabled: 0
431 | switchTcpInitialSendBufferSize: 32
432 | switchTcpInitialReceiveBufferSize: 64
433 | switchTcpAutoSendBufferSizeMax: 256
434 | switchTcpAutoReceiveBufferSizeMax: 256
435 | switchUdpSendBufferSize: 9
436 | switchUdpReceiveBufferSize: 42
437 | switchSocketBufferEfficiency: 4
438 | switchSocketInitializeEnabled: 1
439 | switchNetworkInterfaceManagerInitializeEnabled: 1
440 | switchPlayerConnectionEnabled: 1
441 | ps4NPAgeRating: 12
442 | ps4NPTitleSecret:
443 | ps4NPTrophyPackPath:
444 | ps4ParentalLevel: 11
445 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000
446 | ps4Category: 0
447 | ps4MasterVersion: 01.00
448 | ps4AppVersion: 01.00
449 | ps4AppType: 0
450 | ps4ParamSfxPath:
451 | ps4VideoOutPixelFormat: 0
452 | ps4VideoOutInitialWidth: 1920
453 | ps4VideoOutBaseModeInitialWidth: 1920
454 | ps4VideoOutReprojectionRate: 60
455 | ps4PronunciationXMLPath:
456 | ps4PronunciationSIGPath:
457 | ps4BackgroundImagePath:
458 | ps4StartupImagePath:
459 | ps4StartupImagesFolder:
460 | ps4IconImagesFolder:
461 | ps4SaveDataImagePath:
462 | ps4SdkOverride:
463 | ps4BGMPath:
464 | ps4ShareFilePath:
465 | ps4ShareOverlayImagePath:
466 | ps4PrivacyGuardImagePath:
467 | ps4NPtitleDatPath:
468 | ps4RemotePlayKeyAssignment: -1
469 | ps4RemotePlayKeyMappingDir:
470 | ps4PlayTogetherPlayerCount: 0
471 | ps4EnterButtonAssignment: 1
472 | ps4ApplicationParam1: 0
473 | ps4ApplicationParam2: 0
474 | ps4ApplicationParam3: 0
475 | ps4ApplicationParam4: 0
476 | ps4DownloadDataSize: 0
477 | ps4GarlicHeapSize: 2048
478 | ps4ProGarlicHeapSize: 2560
479 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ
480 | ps4pnSessions: 1
481 | ps4pnPresence: 1
482 | ps4pnFriends: 1
483 | ps4pnGameCustomData: 1
484 | playerPrefsSupport: 0
485 | enableApplicationExit: 0
486 | restrictedAudioUsageRights: 0
487 | ps4UseResolutionFallback: 0
488 | ps4ReprojectionSupport: 0
489 | ps4UseAudio3dBackend: 0
490 | ps4SocialScreenEnabled: 0
491 | ps4ScriptOptimizationLevel: 0
492 | ps4Audio3dVirtualSpeakerCount: 14
493 | ps4attribCpuUsage: 0
494 | ps4PatchPkgPath:
495 | ps4PatchLatestPkgPath:
496 | ps4PatchChangeinfoPath:
497 | ps4PatchDayOne: 0
498 | ps4attribUserManagement: 0
499 | ps4attribMoveSupport: 0
500 | ps4attrib3DSupport: 0
501 | ps4attribShareSupport: 0
502 | ps4attribExclusiveVR: 0
503 | ps4disableAutoHideSplash: 0
504 | ps4videoRecordingFeaturesUsed: 0
505 | ps4contentSearchFeaturesUsed: 0
506 | ps4attribEyeToEyeDistanceSettingVR: 0
507 | ps4IncludedModules: []
508 | monoEnv:
509 | psp2Splashimage: {fileID: 0}
510 | psp2NPTrophyPackPath:
511 | psp2NPSupportGBMorGJP: 0
512 | psp2NPAgeRating: 12
513 | psp2NPTitleDatPath:
514 | psp2NPCommsID:
515 | psp2NPCommunicationsID:
516 | psp2NPCommsPassphrase:
517 | psp2NPCommsSig:
518 | psp2ParamSfxPath:
519 | psp2ManualPath:
520 | psp2LiveAreaGatePath:
521 | psp2LiveAreaBackroundPath:
522 | psp2LiveAreaPath:
523 | psp2LiveAreaTrialPath:
524 | psp2PatchChangeInfoPath:
525 | psp2PatchOriginalPackage:
526 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui
527 | psp2KeystoneFile:
528 | psp2MemoryExpansionMode: 0
529 | psp2DRMType: 0
530 | psp2StorageType: 0
531 | psp2MediaCapacity: 0
532 | psp2DLCConfigPath:
533 | psp2ThumbnailPath:
534 | psp2BackgroundPath:
535 | psp2SoundPath:
536 | psp2TrophyCommId:
537 | psp2TrophyPackagePath:
538 | psp2PackagedResourcesPath:
539 | psp2SaveDataQuota: 10240
540 | psp2ParentalLevel: 1
541 | psp2ShortTitle: Not Set
542 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF
543 | psp2Category: 0
544 | psp2MasterVersion: 01.00
545 | psp2AppVersion: 01.00
546 | psp2TVBootMode: 0
547 | psp2EnterButtonAssignment: 2
548 | psp2TVDisableEmu: 0
549 | psp2AllowTwitterDialog: 1
550 | psp2Upgradable: 0
551 | psp2HealthWarning: 0
552 | psp2UseLibLocation: 0
553 | psp2InfoBarOnStartup: 0
554 | psp2InfoBarColor: 0
555 | psp2ScriptOptimizationLevel: 0
556 | splashScreenBackgroundSourceLandscape: {fileID: 0}
557 | splashScreenBackgroundSourcePortrait: {fileID: 0}
558 | spritePackerPolicy:
559 | webGLMemorySize: 256
560 | webGLExceptionSupport: 1
561 | webGLNameFilesAsHashes: 0
562 | webGLDataCaching: 1
563 | webGLDebugSymbols: 0
564 | webGLEmscriptenArgs:
565 | webGLModulesDirectory:
566 | webGLTemplate: APPLICATION:Default
567 | webGLAnalyzeBuildSize: 0
568 | webGLUseEmbeddedResources: 0
569 | webGLCompressionFormat: 1
570 | webGLLinkerTarget: 1
571 | scriptingDefineSymbols: {}
572 | platformArchitecture: {}
573 | scriptingBackend: {}
574 | il2cppCompilerConfiguration: {}
575 | incrementalIl2cppBuild: {}
576 | allowUnsafeCode: 0
577 | additionalIl2CppArgs:
578 | scriptingRuntimeVersion: 1
579 | apiCompatibilityLevelPerPlatform: {}
580 | m_RenderingPath: 1
581 | m_MobileRenderingPath: 1
582 | metroPackageName: Template_3D
583 | metroPackageVersion:
584 | metroCertificatePath:
585 | metroCertificatePassword:
586 | metroCertificateSubject:
587 | metroCertificateIssuer:
588 | metroCertificateNotAfter: 0000000000000000
589 | metroApplicationDescription: Template_3D
590 | wsaImages: {}
591 | metroTileShortName:
592 | metroTileShowName: 0
593 | metroMediumTileShowName: 0
594 | metroLargeTileShowName: 0
595 | metroWideTileShowName: 0
596 | metroDefaultTileSize: 1
597 | metroTileForegroundText: 2
598 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
599 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
600 | a: 1}
601 | metroSplashScreenUseBackgroundColor: 0
602 | platformCapabilities: {}
603 | metroFTAName:
604 | metroFTAFileTypes: []
605 | metroProtocolName:
606 | metroCompilationOverrides: 1
607 | n3dsUseExtSaveData: 0
608 | n3dsCompressStaticMem: 1
609 | n3dsExtSaveDataNumber: 0x12345
610 | n3dsStackSize: 131072
611 | n3dsTargetPlatform: 2
612 | n3dsRegion: 7
613 | n3dsMediaSize: 0
614 | n3dsLogoStyle: 3
615 | n3dsTitle: GameName
616 | n3dsProductCode:
617 | n3dsApplicationId: 0xFF3FF
618 | XboxOneProductId:
619 | XboxOneUpdateKey:
620 | XboxOneSandboxId:
621 | XboxOneContentId:
622 | XboxOneTitleId:
623 | XboxOneSCId:
624 | XboxOneGameOsOverridePath:
625 | XboxOnePackagingOverridePath:
626 | XboxOneAppManifestOverridePath:
627 | XboxOneVersion: 1.0.0.0
628 | XboxOnePackageEncryption: 0
629 | XboxOnePackageUpdateGranularity: 2
630 | XboxOneDescription:
631 | XboxOneLanguage:
632 | - enus
633 | XboxOneCapability: []
634 | XboxOneGameRating: {}
635 | XboxOneIsContentPackage: 0
636 | XboxOneEnableGPUVariability: 0
637 | XboxOneSockets: {}
638 | XboxOneSplashScreen: {fileID: 0}
639 | XboxOneAllowedProductIds: []
640 | XboxOnePersistentLocalStorageSize: 0
641 | XboxOneXTitleMemory: 8
642 | xboxOneScriptCompiler: 0
643 | vrEditorSettings:
644 | daydream:
645 | daydreamIconForeground: {fileID: 0}
646 | daydreamIconBackground: {fileID: 0}
647 | cloudServicesEnabled:
648 | UNet: 1
649 | facebookSdkVersion: 7.9.4
650 | apiCompatibilityLevel: 3
651 | cloudProjectId:
652 | projectName:
653 | organizationId:
654 | cloudEnabled: 0
655 | enableNativePlatformBackendsForNewInputSystem: 0
656 | disableOldInputManagerSupport: 0
657 |
--------------------------------------------------------------------------------
/ProjectSettings/ProjectVersion.txt:
--------------------------------------------------------------------------------
1 | m_EditorVersion: 2018.2.6f1
2 |
--------------------------------------------------------------------------------
/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!47 &1
4 | QualitySettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 5
7 | m_CurrentQuality: 4
8 | m_QualitySettings:
9 | - serializedVersion: 2
10 | name: Very Low
11 | pixelLightCount: 0
12 | shadows: 0
13 | shadowResolution: 0
14 | shadowProjection: 1
15 | shadowCascades: 1
16 | shadowDistance: 15
17 | shadowNearPlaneOffset: 3
18 | shadowCascade2Split: 0.33333334
19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
20 | shadowmaskMode: 0
21 | blendWeights: 1
22 | textureQuality: 1
23 | anisotropicTextures: 0
24 | antiAliasing: 0
25 | softParticles: 0
26 | softVegetation: 0
27 | realtimeReflectionProbes: 0
28 | billboardsFaceCameraPosition: 0
29 | vSyncCount: 0
30 | lodBias: 0.3
31 | maximumLODLevel: 0
32 | particleRaycastBudget: 4
33 | asyncUploadTimeSlice: 2
34 | asyncUploadBufferSize: 4
35 | resolutionScalingFixedDPIFactor: 1
36 | excludedTargetPlatforms: []
37 | - serializedVersion: 2
38 | name: Low
39 | pixelLightCount: 0
40 | shadows: 0
41 | shadowResolution: 0
42 | shadowProjection: 1
43 | shadowCascades: 1
44 | shadowDistance: 20
45 | shadowNearPlaneOffset: 3
46 | shadowCascade2Split: 0.33333334
47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
48 | shadowmaskMode: 0
49 | blendWeights: 2
50 | textureQuality: 0
51 | anisotropicTextures: 0
52 | antiAliasing: 0
53 | softParticles: 0
54 | softVegetation: 0
55 | realtimeReflectionProbes: 0
56 | billboardsFaceCameraPosition: 0
57 | vSyncCount: 0
58 | lodBias: 0.4
59 | maximumLODLevel: 0
60 | particleRaycastBudget: 16
61 | asyncUploadTimeSlice: 2
62 | asyncUploadBufferSize: 4
63 | resolutionScalingFixedDPIFactor: 1
64 | excludedTargetPlatforms: []
65 | - serializedVersion: 2
66 | name: Medium
67 | pixelLightCount: 1
68 | shadows: 1
69 | shadowResolution: 0
70 | shadowProjection: 1
71 | shadowCascades: 1
72 | shadowDistance: 20
73 | shadowNearPlaneOffset: 3
74 | shadowCascade2Split: 0.33333334
75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
76 | shadowmaskMode: 0
77 | blendWeights: 2
78 | textureQuality: 0
79 | anisotropicTextures: 1
80 | antiAliasing: 0
81 | softParticles: 0
82 | softVegetation: 0
83 | realtimeReflectionProbes: 0
84 | billboardsFaceCameraPosition: 0
85 | vSyncCount: 1
86 | lodBias: 0.7
87 | maximumLODLevel: 0
88 | particleRaycastBudget: 64
89 | asyncUploadTimeSlice: 2
90 | asyncUploadBufferSize: 4
91 | resolutionScalingFixedDPIFactor: 1
92 | excludedTargetPlatforms: []
93 | - serializedVersion: 2
94 | name: High
95 | pixelLightCount: 2
96 | shadows: 2
97 | shadowResolution: 1
98 | shadowProjection: 1
99 | shadowCascades: 2
100 | shadowDistance: 40
101 | shadowNearPlaneOffset: 3
102 | shadowCascade2Split: 0.33333334
103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
104 | shadowmaskMode: 1
105 | blendWeights: 2
106 | textureQuality: 0
107 | anisotropicTextures: 1
108 | antiAliasing: 2
109 | softParticles: 0
110 | softVegetation: 1
111 | realtimeReflectionProbes: 1
112 | billboardsFaceCameraPosition: 1
113 | vSyncCount: 1
114 | lodBias: 1
115 | maximumLODLevel: 0
116 | particleRaycastBudget: 256
117 | asyncUploadTimeSlice: 2
118 | asyncUploadBufferSize: 4
119 | resolutionScalingFixedDPIFactor: 1
120 | excludedTargetPlatforms: []
121 | - serializedVersion: 2
122 | name: Very High
123 | pixelLightCount: 3
124 | shadows: 2
125 | shadowResolution: 2
126 | shadowProjection: 1
127 | shadowCascades: 2
128 | shadowDistance: 40
129 | shadowNearPlaneOffset: 3
130 | shadowCascade2Split: 0.33333334
131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
132 | shadowmaskMode: 1
133 | blendWeights: 4
134 | textureQuality: 0
135 | anisotropicTextures: 1
136 | antiAliasing: 4
137 | softParticles: 1
138 | softVegetation: 1
139 | realtimeReflectionProbes: 1
140 | billboardsFaceCameraPosition: 1
141 | vSyncCount: 1
142 | lodBias: 1.5
143 | maximumLODLevel: 0
144 | particleRaycastBudget: 1024
145 | asyncUploadTimeSlice: 2
146 | asyncUploadBufferSize: 4
147 | resolutionScalingFixedDPIFactor: 1
148 | excludedTargetPlatforms: []
149 | - serializedVersion: 2
150 | name: Ultra
151 | pixelLightCount: 4
152 | shadows: 2
153 | shadowResolution: 2
154 | shadowProjection: 1
155 | shadowCascades: 4
156 | shadowDistance: 150
157 | shadowNearPlaneOffset: 3
158 | shadowCascade2Split: 0.33333334
159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
160 | shadowmaskMode: 1
161 | blendWeights: 4
162 | textureQuality: 0
163 | anisotropicTextures: 1
164 | antiAliasing: 4
165 | softParticles: 1
166 | softVegetation: 1
167 | realtimeReflectionProbes: 1
168 | billboardsFaceCameraPosition: 1
169 | vSyncCount: 1
170 | lodBias: 2
171 | maximumLODLevel: 0
172 | particleRaycastBudget: 4096
173 | asyncUploadTimeSlice: 2
174 | asyncUploadBufferSize: 4
175 | resolutionScalingFixedDPIFactor: 1
176 | excludedTargetPlatforms: []
177 | m_PerPlatformDefaultQuality:
178 | Android: 2
179 | Nintendo 3DS: 5
180 | Nintendo Switch: 5
181 | PS4: 5
182 | PSP2: 2
183 | Standalone: 5
184 | Tizen: 2
185 | WebGL: 3
186 | WiiU: 5
187 | Windows Store Apps: 5
188 | XboxOne: 5
189 | iPhone: 2
190 | tvOS: 2
191 |
--------------------------------------------------------------------------------
/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!78 &1
4 | TagManager:
5 | serializedVersion: 2
6 | tags: []
7 | layers:
8 | - Default
9 | - TransparentFX
10 | - Ignore Raycast
11 | -
12 | - Water
13 | - UI
14 | -
15 | -
16 | - PostProcessing
17 | -
18 | -
19 | -
20 | -
21 | -
22 | -
23 | -
24 | -
25 | -
26 | -
27 | -
28 | -
29 | -
30 | -
31 | -
32 | -
33 | -
34 | -
35 | -
36 | -
37 | -
38 | -
39 | -
40 | m_SortingLayers:
41 | - name: Default
42 | uniqueID: 0
43 | locked: 0
44 |
--------------------------------------------------------------------------------
/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!5 &1
4 | TimeManager:
5 | m_ObjectHideFlags: 0
6 | Fixed Timestep: 0.02
7 | Maximum Allowed Timestep: 0.1
8 | m_TimeScale: 1
9 | Maximum Particle Timestep: 0.03
10 |
--------------------------------------------------------------------------------
/ProjectSettings/UnityConnectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!310 &1
4 | UnityConnectSettings:
5 | m_ObjectHideFlags: 0
6 | m_Enabled: 0
7 | m_TestMode: 0
8 | m_TestEventUrl:
9 | m_TestConfigUrl:
10 | m_TestInitMode: 0
11 | CrashReportingSettings:
12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes
13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate
14 | m_Enabled: 0
15 | m_CaptureEditorExceptions: 1
16 | UnityPurchasingSettings:
17 | m_Enabled: 0
18 | m_TestMode: 0
19 | UnityAnalyticsSettings:
20 | m_Enabled: 0
21 | m_InitializeOnStartup: 1
22 | m_TestMode: 0
23 | m_TestEventUrl:
24 | m_TestConfigUrl:
25 | UnityAdsSettings:
26 | m_Enabled: 0
27 | m_InitializeOnStartup: 1
28 | m_TestMode: 0
29 | m_IosGameId:
30 | m_AndroidGameId:
31 | m_GameIds: {}
32 | m_GameId:
33 | PerformanceReportingSettings:
34 | m_Enabled: 0
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OctoMapSharp
2 | An Efficient Probabilistic 3D Mapping Framework Based on Octrees. A Unity C# port of the original C++ implementation.
3 |
4 | # Acknowledgements
5 | - OctoMap white paper and C++ implementation originally developed by Kai M. Wurm and Armin Hornung. [LINK](https://github.com/OctoMap/octomap)
6 | - BitStream stream wrapper to read/write bits and other data types developed by Rubendal. [LINK](https://github.com/rubendal/BitStream)
7 |
8 | # Requirements
9 | - Unity Scripting Runtime Version .NET 4.x Equivalent
10 |
11 | # Features
12 | - Create an OctoMap data structure by defining a starting position and size as well as the minimum node size.
13 | - Add 3D points to the OctoMap and mark nodes as occupied. Recursive subdivision is used to mark the leaf node (as defined by the minimum node size) that encompasses the added point as occupied.
14 | - Mark nodes along a ray as free. Recursive subdivision is used to find leaf nodes that the ray intersects as marks them as free.
15 | - Child nodes are pruned (removed) if they share the same occupancy state and the parent node's occupancy value is set to it.
16 | - Compact bitstream serialization (as first defined in the white paper) that reduces the OctoMap to a small size by only storing parent-child relationships as opposed to individual node positions.
--------------------------------------------------------------------------------