public PotreeNode(string name, PointCloudMetaData metaData, PotreeBoundingBox boundingBox, PotreeNode parent) { this.name = name; this.metaData = metaData; this.boundingBox = boundingBox; this.parent = parent; }
// === FUNCTIONS === // Load PointCloud until level 5 and add to parentObject public IEnumerator LoadPointCloud(string cloudPath, GameObject parentObject, int level = 4, int pointRadius = 5) { meshConfiguration = new PointMeshConfiguration(parentObject, level, pointRadius); listNodes = new List <PotreeNode>(); // point cloud metadata pointCloudMetaData = new PointCloudMetaData(); string jsonfile; using (StreamReader reader = new StreamReader(new FileStream(cloudPath + "/cloud.js", FileMode.Open, FileAccess.Read, FileShare.Read))) { jsonfile = reader.ReadToEnd(); reader.Dispose(); } PointCloudMetaData metaData = PointCloudMetaData.ReadFromJson(jsonfile, meshConfiguration.moveToOrigin); metaData.cloudPath = cloudPath; metaData.cloudName = cloudPath.Substring(0, cloudPath.Length - 1).Substring(cloudPath.Substring(0, cloudPath.Length - 1).LastIndexOf("/") + 1); // root node string dataRPath = metaData.cloudPath + metaData.octreeDir + "/r/"; PotreeNode rootNode = new PotreeNode("", metaData, metaData.boundingBox, null); // load hierarchy LoadHierarchy(dataRPath, metaData, rootNode); // load pointcloud data //LoadAllPoints(dataRPath, metaData, rootNode); GetListNodes(dataRPath, metaData, rootNode); // now load data for nodes float startTime = DateTime.Now.Millisecond; foreach (PotreeNode node in listNodes) { LoadPoints(dataRPath, metaData, node); //Debug.Log(DateTime.Now.Millisecond); if (DateTime.Now.Millisecond - startTime > 100.0f) { //Debug.Log("resume display"); startTime = DateTime.Now.Millisecond; yield return(null); } } listNodes.Clear(); // create gameobjects rootNode.CreateAllGameObjects(meshConfiguration); yield return(null); }
private void GetListNodes(string dataRPath, PointCloudMetaData metaData, PotreeNode node) { listNodes.Add(node); // load until maxLevel if (node.GetLevel() >= meshConfiguration.maxLevel) { return; } for (int i = 0; i < 8; i++) { if (node.HasChild(i)) { GetListNodes(dataRPath, metaData, node.GetChild(i)); } } }
private void LoadPoints(string dataRPath, PointCloudMetaData metaData, PotreeNode node) { byte[] data = FindAndLoadFile(dataRPath, metaData, node.Name, ".bin"); int pointByteSize = 16;//TODO: Is this always the case? int numPoints = data.Length / pointByteSize; int offset = 0; Vector3[] vertices = new Vector3[numPoints]; Color[] colors = new Color[numPoints]; //Read in data foreach (string pointAttribute in metaData.pointAttributes) { if (pointAttribute.Equals(PointAttributes.POSITION_CARTESIAN)) { for (int i = 0; i < numPoints; i++) { //Reduction to single precision! //Note: y and z are switched float x = (float)(System.BitConverter.ToUInt32(data, offset + i * pointByteSize + 0) * metaData.scale); float y = (float)(System.BitConverter.ToUInt32(data, offset + i * pointByteSize + 8) * metaData.scale); float z = (float)(System.BitConverter.ToUInt32(data, offset + i * pointByteSize + 4) * metaData.scale); //float x = (float)(System.BitConverter.ToUInt32(data, offset + i * pointByteSize + 0) * metaData.scale + node.PotreeBoundingBox.lx); // including bounding offset //float y = (float)(System.BitConverter.ToUInt32(data, offset + i * pointByteSize + 8) * metaData.scale + node.PotreeBoundingBox.lz); // including bounding offset //float z = (float)(System.BitConverter.ToUInt32(data, offset + i * pointByteSize + 4) * metaData.scale + node.PotreeBoundingBox.ly); // including bounding offset vertices[i] = new Vector3(x, y, z); } offset += 12; } else if (pointAttribute.Equals(PointAttributes.COLOR_PACKED)) { for (int i = 0; i < numPoints; i++) { byte r = data[offset + i * pointByteSize + 0]; byte g = data[offset + i * pointByteSize + 1]; byte b = data[offset + i * pointByteSize + 2]; colors[i] = new Color32(r, g, b, 255); } offset += 3; } } node.SetPoints(vertices, colors); }
private static void LoadHierarchy(string dataRPath, PointCloudMetaData metaData, PotreeNode root) { byte[] data = FindAndLoadFile(dataRPath, metaData, root.Name, ".hrc"); int nodeByteSize = 5; int numNodes = data.Length / nodeByteSize; int offset = 0; Queue <PotreeNode> nextNodes = new Queue <PotreeNode>(); nextNodes.Enqueue(root); for (int i = 0; i < numNodes; i++) { PotreeNode n = nextNodes.Dequeue(); byte configuration = data[offset]; //uint pointcount = System.BitConverter.ToUInt32(data, offset + 1); //n.PointCount = pointcount; //TODO: Pointcount is wrong for (int j = 0; j < 8; j++) { //check bits if ((configuration & (1 << j)) != 0) { //This is done twice for some nodes PotreeNode child = new PotreeNode(n.Name + j, metaData, calculateBoundingBox(n.PotreeBoundingBox, j), n); n.SetChild(j, child); nextNodes.Enqueue(child); } } offset += 5; } HashSet <PotreeNode> parentsOfNextNodes = new HashSet <PotreeNode>(); while (nextNodes.Count != 0) { PotreeNode n = nextNodes.Dequeue().Parent; if (!parentsOfNextNodes.Contains(n)) { parentsOfNextNodes.Add(n); LoadHierarchy(dataRPath, metaData, n); } //PotreeNode n = nextNodes.Dequeue(); //LoadHierarchy(dataRPath, metaData, n); } }
private uint LoadAllPoints(string dataRPath, PointCloudMetaData metaData, PotreeNode node) { LoadPoints(dataRPath, metaData, node); uint numpoints = (uint)node.PointCount; // load until maxLevel if (node.GetLevel() >= meshConfiguration.maxLevel) { return(numpoints); } for (int i = 0; i < 8; i++) { if (node.HasChild(i)) { numpoints += LoadAllPoints(dataRPath, metaData, node.GetChild(i)); } } return(numpoints); }
public void SetChild(int index, PotreeNode node) { children[index] = node; }