【連載第4回】LookingGlassに点群を表示

Looking Glassで点群モデルを表示

1.目標 Looking Glassに点群モデルを表示します。

2.点群の読み込み方法

今回の点群は弊社のスキャンソフト「pronoPointsScan」で撮影したデータを使いました。

ヒエラルキーに「PointCloudRoot」という名前のGameObjectを作成します。これが点群表示のもとになります。

点群の読み込みは以下のスクリプトを使用しました。

IEnumerator ProcLoadAndViewPointCloud(string sPath)
{
    if (isRunning) { yield break; }
  // bool型
    isRunning = true;

    int nLastPercent = 0;
    yield return null;

    Mesh mesh = new Mesh();
    mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
    List<Vector3> points = new List<Vector3>();
    List<Color32> colors = new List<Color32>();
    List<int> indices = new List<int>();
    using (var sr = new StreamReader(sPath))
    {
        int index = 0;
        while (!sr.EndOfStream)
        {
            int nPercent = (int)(sr.BaseStream.Position * 100.0f / sr.BaseStream.Length);
            if (nPercent > nLastPercent)
            {
                nLastPercent = nPercent;
                yield return null;
            }

            string str = sr.ReadLine();
            string[] strs = str.Split(',');
            float x = float.Parse(strs[0]);
            float y = float.Parse(strs[1]);
            float z = float.Parse(strs[2]);
            byte r = byte.Parse(strs[3]);
            byte g = byte.Parse(strs[4]);
            byte b = byte.Parse(strs[5]);
            // 座標系をCG系に(左手系)に変更する。単位をmm->mにする
            points.Add(new Vector3(x, z, y) * 0.001f);
            colors.Add(new Color32(r, g, b, 255));
            indices.Add(index++);
        }
    }
    mesh.SetVertices(points);
    mesh.SetColors(colors);
    mesh.SetIndices(indices, MeshTopology.Points, 0);
    mesh.RecalculateBounds();

    this.PointCloudMesh = mesh;

    var leftCoroutine = StartCoroutine(OnClickViewPoints());
    // OnClickViewPointsの終了待ち
    yield return leftCoroutine;

    isRunning = false;

    yield return null;
}

IEnumerator OnClickViewPoints()
{
    PointCloudRoot.GetComponentInChildren<MeshFilter>().mesh = this.PointCloudMesh;

    yield return null;
}

上記スクリプトはどなたでもご利用いただけます。
ただし、上記スクリプトの使用、または使用不具合等により生じたいかなる損害に関しまして一切責任を負いません。

3.シェーダー

Shader "Custom/VertexColor" 
{    
    Properties     
    {         
        _PointSize("Point size", Float) = 1    
    }       
    SubShader     
    {         
        Pass         
        {             
            LOD 200                         

            CGPROGRAM             
            #pragma vertex vert
            #pragma fragment frag               

            uniform float _PointSize;               

            struct VertexInput             
            {                 
                float4 vertex: POSITION;                 
                float4 color: COLOR;            
            };               

            struct VertexOutput          
            {
                float4 pos: SV_POSITION;                 
                float4 col: COLOR;                 
                float size: PSIZE;            
            };               

            void vert(VertexInput v, out VertexOutput o)
            {
                 o.pos = UnityObjectToClipPos(v.vertex);                 
                 o.col = v.color;                 
                 o.size = _PointSize;
            }               

            float4 frag(VertexOutput o) : COLOR             
            {                 
                return o.col;             
            }             
            ENDCG         
        }     
    } 
}

4.読み込み方法

せっかくなのでシンプルに、Enterキーを押下することで点群の読み込み機構が走るように設定しました。
設定については以下の通りです。

public class PointCloudScript : MonoBehaviour
{
(略)
    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyUp(KeyCode.Return))
        {
            LoadPointCloud();
        }
    }

    /// <summary>
    /// 点群読み込み
    /// </summary>
    public void LoadPointCloud()
    {
        do
        {
            // "\\\\"を"/"に置き換え
            // StreamingAssetsから取得
            string sPath = Path.Combine(Application.streamingAssetsPath, "PointCloud").Replace("\\\\", "/");
            sPath = Path.Combine(sPath, "U2.txt").Replace("\\\\", "/");

            StartCoroutine(ProcLoadAndViewPointCloud(sPath));

        } while (false);
    }
(略)
}

読み込んだ結果はこんな感じです。


第1回:LookingGlass開封式

第2回:LookingGlassセットアップ

第3回:LookingGlassにCADモデルを表示

第4回:LookingGlassに点群を表示