LoginSignup
13
12

More than 5 years have passed since last update.

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

Posted at

今点群マップにハマっています。というのも格安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

13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12