diff --git a/Assets/Scripts/Editor/PointCloud/PointElement.cs b/Assets/Scripts/Editor/PointCloud/PointElement.cs index 00b73b227..9532d5f94 100644 --- a/Assets/Scripts/Editor/PointCloud/PointElement.cs +++ b/Assets/Scripts/Editor/PointCloud/PointElement.cs @@ -21,8 +21,9 @@ public enum PointElementName X, Y, Z, R, G, B, I, + RGB, } - + public struct PointElement { public PointElementType Type; diff --git a/Assets/Scripts/Editor/PointCloud/Trees/PcdPointProcessor.cs b/Assets/Scripts/Editor/PointCloud/Trees/PcdPointProcessor.cs index 582bbc04c..020783fff 100644 --- a/Assets/Scripts/Editor/PointCloud/Trees/PcdPointProcessor.cs +++ b/Assets/Scripts/Editor/PointCloud/Trees/PcdPointProcessor.cs @@ -37,7 +37,7 @@ private DefaultHeaderData ReadHeader() string[] fields = null; string[] sizes = null; string[] types = null; - + using (var view = file.CreateViewStream(0, 4096, MemoryMappedFileAccess.Read)) { var buffer = new byte[4096]; @@ -76,7 +76,7 @@ private DefaultHeaderData ReadHeader() if (line.StartsWith("VERSION")) { - var version = line.Split(new[] {' '}, 2); + var version = line.Split(new[] { ' ' }, 2); if (version[1] != "0.7") { throw new Exception($"Unsupported PCD version: {version[1]}"); @@ -104,7 +104,7 @@ private DefaultHeaderData ReadHeader() } else if (line.StartsWith("HEIGHT")) { - var height = line.Split(new[] {' '}, 2); + var height = line.Split(new[] { ' ' }, 2); if (height[1] != "1") { throw new Exception($"Unsupported PCD height: {height[1]}"); @@ -112,12 +112,12 @@ private DefaultHeaderData ReadHeader() } else if (line.StartsWith("POINTS")) { - var points = line.Split(new[] {' '}, 2); + var points = line.Split(new[] { ' ' }, 2); result.DataCount = long.Parse(points[1]); } else if (line.StartsWith("DATA")) { - var data = line.Split(new[] {' '}, 2); + var data = line.Split(new[] { ' ' }, 2); if (data[1] != "binary") { throw new Exception($"Unsupported PCD data format: {data[1]}"); @@ -154,6 +154,7 @@ private DefaultHeaderData ReadHeader() if (fields[i] == "z") name = PointElementName.Z; if (fields[i] == "intensity") name = PointElementName.I; if (fields[i] == "scalar_intensity") name = PointElementName.I; + if (fields[i] == "rgb") name = PointElementName.RGB; if (types[i] == "U" && elementSize == 1) type = PointElementType.Byte; if (types[i] == "F" && elementSize == 4) type = PointElementType.Float; @@ -162,7 +163,7 @@ private DefaultHeaderData ReadHeader() if (type.HasValue && name.HasValue) { result.Elements.Add(new PointElement() - {Type = type.Value, Name = name.Value, Offset = elementOffset}); + { Type = type.Value, Name = name.Value, Offset = elementOffset }); } elementOffset += elementSize; diff --git a/Assets/Scripts/Editor/PointCloud/Trees/PointImportJobs.cs b/Assets/Scripts/Editor/PointCloud/Trees/PointImportJobs.cs index 4bd5d3edc..058c63c91 100644 --- a/Assets/Scripts/Editor/PointCloud/Trees/PointImportJobs.cs +++ b/Assets/Scripts/Editor/PointCloud/Trees/PointImportJobs.cs @@ -36,8 +36,8 @@ public double this[int index] { unsafe { - void* ptr = (byte*) Data + index * Stride; - return Size == 4 ? *(float*) ptr : *(double*) ptr; + void* ptr = (byte*)Data + index * Stride; + return Size == 4 ? *(float*)ptr : *(double*)ptr; } } } @@ -50,6 +50,9 @@ private struct ColorAccess [NativeDisableUnsafePtrRestriction] public unsafe void* Color; + [NativeDisableUnsafePtrRestriction] + public unsafe void* ColorF; + [NativeDisableUnsafePtrRestriction] public unsafe void* Intensity; @@ -69,11 +72,19 @@ public uint this[int index] byte b = 0; if (Color != null) { - var ptr = (byte*) Color + index * Stride; + var ptr = (byte*)Color + index * Stride; r = ptr[0]; g = ptr[1]; b = ptr[2]; - color = (uint) ((b << 16) | (g << 8) | r); + color = (uint)((b << 16) | (g << 8) | r); + } + else if (ColorF != null) + { + var ptr = (byte*)ColorF + index * Stride; + r = ptr[2]; + g = ptr[1]; + b = ptr[0]; + color = (uint)((b << 16) | (g << 8) | r); } if (Intensity != null || IntensityF != null) @@ -81,25 +92,25 @@ public uint this[int index] byte intensity; if (Intensity != null) { - var ptr = (byte*) Intensity + index * Stride; + var ptr = (byte*)Intensity + index * Stride; intensity = *ptr; } else { - var ptr = (float*) ((byte*) IntensityF + index * Stride); - intensity = (byte) *ptr; + var ptr = (float*)((byte*)IntensityF + index * Stride); + intensity = (byte)*ptr; } - color |= (uint) intensity << 24; + color |= (uint)intensity << 24; if (Color == null) { - color |= (uint) ((intensity << 16) | (intensity << 8) | intensity); + color |= (uint)((intensity << 16) | (intensity << 8) | intensity); } } - else if (Color != null) + else if (Color != null || ColorF != null) { - var intensity = (byte) ((r + g + b) / 3); - color |= (uint) intensity << 24; + var intensity = (byte)((r + g + b) / 3); + color |= (uint)intensity << 24; } return color; @@ -162,7 +173,7 @@ public void Execute(int index) var y = (Y[index] + OutputCenterY) * OutputScaleY; var z = (Z[index] + OutputCenterZ) * OutputScaleZ; - var pt = Transform.MultiplyVector(new Vector3((float) x, (float) y, (float) z)); + var pt = Transform.MultiplyVector(new Vector3((float)x, (float)y, (float)z)); Output[index] = new PointCloudPoint() { @@ -215,7 +226,7 @@ unsafe struct LasConvertJob : IJobParallelFor public void Execute(int index) { - int* data = (int*) (Input + Stride * index); + int* data = (int*)(Input + Stride * index); double x = data[0] * InputScaleX + InputOffsetX; double y = data[1] * InputScaleY + InputOffsetY; @@ -225,43 +236,43 @@ public void Execute(int index) y = (y + OutputCenterY) * OutputScaleY; z = (z + OutputCenterZ) * OutputScaleZ; - var pt = Transform.MultiplyVector(new Vector3((float) x, (float) y, (float) z)); + var pt = Transform.MultiplyVector(new Vector3((float)x, (float)y, (float)z)); byte intensity; { - ushort* iptr = (ushort*) (Input + Stride * index + 12); + ushort* iptr = (ushort*)(Input + Stride * index + 12); if (LasRGB8BitWorkaround) { - intensity = (byte) *iptr; + intensity = (byte)*iptr; } else { - intensity = (byte) (*iptr >> 8); + intensity = (byte)(*iptr >> 8); } } - uint color = (uint) (intensity << 24); + uint color = (uint)(intensity << 24); if (ColorInput == null) { - color |= (uint) ((intensity << 16) | (intensity << 8) | intensity); + color |= (uint)((intensity << 16) | (intensity << 8) | intensity); } else { - ushort* rgb = (ushort*) (ColorInput + Stride * index); + ushort* rgb = (ushort*)(ColorInput + Stride * index); if (LasRGB8BitWorkaround) { - byte r = (byte) rgb[0]; - byte g = (byte) rgb[1]; - byte b = (byte) rgb[2]; - color |= (uint) ((b << 16) | (g << 8) | r); + byte r = (byte)rgb[0]; + byte g = (byte)rgb[1]; + byte b = (byte)rgb[2]; + color |= (uint)((b << 16) | (g << 8) | r); } else { - byte r = (byte) (rgb[0] >> 8); - byte g = (byte) (rgb[1] >> 8); - byte b = (byte) (rgb[2] >> 8); - color |= (uint) ((b << 16) | (g << 8) | r); + byte r = (byte)(rgb[0] >> 8); + byte g = (byte)(rgb[1] >> 8); + byte b = (byte)(rgb[2] >> 8); + color |= (uint)((b << 16) | (g << 8) | r); } } @@ -309,18 +320,18 @@ public static PointCloudBounds CalculateBounds(MemoryMappedViewAccessor accessor X = GetInputAccess(PointElementName.X, elements, ptr, stride), Y = GetInputAccess(PointElementName.Y, elements, ptr, stride), Z = GetInputAccess(PointElementName.Z, elements, ptr, stride), - Bounds = (PointCloudBounds*) bounds.GetUnsafePtr(), - Counts = (int*) counts.GetUnsafePtr(), + Bounds = (PointCloudBounds*)bounds.GetUnsafePtr(), + Counts = (int*)counts.GetUnsafePtr(), ThreadIndex = 0, }; - var h = job.Schedule((int) count, 65536); + var h = job.Schedule((int)count, 65536); while (!h.IsCompleted) { System.Threading.Thread.Sleep(100); var processed = counts.Sum(); - var progress = (float) ((double) processed / count); + var progress = (float)((double)processed / count); EditorUtility.DisplayProgressBar( string.IsNullOrEmpty(progressBarTitle) ? "Calculating bounds" : progressBarTitle, @@ -399,17 +410,17 @@ public static void ConvertData(MemoryMappedViewAccessor accessor, PointCloudPoin OutputScaleY = transformationData.OutputScaleY, OutputScaleZ = transformationData.OutputScaleZ, - Counts = (int*) counts.GetUnsafePtr(), + Counts = (int*)counts.GetUnsafePtr(), ThreadIndex = 0, }; - var h = job.Schedule((int) count, 65536); + var h = job.Schedule((int)count, 65536); while (!h.IsCompleted) { System.Threading.Thread.Sleep(100); var processed = counts.Sum(); - var progress = (float) ((double) processed / count); + var progress = (float)((double)processed / count); EditorUtility.DisplayProgressBar( string.IsNullOrEmpty(progressBarTitle) ? $"Applying transformation" : progressBarTitle, $"{processed:N0} points", progress); @@ -462,7 +473,7 @@ public static void ConvertLasData(MemoryMappedViewAccessor accessor, PointCloudP OutputScaleY = transformationData.OutputScaleY, OutputScaleZ = transformationData.OutputScaleZ, - Counts = (int*) counts.GetUnsafePtr(), + Counts = (int*)counts.GetUnsafePtr(), ThreadIndex = 0, }; @@ -486,7 +497,7 @@ public static void ConvertLasData(MemoryMappedViewAccessor accessor, PointCloudP System.Threading.Thread.Sleep(100); int processed = counts.Sum(); - float progress = (float) ((double) processed / count); + float progress = (float)((double)processed / count); EditorUtility.DisplayProgressBar( string.IsNullOrEmpty(progressBarTitle) ? $"Applying transformation" : progressBarTitle, $"{processed:N0} points", progress); @@ -511,7 +522,7 @@ private static unsafe InputAccess GetInputAccess(PointElementName name, List elements, by { result.IntensityF = data + elements[i].Offset; } + else if (elements[i].Name == PointElementName.RGB && elements[i].Type == PointElementType.Float) + { + result.ColorF = data + elements[i].Offset; + } else if (i < elements.Count - 2 && elements[i].Name == PointElementName.R && elements[i + 1].Name == PointElementName.G @@ -552,7 +567,7 @@ private static unsafe ColorAccess GetColorAccess(List elements, by } } - if (result.Intensity == null && result.IntensityF == null && result.Color == null) + if (result.Intensity == null && result.IntensityF == null && result.Color == null && result.ColorF == null) { Debug.LogError("Point Cloud has no color and intensity data. Everything will be black!"); }