Unity绘制点云(untiy draw point cloud)

Posted 御雪妃舞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity绘制点云(untiy draw point cloud)相关的知识,希望对你有一定的参考价值。

现在好多图像识别会设计点云显示问题,这里简单说下
本篇先说下静态实现方法:

一.Mesh实现

使用mesh的方式显示点云,比如本篇以绘制一个大象的点云为例
mesh方式实现结果如图:

点云的数据这里是网上找的数据,然后存成csv文件读取,个人认为csv文件在读取数据方面还是很方便的。
核心代码如下:

using UnityEngine;
using System.Collections;
using System.IO;

public class DrawMeshPointCloud : MonoBehaviour

    ArrayList list = new ArrayList();

    void Start()
    
        // 1. 读取数据
        list = ReadFile();

        // 2. 渲染
        CreateMesh();
    

    ArrayList ReadFile()
    
        // 提前将点云存成csv文件放在Assert/StreamingAssets文件夹下,文本的每行代表一个点,由点的x,y,z
        //csv文件存储数据,用逗号分隔,比较容易读取处理
        string path = (Application.streamingAssetsPath + "/" + "elephant.csv");
        FileInfo fInfo = new FileInfo(path);

        string s = "";
        StreamReader r;
        ArrayList vecList = new ArrayList();

        if (fInfo.Exists)
        
            r = new StreamReader(path);
        
        else
        
            Debug.Log("文件不存在");
            return null;
        
        // 点云数据存入队列
        while ((s = r.ReadLine()) != null)
        
            string[] words = s.Split(","[0]);

            Vector3 xyz = new Vector3(float.Parse(words[0]), -float.Parse(words[1]), float.Parse(words[2])) * 10;
            vecList.Add(xyz);
        

        return vecList;
    



    void CreateMesh()
    
        int num = list.Count;

        GameObject pointObj = new GameObject();
        pointObj.name = "new";
        //处理大象朝向
        pointObj.transform.rotation = Quaternion.Euler(new Vector3(180, -180, 0));
        pointObj.AddComponent<MeshFilter>();
        pointObj.AddComponent<MeshRenderer>();
        Mesh meshNeed = new Mesh();
        Material mat = new Material(Shader.Find("Custom/VertexColor"));
        pointObj.GetComponent<MeshFilter>().mesh = meshNeed;
        pointObj.GetComponent<MeshRenderer>().material = mat;

        Vector3[] points = new Vector3[num];
        Color[] colors = new Color[num];
        int[] indecies = new int[num];
        for (int i = 0; i < num; ++i)
        
            points[i] = (Vector3)list[i];
            indecies[i] = i;
            colors[i] = Color.white;
        

        meshNeed.vertices = points;
        meshNeed.colors = colors;
        meshNeed.SetIndices(indecies, MeshTopology.Points, 0);

    

二、粒子的方式实现

场景里添加一个粒子系统,设置速度为0,也可以实现
实现效果如图:

核心代码如下:

 ParticleSystem.Particle[] allParticles;         // 所有粒子的集合
    void DrawPointCloud(ArrayList drawList)
    
        var main = particleSystem.main;
        main.startSpeed = 0.0f;                           // 设置粒子的初始速度为0
        main.startLifetime = 1000.0f;

        var pointCount = drawList.Count;
        allParticles = new ParticleSystem.Particle[pointCount];
        main.maxParticles = pointCount;
        particleSystem.Emit(pointCount);
        particleSystem.GetParticles(allParticles);
        for (int i = 0; i < pointCount; i++)
        
            allParticles[i].position = (Vector3)drawList[i];    // 设置每个点的位置
            allParticles[i].startColor = Color.yellow;    // 设置每个点的rgb
            allParticles[i].startSize = 0.02f;                     
        

        particleSystem.SetParticles(allParticles, pointCount);      // 将点云载入粒子系统
    

总结

两种方法都能实现,具体的性能方面自己可以具体比较下,目前这两种方式都能实现静态的点云显示,个人偏向第二种,因为后面动态的点云更新,用第二种比较方便。

完整工程下载

以上是关于Unity绘制点云(untiy draw point cloud)的主要内容,如果未能解决你的问题,请参考以下文章

Unity自定义Untiy天空

学习进度12

Unity 实现《物理画线》Draw Physics Line 总览

Untiy截图更新,及截取透明图片签字

Untiy3D性能优化实战记录

Untiy3D性能优化实战记录