ぼくの息抜き

ぼくの息抜き

気ままな二人が記事を書くことで息抜きしていくブログ

CSS MenuMaker

【VR,OculusGo,Unity】素人がメッシュカットについて実際に触って理解する Part7

f:id:bokunoikinuki:20180908232241p:plain

どんどんPartが増えていく。でも着実に進んでる感があって、とても良い。

前回の続き。

なぜ減算しているのか。normalizedとは何か。

についてやっていこう。

planeとmeshの交点を求める関数を理解するPart2

参考

  1. 【Unity】メッシュカッターについて その3 - ぐーるらいふ

  2. 【Unity】メッシュカッターについて その2 - ぐーるらいふ

  3. 【Unity】ベクトルを正規化する - ぱふの自由帳

  4. 【Unity】Rayの使い方まとめ - 藍と淡々

  5. RayCastその1、使い方【Unity】 - (:3[kanのメモ帳]

実践

normalizedとは?

Vector3.normalized - Unity スクリプトリファレンス

正規化されたときベクトルは同じ方向は維持したままで長さが 1.0 のものが作成されます。

Vector3のnormalizedしないとどうなるのか。

うーん。とりあえず、参考記事3によるとベクトルの向きを変えずに長さを1にしているっぽい。

よくわからないから、とりあえずコンソールでそれぞれの数値を出してみるとこんな感じ。

        // 少ない所から多い片方の頂点に向かってrayを飛ばす。
        var a = (tmpPos1 - basePos).normalized;
        var b = tmpPos1 - basePos;
        Ray ray1 = new Ray(basePos, (tmpPos1 - basePos).normalized);
        print ("basePos" + basePos);
        print ("tmpPos1" + tmpPos1);
        print ("b" + b);
        print ("a" + a);

f:id:bokunoikinuki:20180930130004p:plain

bが正規化されていないVector3で、aが正規化されたもの。確かに方向は変わっていない。

directionやっとわかった!

Ray.direction - Unity スクリプトリファレンス

normalizedに関してはなくてもおかしくなかった。

Direction is always a normalized vector. If you assign a vector of non unit length, it will be normalized.

法線が出てない場合でも勝手にnormalizedされるって書いてある?

英語わからん。

そしてnormalizedを弄っていたらやっとdirectionがわかった。そもそもVector3は座標ではなく、ベクトルの向きを表してる。Vectro3を基本3D空間の座標として扱っているからイメージがぐちゃぐちゃになっていた。

基点が(5.0, 0, 0)座標でdirectionが(-1.0, 1.0, 0)の場合青い矢印の方向に45度で飛んでいく。

f:id:bokunoikinuki:20180930130242p:plain

directionが(-1.0, 0.5, 0)の場合はこうなった!

f:id:bokunoikinuki:20180930130501p:plain

完全理解した。Vector3ややこしい。これで

Ray ray1 = new Ray(basePos, (tmpPos1 - basePos).normalized);

減算していた意味がわかった。ひゃー、しかし数学全然できないな。

RayCastについて調べる

次はこちら。

        // planeと交差する距離を求める
        plane.Raycast(ray1, out distance);

RayCastだ。

参考記事5がRayCastについて詳しく丁寧に説明されているので、見ていく。

大きく分けて2パターン、1つ目はRayの発射位置と方向を指定するパターン 

//startPointが発射位置、directionが発射方向。両方ともVector3
Physics.Raycast (startPoint, direction, out hit, Mathf.Infinity);


2つ目は上記の例でもあった直接Rayを使ったパターン

Physics.Raycast(ray, out hit, Mathf.Infinity);


こちらは発射位置と方向がrayに設定されています。

めっちゃわかりやすい!ありがとうございます。

3つ目の引数は何も指定しないと無限になるらしい。だから今回2つしか引数がない。

ちょっと待てよ?

ちょっと待てよ、RayCastしているのにPhysicsがPlaneなんだ?

と思ってplane.raycastで調べてみるとあった。Physics.RayCastと違う!

Unity - Scripting API: Plane.Raycast

public bool Raycast(Ray ray, out float enter);

1つ目の引数のRayとぶつかった場所までの距離をfloatに代入してくれるっぽい。

参考記事:参照渡し - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

修飾子outは戻り値的な感じで使えるらしい。戻り値と違うのは戻り値は1つの関数につき1つだが、outはいくつも使える点だ。

距離がわかったらGetPoint

次はこれ。

        // ray1がその距離を進んだ位置を取得(ここが交点になる)
        _pos1 = ray1.GetPoint(distance);

Ray.GetPoint - Unity スクリプトリファレンス

調べてみると引数の距離の分進んだ場所のVector3を返してくれる関数だ。わかりやすい。

これで一つ目のRayとPlaneの交点座標がわかったわけだ。

そして同じことをもう一回繰り返すとこうなる。

f:id:bokunoikinuki:20180930142114p:plain

PrefabのSphereを表示させる関数は理解できたからスキップ。

次はCut関数をみていく。