Created
September 5, 2023 17:17
-
-
Save sasame/7b303d6062c5a2c6093dfdd40116edf6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Collections; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| using System.Text; | |
| using UnityEngine; | |
| public class LASImporter | |
| { | |
| public void Import(string filename) | |
| { | |
| using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) | |
| { | |
| Import(fs); | |
| } | |
| } | |
| void Import(Stream stream) | |
| { | |
| BinaryReader br = new BinaryReader(stream); | |
| var fileSignature = br.ReadBytes(4); | |
| var fileSourceID = br.ReadUInt16(); | |
| var globalEncoding = br.ReadUInt16(); | |
| var guidData1 = br.ReadUInt32(); | |
| var guidData2 = br.ReadUInt16(); | |
| var guidData3 = br.ReadUInt16(); | |
| var guidData4 = br.ReadBytes(8); | |
| var versionMajor = br.ReadByte(); | |
| var versionMinor = br.ReadByte(); | |
| var systemIdentifier = Encoding.UTF8.GetString(br.ReadBytes(32)); | |
| Debug.Log(systemIdentifier); | |
| var generatingSoftware = Encoding.UTF8.GetString(br.ReadBytes(32)); | |
| Debug.Log(generatingSoftware); | |
| var fileCreationDayOfYear = br.ReadUInt16(); | |
| var fileCreationYear = br.ReadUInt16(); | |
| var headerSize = br.ReadUInt16(); | |
| Debug.Log("headerSize:" + headerSize); | |
| var offsetToPointData = br.ReadUInt32(); | |
| Debug.Log("offsetToPointData:" + offsetToPointData); | |
| var numberOfVariableLengthRecords = br.ReadUInt32(); | |
| Debug.Log("numberOfVariableLengthRecords:" + numberOfVariableLengthRecords); | |
| var pointDataFormatID = br.ReadByte(); | |
| Debug.Log("pointDataFormatID:" + pointDataFormatID); | |
| var pointDataRecordLength = br.ReadUInt16(); | |
| Debug.Log("pointDataRecordLength:" + pointDataRecordLength); | |
| var numberOfPointRecords = br.ReadUInt32(); | |
| Debug.Log("numberOfPointRecords:" + numberOfPointRecords); | |
| var numberOfPointByReturn = new uint[5]; | |
| for(int i=0;i<5;++i) | |
| { | |
| numberOfPointByReturn[i] = br.ReadUInt32(); | |
| } | |
| var xScaleFactor = br.ReadDouble(); | |
| var yScaleFactor = br.ReadDouble(); | |
| var zScaleFactor = br.ReadDouble(); | |
| Debug.Log(xScaleFactor + "," + yScaleFactor + "," + zScaleFactor); | |
| var xOffset = br.ReadDouble(); | |
| var yOffset = br.ReadDouble(); | |
| var zOffset = br.ReadDouble(); | |
| Debug.Log(xOffset + "," + yOffset + "," + zOffset); | |
| var maxX = br.ReadDouble(); | |
| var minX = br.ReadDouble(); | |
| var maxY = br.ReadDouble(); | |
| var minY = br.ReadDouble(); | |
| var maxZ = br.ReadDouble(); | |
| var minZ = br.ReadDouble(); | |
| Debug.Log(maxX + "," + maxY + "," + maxZ); | |
| Debug.Log(minX + "," + minY + "," + minZ); | |
| Debug.Log("Position:" + br.BaseStream.Position); | |
| Debug.Log("Length:" + br.BaseStream.Length); | |
| br.BaseStream.Seek(offsetToPointData, SeekOrigin.Begin); | |
| var mesh = ReadPointData_Format3(br, (int)numberOfPointRecords, | |
| xScaleFactor, | |
| yScaleFactor, | |
| zScaleFactor, | |
| xOffset - minX, | |
| yOffset - minY, | |
| zOffset - minZ, | |
| pointDataRecordLength | |
| ); | |
| GameObject o = new GameObject("las"); | |
| var mf = o.AddComponent<MeshFilter>(); | |
| mf.sharedMesh = mesh; | |
| var mr = o.AddComponent<MeshRenderer>(); | |
| Debug.Log("Last Position:" + br.BaseStream.Position); | |
| } | |
| Mesh ReadPointData_Format3(BinaryReader br, | |
| int numPoints, | |
| double xScaleFactor, | |
| double yScaleFactor, | |
| double zScaleFactor, | |
| double xOffset, | |
| double yOffset, | |
| double zOffset, | |
| int pointDataRecordLength | |
| ) | |
| { | |
| var from = br.BaseStream.Position; | |
| Mesh mesh = new Mesh(); | |
| Vector3[] points = new Vector3[numPoints]; | |
| Color32[] colors = new Color32[numPoints]; | |
| int[] indices = new int[numPoints]; | |
| for (int i = 0; i < numPoints; ++i) | |
| { | |
| br.BaseStream.Seek(from + i * pointDataRecordLength, SeekOrigin.Begin); | |
| var x = br.ReadInt32(); // 4 | |
| var y = br.ReadInt32(); // 8 | |
| var z = br.ReadInt32(); // 12 | |
| var intensity = br.ReadUInt16(); // 14 | |
| var pack1 = br.ReadByte(); // 15 | |
| var classification = br.ReadByte(); // 16 | |
| var scanAngleRank = br.ReadByte(); // 17 | |
| var userData = br.ReadByte(); // 18 | |
| var pointSourceID = br.ReadUInt16(); // 20 | |
| var gpsTime = br.ReadDouble(); // 28 | |
| var red = br.ReadUInt16(); // 30 | |
| var green = br.ReadUInt16(); //32 | |
| var blue = br.ReadUInt16(); // 34 | |
| points[i] = new Vector3( | |
| (float)(x * xScaleFactor + xOffset), | |
| (float)(z * zScaleFactor + zOffset), | |
| (float)(y * yScaleFactor + yOffset) | |
| ); | |
| colors[i] = new Color( | |
| red / (float)ushort.MaxValue, | |
| green / (float)ushort.MaxValue, | |
| blue / (float)ushort.MaxValue, | |
| intensity / (float)ushort.MaxValue | |
| ); | |
| indices[i] = i; | |
| } | |
| mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; | |
| mesh.SetVertices(points); | |
| mesh.SetColors(colors); | |
| mesh.SetIndices(indices, MeshTopology.Points,0); | |
| { | |
| Vector3 min = points[0]; | |
| Vector3 max = points[0]; | |
| for(int i=0;i<points.Length;++i) | |
| { | |
| min = Vector3.Min(min, points[i]); | |
| max = Vector3.Max(max, points[i]); | |
| } | |
| Debug.Log("mesh min:" + min.ToString()); | |
| Debug.Log("mesh max:" + max.ToString()); | |
| } | |
| return mesh; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment