Skip to content

Instantly share code, notes, and snippets.

@sasame
Created September 5, 2023 17:17
Show Gist options
  • Select an option

  • Save sasame/7b303d6062c5a2c6093dfdd40116edf6 to your computer and use it in GitHub Desktop.

Select an option

Save sasame/7b303d6062c5a2c6093dfdd40116edf6 to your computer and use it in GitHub Desktop.
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