質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1725閲覧

Unityで点群からポリゴンを自動生成するプログラムの使い方がわかりません。

osugutto

総合スコア2

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2022/09/08 11:29

編集2022/09/08 11:31

前提

Unityで点群からポリゴンを自動生成するプログラムを書きたいです。
この
https://edom18.hateblo.jp/entry/2018/03/25/100234
サイトを参考にしているのですが、点群の情報をどこに入れれば良いかがわかりません。

実現したいこと

このコードのどの変数にデータを入れればいいかを知りたいです。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEngine; 5 6/// <summary> 7/// Draw mesh by clicked points. 8/// </summary> 9public class DrawMesh : MonoBehaviour 10{ 11 private List<int> _triangles = new List<int>(); 12 private List<Vector3> _vertices = new List<Vector3>(); 13 private Dictionary<int, bool> _verticesBuffer = new Dictionary<int, bool>(); 14 15 private Vector3 _prevDirection = Vector3.zero; 16 17 private bool _isIncluding = false; 18 private int _curIndex; 19 private int _nextIndex; 20 private int _prevIndex; 21 22 private Vector3 CurrentPoint 23 { 24 get { return _vertices[_curIndex]; } 25 } 26 private Vector3 PreviousPoiont 27 { 28 get { return _vertices[_prevIndex]; } 29 } 30 private Vector3 NextPoint 31 { 32 get { return _vertices[_nextIndex]; } 33 } 34 35 /// <summary> 36 /// Clear buffers. 37 /// </summary> 38 private void Clear() 39 { 40 _vertices.Clear(); 41 _verticesBuffer.Clear(); 42 _triangles.Clear(); 43 } 44 45 private void Initialize(List<Vector3> vertices) 46 { 47 Clear(); 48 49 // 設定された頂点を保持しておく 50 _vertices.AddRange(vertices); 51 52 // 全頂点のインデックスを保持、使用済みフラグをfalseで初期化 53 for (int i = 0; i < vertices.Count; i++) 54 { 55 _verticesBuffer.Add(i, false); 56 } 57 } 58 59 /// <summary> 60 /// Create mesh by vertices. 61 /// </summary> 62 public GameObject CreateMesh(List<Vector3> vertices) 63 { 64 Initialize(vertices); 65 66 while (true) 67 { 68 KeyValuePair<int, bool>[] left = _verticesBuffer.Where(buf => !buf.Value).ToArray(); 69 if (left.Length <= 3) 70 { 71 break; 72 } 73 DetecteTriangle(); 74 } 75 76 int[] keys = _verticesBuffer.Keys.ToArray(); 77 foreach (int key in keys) 78 { 79 if (!_verticesBuffer[key]) 80 { 81 _verticesBuffer[key] = true; 82 _triangles.Add(key); 83 } 84 } 85 86 Debug.Log("Done chekcing."); 87 88 Mesh mesh = new Mesh(); 89 mesh.vertices = _vertices.ToArray(); 90 91 mesh.triangles = _triangles.ToArray(); 92 mesh.RecalculateNormals(); 93 94 GameObject go = new GameObject("MeshObject", typeof(MeshFilter), typeof(MeshRenderer)); 95 96 MeshFilter filter = go.GetComponent<MeshFilter>(); 97 filter.mesh = mesh; 98 99 return go; 100 } 101 102 /// <summary> 103 /// Detect triangle from far point. 104 /// </summary> 105 private void DetecteTriangle() 106 { 107 if (!_isIncluding) 108 { 109 FindFarPoint(); 110 } 111 112 Vector3 a = CurrentPoint; 113 Vector3 b = NextPoint; 114 Vector3 c = PreviousPoiont; 115 116 Vector3 edge1 = b - a; 117 Vector3 edge2 = c - a; 118 119 float angle = Vector3.Angle(edge1, edge2); 120 if (angle >= 180) 121 { 122 Debug.LogError("Something was wrong."); 123 return; 124 } 125 126 if (IsIncludePoint()) 127 { 128 Debug.Log("Point is including."); 129 130 // try to find other point. 131 _isIncluding = true; 132 133 // Store current triangle dicretion. 134 _prevDirection = GetCurrentDirection(); 135 136 MoveToNext(); 137 138 return; 139 } 140 141 _isIncluding = false; 142 143 _triangles.Add(_curIndex); 144 _triangles.Add(_nextIndex); 145 _triangles.Add(_prevIndex); 146 147 bool isDtected = true; 148 _verticesBuffer[_curIndex] = isDtected; 149 } 150 151 /// <summary> 152 /// Check to include point in the triangle. 153 /// </summary> 154 /// <returns></returns> 155 private bool IsIncludePoint() 156 { 157 foreach (var key in _verticesBuffer.Keys) 158 { 159 int index = key; 160 161 if (_verticesBuffer[key]) 162 { 163 continue; 164 } 165 166 // skip if index in detected three points. 167 if (index == _curIndex || index == _nextIndex || index == _prevIndex) 168 { 169 continue; 170 } 171 172 if (CheckInPoint(_vertices[index])) 173 { 174 return true; 175 } 176 } 177 178 return false; 179 } 180 181 /// <summary> 182 /// Get current triangle direction. 183 /// </summary> 184 /// <returns>Triagnel direction normal.</returns> 185 private Vector3 GetCurrentDirection() 186 { 187 Vector3 edge1 = (NextPoint - CurrentPoint).normalized; 188 Vector3 edge2 = (PreviousPoiont - CurrentPoint).normalized; 189 190 return Vector3.Cross(edge1, edge2); 191 } 192 193 /// <summary> 194 /// Check including point. 195 /// </summary> 196 /// <param name="target">Target point.</param> 197 /// <returns>return true if point is including.</returns> 198 private bool CheckInPoint(Vector3 target) 199 { 200 // Triangle points. 201 Vector3[] tp = 202 { 203 CurrentPoint, 204 NextPoint, 205 PreviousPoiont, 206 }; 207 208 Vector3 prevNormal = default(Vector3); 209 for (int i = 0; i < tp.Length; i++) 210 { 211 Vector3 edge1 = (target - tp[i]); 212 Vector3 edge2 = (target - tp[(i + 1) % tp.Length]); 213 214 Vector3 normal = Vector3.Cross(edge1, edge2).normalized; 215 216 if (prevNormal == default(Vector3)) 217 { 218 prevNormal = normal; 219 continue; 220 } 221 222 // If not same direction, the point out of a triangle. 223 if (Vector3.Dot(prevNormal, normal) <= 0.99f) 224 { 225 return false; 226 } 227 } 228 229 return true; 230 } 231 232 /// <summary> 233 /// Poition reference move to next. 234 /// </summary> 235 private void MoveToNext() 236 { 237 _curIndex = FindNextIndex(_curIndex); 238 _nextIndex = FindNextIndex(_curIndex); 239 _prevIndex = FindPrevIndex(_curIndex); 240 } 241 242 /// <summary> 243 /// 原点から最も遠い点を探す 244 /// </summary> 245 private void FindFarPoint() 246 { 247 int farIndex = -1; 248 float maxDist = float.MinValue; 249 250 foreach (var key in _verticesBuffer.Keys) 251 { 252 if (_verticesBuffer[key]) 253 { 254 continue; 255 } 256 257 float dist = Vector3.Distance(Vector3.zero, _vertices[key]); 258 if (dist > maxDist) 259 { 260 maxDist = dist; 261 farIndex = key; 262 } 263 } 264 265 _curIndex = farIndex; 266 _nextIndex = FindNextIndex(_curIndex); 267 _prevIndex = FindPrevIndex(_curIndex); 268 } 269 270 /// <summary> 271 /// 指定インデックスから調べて次の有効頂点インデックスを探す 272 /// </summary> 273 private int FindNextIndex(int start) 274 { 275 int i = start; 276 while (true) 277 { 278 i = (i + 1) % _vertices.Count; 279 if (!_verticesBuffer[i]) 280 { 281 return i; 282 } 283 } 284 } 285 286 /// <summary> 287 /// 指定インデックスから調べて前の有効頂点インデックスを探す 288 /// </summary> 289 private int FindPrevIndex(int start) 290 { 291 int i = start; 292 while (true) 293 { 294 i = (i - 1) >= 0 ? i - 1 : _vertices.Count - 1; 295 if (!_verticesBuffer[i]) 296 { 297 return i; 298 } 299 } 300 } 301}

