PointCloudData ImportLaz(AssetImportContext context)
        {
            var name = Path.GetFileName(context.assetPath);

            using (var laz = new Laszip(context.assetPath))
            {
                long count = laz.Count;
                if (count > MaxPointCount)
                {
                    Debug.LogWarning($"Too many points ({count:n0}), truncating to {MaxPointCount:n0}");
                    count = MaxPointCount;
                }

                var bounds = new PointCloudBounds()
                {
                    MinX = laz.MinX,
                    MinY = laz.MinY,
                    MinZ = laz.MinZ,
                    MaxX = laz.MaxX,
                    MaxY = laz.MaxY,
                    MaxZ = laz.MaxZ,
                };

                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;
                }

                bool hasColor  = laz.HasColor;
                var  transform = GetTransform();

                var points = new PointCloudPoint[(int)count];

                try
                {
                    for (long i = 0; i < count; i++)
                    {
                        if ((i % (128 * 1024)) == 0)
                        {
                            float progress = (float)((double)i / count);
                            EditorUtility.DisplayProgressBar($"Importing {name}", $"{i:N0} points", progress);
                        }

                        var    p = laz.GetNextPoint();
                        double x = (p.X + centerX) * scaleX;
                        double y = (p.Y + centerY) * scaleY;
                        double z = (p.Z + centerZ) * scaleZ;

                        var pt = transform.MultiplyVector(new Vector3((float)x, (float)y, (float)z));

                        byte intensity;
                        if (LasRGB8BitWorkaround)
                        {
                            intensity = (byte)(p.Intensity >> 0);
                        }
                        else
                        {
                            intensity = (byte)(p.Intensity >> 8);
                        }

                        uint color = (uint)(intensity << 24);
                        if (hasColor)
                        {
                            if (LasRGB8BitWorkaround)
                            {
                                byte r = (byte)(p.Red >> 0);
                                byte g = (byte)(p.Green >> 0);
                                byte b = (byte)(p.Blue >> 0);
                                color |= (uint)((b << 16) | (g << 8) | r);
                            }
                            else
                            {
                                byte r = (byte)(p.Red >> 8);
                                byte g = (byte)(p.Green >> 8);
                                byte b = (byte)(p.Blue >> 8);
                                color |= (uint)((b << 16) | (g << 8) | r);
                            }
                        }
                        else
                        {
                            color |= (uint)((intensity << 16) | (intensity << 8) | intensity);
                        }

                        points[i] = new PointCloudPoint()
                        {
                            Position = pt,
                            Color    = color,
                        };
                    }
                }
                finally
                {
                    EditorUtility.ClearProgressBar();
                }

                var unityBounds = GetBounds(bounds);
                unityBounds.center  = transform.MultiplyPoint3x4(unityBounds.center);
                unityBounds.extents = transform.MultiplyVector(unityBounds.extents);

                return(PointCloudData.Create(points, unityBounds, hasColor, transform.MultiplyPoint3x4(bounds.Center), transform.MultiplyVector(bounds.Extents)));
            }
        }
