public static void ConvertLasData(MemoryMappedViewAccessor accessor, PointCloudPoint[] target, int count, ref LasPointProcessor.LasHeader header, TransformationData transformationData, string progressBarTitle = null) { unsafe { byte *sourcePtr = null; accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref sourcePtr); try { fixed(PointCloudPoint *targetPtr = target) { var counts = new NativeArray <int>(JobsUtility.MaxJobThreadCount, Allocator.TempJob); try { var job = new LasConvertJob() { LasRGB8BitWorkaround = transformationData.LasRGB8BitWorkaround, Input = sourcePtr, Stride = header.PointDataSize, Output = targetPtr, Transform = transformationData.TransformationMatrix, InputScaleX = header.ScaleX, InputScaleY = header.ScaleY, InputScaleZ = header.ScaleZ, InputOffsetX = header.OffsetX, InputOffsetY = header.OffsetY, InputOffsetZ = header.OffsetZ, OutputCenterX = transformationData.OutputCenterX, OutputCenterY = transformationData.OutputCenterY, OutputCenterZ = transformationData.OutputCenterZ, OutputScaleX = transformationData.OutputScaleX, OutputScaleY = transformationData.OutputScaleY, OutputScaleZ = transformationData.OutputScaleZ, Counts = (int *)counts.GetUnsafePtr(), ThreadIndex = 0, }; if (header.PointDataFormat == 2) { job.ColorInput = sourcePtr + 20; } else if (header.PointDataFormat == 3 || header.PointDataFormat == 5) { job.ColorInput = sourcePtr + 28; } else if (header.PointDataFormat == 7 || header.PointDataFormat == 8 || header.PointDataFormat == 10) { job.ColorInput = sourcePtr + 30; } var h = job.Schedule(count, 65536); while (!h.IsCompleted) { System.Threading.Thread.Sleep(100); int processed = counts.Sum(); float progress = (float)((double)processed / count); EditorUtility.DisplayProgressBar( string.IsNullOrEmpty(progressBarTitle) ? $"Applying transformation" : progressBarTitle, $"{processed:N0} points", progress); } } finally { EditorUtility.ClearProgressBar(); counts.Dispose(); } } } finally { accessor.SafeMemoryMappedViewHandle.ReleasePointer(); } } }
unsafe bool LasConvert(AssetImportContext context, byte *ptr, int stride, int count, ref LasHeader header, PointCloudBounds bounds, PointCloudPoint *points) { var name = Path.GetFileName(context.assetPath); var counts = new NativeArray <int>(JobsUtility.MaxJobThreadCount, Allocator.TempJob); try { double scaleX, scaleY, scaleZ; double centerX, centerY, centerZ; if (Normalize) { centerX = -0.5 * (bounds.MaxX + bounds.MinX); centerY = -0.5 * (bounds.MaxY + bounds.MinY); centerZ = -0.5 * (bounds.MaxZ + bounds.MinZ); scaleX = 2.0 / (bounds.MaxX - bounds.MinX); scaleY = 2.0 / (bounds.MaxY - bounds.MinY); scaleZ = 2.0 / (bounds.MaxZ - bounds.MinZ); } else if (Center) { centerX = -0.5 * (bounds.MaxX + bounds.MinX); centerY = -0.5 * (bounds.MaxY + bounds.MinY); centerZ = -0.5 * (bounds.MaxZ + bounds.MinZ); scaleX = scaleY = scaleZ = 1.0; } else { centerX = centerY = centerZ = 0.0; scaleX = scaleY = scaleZ = 1.0; } var job = new LasConvertJob() { LasRGB8BitWorkaround = LasRGB8BitWorkaround, Input = ptr, Stride = stride, Output = points, Transform = GetTransform(), InputScaleX = header.ScaleX, InputScaleY = header.ScaleY, InputScaleZ = header.ScaleZ, InputOffsetX = header.OffsetX, InputOffsetY = header.OffsetY, InputOffsetZ = header.OffsetZ, OutputCenterX = centerX, OutputCenterY = centerY, OutputCenterZ = centerZ, OutputScaleX = scaleX, OutputScaleY = scaleY, OutputScaleZ = scaleZ, Counts = (int *)counts.GetUnsafePtr(), ThreadIndex = 0, }; bool hasColor = false; if (header.PointDataFormat == 2) { job.ColorInput = ptr + 20; hasColor = true; } else if (header.PointDataFormat == 3 || header.PointDataFormat == 5) { job.ColorInput = ptr + 28; hasColor = true; } else if (header.PointDataFormat == 7 || header.PointDataFormat == 8 || header.PointDataFormat == 10) { job.ColorInput = ptr + 30; hasColor = true; } var h = job.Schedule((int)count, 65536); while (!h.IsCompleted) { System.Threading.Thread.Sleep(100); int processed = counts.Sum(); float progress = (float)((double)processed / count); EditorUtility.DisplayProgressBar($"Importing {name}", $"{processed:N0} points", progress); } return(hasColor); } finally { EditorUtility.ClearProgressBar(); counts.Dispose(); } }