試したこと

12行目のprivate List<Vector3> _verticesにVecter3の点群を入れてみたのですが何も生成されませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

CreateMeshメソッドだけアクセシビリティがpublicになっていますが、おそらく「メッシュを作りたいときは別のスクリプトからCreateMeshを実行してくれ」という意図なんだろうと思います。
そこで、DrawMeshスクリプト自体には手を加えず適当なオブジェクトにアタッチして、その上でたとえば下記のようなスクリプトも作って...

C#

1using System.Linq; 2using UnityEngine; 3 4public class PointsToMesh : MonoBehaviour 5{ 6 [SerializeField] private DrawMesh drawMesh; 7 [SerializeField] private Material material; 8 [SerializeField] private Transform[] points; 9 10 private void Update() 11 { 12 if (Input.GetKeyDown(KeyCode.Space)) 13 { 14 var mesh = this.drawMesh.CreateMesh(this.points.Select(t => t.position).ToList()); 15 mesh.GetComponent<Renderer>().sharedMaterial = this.material; 16 } 17 } 18}

こちらのスクリプトも適当なオブジェクトにアタッチし、下図のようにシーンをセットアップした上で実行、そしてスペースキーを押すとメッシュが作成されました。

図

投稿2022/09/09 16:49

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

osugutto

2022/09/12 04:48

ありがとうございます!解決しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問