Unity

unityでポイントクラウド用に点を描画してみた。

今点群マップにハマっています。というのも格安LiDARを買ったので。
そこで描画するときにいくつかハマったのでハマりポイントと
unityで点が描画できることがわかったのでやり方を。

試したこと

1.律儀にプリミティブでスフィアを作った
2.スクリプトからポリゴン書いた
3.頂点が65535を超えて描画されなかったので32bit化した
4.純粋にポリゴンじゃなくて点を描画した

※今回使用したサンプルデータは自前で記録したLiDARのデータです。

1.律儀にプリミティブでスフィアを作った

generatePrimitive.cs
GameObject PointDot = GameObject.CreatePrimitive(PrimitiveType.Sphere);

これでプレハブから複製することなく基本3Dオブジェクトが生成できます。
タイプはsphere,cube,quadなど。

ただし、当たり前ですが、ポイントクラウドで点ごとにこれを行うと
ゲームオブジェクトが馬鹿みたいに増えてめちゃめちゃ重くなります。
ちょっと手っ取り早く見たいときでも避けましょう。

2.スクリプトからポリゴン書いた

数年前、DK2の頃にポジトラ用カメラからポジトラ範囲を描画するために
自前でポリゴンを書いたことがあったので、そんな感じで各点群から三角錐なメッシュを張ってみました。

generateMesh.cs
           Vector3 center = new Vector3(x, y, z);//点群点
           //頂点
           vertices[i * Vertex_size] = center + (Vector3.up);
           vertices[i * Vertex_size + 1  ] = center + (Vector3.right   + Vector3.down + Vector3.back);
           vertices[i * Vertex_size + 2  ] = center + (Vector3.left    + Vector3.down + Vector3.back);
           vertices[i * Vertex_size + 3  ] = center + (Vector3.forward + Vector3.down               );
           //三角形

           //手前
           triangles[i * Surface_size      ] = i * Vertex_size     ;
           triangles[i * Surface_size + 1  ] = i * Vertex_size + 1 ;
           triangles[i * Surface_size + 2  ] = i * Vertex_size + 2 ;
           //左奥
           triangles[i * Surface_size + 3  ] = i * Vertex_size     ;
           triangles[i * Surface_size + 4  ] = i * Vertex_size + 2 ;
           triangles[i * Surface_size + 5  ] = i * Vertex_size + 3 ;
           //右奥
           triangles[i * Surface_size + 6  ] = i * Vertex_size     ;
           triangles[i * Surface_size + 7  ] = i * Vertex_size + 3 ;
           triangles[i * Surface_size + 8  ] = i * Vertex_size + 1 ;
           //底面
           triangles[i * Surface_size + 9  ] = i * Vertex_size + 1 ;
           triangles[i * Surface_size + 10 ] = i * Vertex_size + 2 ;
           triangles[i * Surface_size + 11 ] = i * Vertex_size + 3 ;

こんなかんじで頂点行列作って、面をどの頂点で作るかで行列作って点ごとに追加してmeshfilterに渡してました。
この当時はunityで点の描画が出来ると知らず、三角錐っていう発想。

3.頂点が65535を超えて描画されなかったので32bit化した

このメッシュ化で負荷は減ったので運用していたのですが、なぜか360度ではなく60度ぐらいしか描画されませんでした。
よくよく見てみると60度あたりで頂点数が65535を越えていました。そういえば3Dモデルも65535越えたら分割されてましたっけ。
ってことで65535を越えるために32bit化しました。unity2017からの機能?

32IndexFormat.cs
Mesh mesh = new Mesh();
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

これでインデックスバッファーが32bit対応になり頂点が65535越えても描画されます。
Unity - Scripting API: Mesh.indexFormat

4.純粋にポリゴンじゃなくて点を描画した

65535頂点あたりを調べてて、点を描画できることがわかったので切り替え。

SetIndices.cs
    int[] indices = new int[vertices.Length];
       for (int i = 0; i < vertices.Length; i++)
       {
           indices[i] = i;
       }
       filter.mesh.SetIndices(indices, MeshTopology.Points, 0);

MeshTopologyをPointsに切り替える(っぽい)。
indicesが点群行列。頂点行列ぶっこんでもうまく行かなくて作った。

よく見る点だけの描画はこうやってたんだねぇ、知らなかったw