Esempio n. 2
0
        private PointCloudData <T> ParseLines(FileInfo f, int id)
        {
            _metadata = new PointCloudMetaData();
            bool isInitialized = false;
            int  index         = 0;

            _startData = false;
            T[]      points = new T[0];
            string[] lines  = new string[0];
            try
            {
                lines = File.ReadAllLines(f.FullName);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.Log(e.Message);
            }
            foreach (string line in lines)
            {
                // Parse metadata
                if (!_startData)
                {
                    ParseMetadata(line, ref _metadata);
                }
                else
                {
                    if (!isInitialized)
                    {
                        points        = new T[_metadata.pointSize];
                        isInitialized = true;
                    }

                    // Parse vertices
                    string[] values = line.Split(' ');
                    if (values.Length != _metadata.numFields)
                    {
                        throw new System.Exception("Vertices was not same as fields");
                    }
                    float x = 0, y = 0, z = 0;
                    bool  success = float.TryParse(values[0], out x);
                    success = success && float.TryParse(values[1], out y);
                    success = success && float.TryParse(values[2], out z);
                    if (!success)
                    {
                        throw new System.Exception("Could not parse a vertex");
                    }
                    if (_metadata.field == PointCloudDataType.XYZ)
                    {
                        Vector3  pos   = new Vector3(x, y, z);
                        PointXYZ point = new PointXYZ(pos);
                        points[index++] = (T)point;
                    }

                    /*
                     * else if (_metadata.field == PointCloudDataType.XYZRGB)
                     * {
                     *  float rgba = float.Parse(values[3]);
                     *  byte r, g, b;
                     *
                     *  // Unpack packed float - 3 channel
                     *  byte[] colorBytes = BitConverter.GetBytes(rgba);
                     *  r = colorBytes[0];
                     *  g = colorBytes[1];
                     *  b = colorBytes[2];
                     *
                     *  Vector3 point = new Vector3(x, y, z);
                     *  Color col = new Color(r, g, b);
                     *  points[index++] = new PointXYZRGBA(point, col);
                     * }
                     * else if (_metadata.field == PointCloudDataType.XYZRGBA)
                     * {
                     *  int rgba = int.Parse(values[3]);
                     *  byte r, g, b, a;
                     *
                     *  // Unpack float - 4 channel
                     *  byte[] colorBytes = BitConverter.GetBytes(rgba);
                     *  r = colorBytes[0];
                     *  g = colorBytes[1];
                     *  b = colorBytes[2];
                     *  a = colorBytes[3];
                     *
                     *  Vector3 point = new Vector3(x, y, z);
                     *  Color32 col = new Color32(r, g, b, a);
                     *  points[index++] = new PointXYZRGBA(point, col);
                     * }
                     */
                }
            }
            if (points.Length == 0 || points.Length != _metadata.pointSize)
            {
                throw new System.Exception("Vertices were empty or did not match declared points. Was:" +
                                           points.Length + ", but expected: " + _metadata.pointSize);
            }
            PointCloudData <T> pcd = new PointCloudData <T>(points, points.Length, _metadata, id);

            return(pcd);
        }
 public void SetPointCloudDataFromInteropData(PointCloudData <PointXYZConfidence> pcd, PointCloudMetaData metadata)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Reads the specified file and returns PointCloudData, assigning the given frame id.
        /// </summary>
        /// <param name="f"></param>
        public virtual PointCloudData <PointXYZConfidence> ParseFile(FileInfo f, int id)
        {
            _metadata = new PointCloudMetaData();
            bool isInitialized = false;
            int  index         = 0;

            _startData = false;
            PointXYZConfidence[] points = new PointXYZConfidence[0];
            string[]             lines  = new string[0];
            int numPoints = 0;

            try
            {
                lines = File.ReadAllLines(f.FullName);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.Log(e.Message);
            }
            foreach (string line in lines)
            {
                // Parse metadata
                if (!_startData)
                {
                    ParseMetadata(line, ref _metadata);
                }
                else
                {
                    if (!isInitialized)
                    {
                        numPoints = _metadata.pointSize;
                        if (_metadata.pointSize != lines.Length - 11)
                        {
                            numPoints = lines.Length - 11;
                            UnityEngine.Debug.Log("Metadata point count didn't match. Overriding point count.");
                        }
                        points        = new PointXYZConfidence[numPoints];
                        isInitialized = true;
                    }

                    // Parse vertices
                    string[] values = line.Split(' ');
                    if (values.Length != _metadata.numFields)
                    {
                        throw new System.Exception("Vertices was not same as fields");
                    }
                    float x = 0, y = 0, z = 0, conf = 0;
                    bool  success = float.TryParse(values[0], out x);
                    success = success && float.TryParse(values[1], out y);
                    success = success && float.TryParse(values[2], out z);
                    success = success && float.TryParse(values[3], out conf);

                    //-3.402823E+38 -3.402823E+38 -3.402823E+38 0
                    // Watch for these values - causes Unity AABB error. Skip for now. To investigate.
                    if (conf == 0)
                    {
                        points[index++] = new PointXYZConfidence(Vector3.zero, 0);
                        continue;
                    }

                    if (!success)
                    {
                        throw new System.Exception("Could not parse a vertex");
                    }
                    Vector3            pos   = new Vector3(x, y, z);
                    PointXYZConfidence point = new PointXYZConfidence(pos, conf);
                    points[index++] = point;
                }
            }
            // Fixing metadata
            _metadata.maxSize = MaxPoints;

            if (points.Length == 0)
            {
                throw new System.Exception("Vertices were empty");
            }
            PointCloudData <PointXYZConfidence> pcd = new PointCloudData <PointXYZConfidence>(points, numPoints, _metadata,
                                                                                              id);

            return(pcd);
        }