GH Tutorial Grasshopper Kangaroo2 Physics

【Grasshopper Tutorial】 Falling Ball

今回は、kangaroo2を使用して、上画像の様にものにぶつかりながら落下する球体を生成していきます。kangaroo2で実装できる基本的なものとなっております。是非ご参考ください。こちらのチュートリアルは動画化しておりますので、動画の方がよい方は以下のリンクからどうぞ。

概要

上画像がプログラムの全体像となっております。各ブロックごとに説明していこうと思います。

基準サーフェイスの生成

  • CenterBoxコンポーネントで直方体を生成します。各辺の長さは6×100×100としています。
  • Deconstruct Brepコンポーネントでサーフェイスに分割し、List Itemコンポーネント一番面積の大きい面を取得します。

基準サーフェイスを変形

  • 生成したサーフェイスを面外方向に変形させていき、凹凸をつけていきます。Divide Surfaceコンポーネントでサーフェイスを分割していきます。u,v方向45分割しています。出力端子のpoint とnormalはFlattenしておきます。
  • 先ほど取得した分割点を法線方向に移動させていきます。Moveコンポーネントにポイントをつなぎ、Divide SurfaceコンポーネントのNormalベクトルをAmplitudeコンポーネントで大きさを変えていきます。
  • List Lengthコンポーネントで分割点の数を取得し、Randomコンポーネントで分割点数分のランダムな値を取得します。今回は-7~7までのランダム値をしゅとくしていきます。これをAmplitudeコンポーネントに接続すると、各分割点が法線方向にランダムに移動します。
  • 長方形の端部の変形を0にしたいので、その処理を実装していきます。Curveコンポーネントでサーフェイスのエッジをポリラインで取得し、Point in Curveコンポーネントでエッジ上にある点のインデックス番号を取得します。
  • Point in Curveコンポーネントはカーブ上にある点は1を出力するので、MemberIndexコンポーネントで値が1のインデックス番号を取得します。
  • 先ほど生成したRandomコンポーネントから出力されるランダムな値のリストから、Replace ItemsコンポーネントMemberIndexコンポーネントで取得したインデックス番号の値を0に置き換えます。
  • これをAmplitudeコンポーネントにつなぎなおせば、端部の変形を0にできます。
  • Surface from Pointsコンポーネントで移動させた点から再度サーフェイスを生成します。入力端子UはExpressionで「x+1」と入力し、Divide Surfaceコンポーネントで分割した際の45を接続します。上画像の様にサーフェイスが変形していればOKです。

変形させたサーフェイスを切断し切断面を取得

  • 先ほど生成した変形させたサーフェイスを切断していきます。まずは切断に用いるサーフェイスですが、基準サーフェイスをx方向に1移動させたサーフェイスを使用します。
  • Brep | Brepコンポーネントで変形させたサーフェイスを切断に用いるサーフェイスの交線を取得します。
  • Boundary Surfacesコンポーネントで取得した交線をサーフェイス化します。これで切断面を取得できました。

切断面の押し出し

  • 取得した切断面を押し出していきます。ExtrudeコンポーネントでX方向に押し出します。押し出す距離は、一番最初にCenter Boxコンポーネントで直方体のX方向の長さ6で押し出しています。
  • 後々のために押し出したオブジェクトを-X方向に1だけ移動させておきます。上画像の様になっていればOKです。

外側のBoxと球体がぶつかる部分を生成

  • 次に、球体を流し込むための外側のBoxを生成します。List ItemコンポーネントDeconstruct Brepコンポーネントで、最初に直方体を分割して取得したサーフェイスから下面を取得します。
  • ExtrudeコンポーネントでZ方向に1押し出します。これでBoxの下面は完成です。
  • 次に、下面以外の4方向を生成します。下面のサーフェイスにCurveコンポーネントを接続し、サーフェイスエッジをポリラインとして取得します。
  • Offset Curveコンポーネントで-1オフセットすることで、先ほど取得したエッジを内部側に1オフセットしたエッジを取得しまます。
  • Boundaryサーフェイスの入力端子をFlattenして、2つのエッジをつなぐことで、ロの字型のサーフェイスが生成されます。
  • ExtrudeコンポーネントでZ方向に押し出します。今回は105押し出しています。上画像の様に、上面に穴が開いたBoxが生成できていればOKです。

Boxの外側部分を生成

  • 前項で生成したBoxは球体とのあたり判定に使うものなので、実際には見えてきません。見えてくる部分のBoxを生成します。
  • Brep Edgeコンポーネントで先ほBoxのエッジを取得し、List Itemコンポーネントで0,1,3番目のエッジ(下面の長方形の帳面以外の3辺)を取得します。
  • Join Curvesコンポーネントで3辺を結合し、ポリライン化します。
  • Offset Curveコンポーネントでポリラインを外側に1オフセットします。
  • Loftコンポーネントでオフセット前と後のポリラインを間にサーフェイスを張ります。
  • ExtrudeコンポーネントでZ方向に押し出します。105押し出しています。

見え係部分の色付け

  • わかりやすいように、見え係部分を色付けします。外側のBox、下面の直方体、以前生成したいびつな形状のジオメトリを、Custom PreviewコンポーネントColour Swatchコンポーネントで白にしときます。

落下させる球体の中心点を生成

  • 落下させる球体の中心点を生成します。List Itemコンポーネントで一番最初に生成した直方体の上面を取得します。
  • Brep Edgeコンポーネントで直方体のエッジを取得し、List Lengthコンポーネントで長さが短い順にリストを並べ替えます。
  • List Itemコンポーネントで0番目と1番目を取得することで、短い2辺が取得でき、Curve Middleコンポーネントでそれぞれの中点を取得し、Lineコンポーネントで中点同士を結ぶ直線を生成します。
  • DivideCurveコンポーネントで生成した直線を15分割し、16の分割点を取得します。
  • Cull Indexコンポーネントで0番目と-1番目の分割点を消去し14点とします。
  • Liner Arrayコンポーネントで14点をZ方向に2間隔で複製します。今回は50複製しているので、700点生成しました。
  • Moveコンポーネントで700点を全体的にZ方向に移動させておきます。+Z方向に5だけ移動させました

kangaroo2ゴールオブジェクトの設定(球体同士の衝突判定)

  • それではkangaroo2の設定をしていきます。まずは球体同士の値判定を設定していきます。Sphere Collideコンポーネントで先ほど取得した700点を接続し、入力端子Rには1、Strengthには十分大きな値を接続するため、適当に10000を入力しておきます。
  • これで入力した700点を中心とした、仮想の半径1の球体が生成され、生成された球体同士がぶつかるようになります。

kangaroo2ゴールオブジェクトの設定(Boxと球体の衝突判定)

  • 以前生成した、衝突判定に使用するロの字型のサーフェイスを押し出したジオメトリ、Box下面のジオメトリ、内部のいびつな形状のジオメトリをMergeコンポーネントでまとめ、それらと先ほど生成した700点とのあたり判定を設定していきます。
  • SolidPointCollideコンポーネントで入力端子SolidにMergeでまとめておいたジオメトリを接続し、Pointsコンポーネントには以前生成した700点を接続します。Strengthには十分大きな値を接続しておきます。
  • これで、生成したジオメトリと700点がぶつかるようになります。

kangaroo2ゴールオブジェクトの設定(球体を落下させる)

  • 生成した700点に対して、-Z方向に力を与えていきます。Loadコンポーネントに700点を接続し、-0.01のZ方向のベクトルを接続します。
  • これで700点は落下するようになります。

Solverの設定

  • Entwineコンポーネントで設定したGoalオブジェクトをまとめます。
  • Solverの設定を行っていきます。今回は演算結果の過程をアニメーションで見ていきたいので、Bouncy Solverコンポーネントを使用します。
  • BouncySolverで演算を開始すると、上画像の様に700点がぶつかりながら落下していくかと思います。

球体の生成

  • 一度演算を止め、ぶつかりながら落下した点を中心とした球体を生成します。Bouncy Solverコンポーネントの出力端子Vから移動した点を取得できるので、MeshSphereコンポーネントでその点を中心に球体メッシュを生成します。UV方向の分割数は10とし、半径はSphereCollideで使用したときの1とします。今回hMeshSphereで球体を生成しているのは、Brepにすると非常に処理が重くなるためです。
  • SolidPointCollideコンポーネントで設定したあたり判定はあくまで点とジオメトリのあたり判定になります。つまり、実際ぶつかっているのは中心点とジオメトリがぶつかっているので、そのぶつかった点を中心とすると、球体がZ方向に半径1ぶんめり込んでしまいます。なので生成したMesh球をMoveコンポーネントでZ方向に1移動させます。X方向Y方向に関しては、白いジオメトリの内部に、ロの字形サーフェイスを押し出したジオメトリを生成し、そのジオメトリと点のあたり判定を設定したかと思います。なので外側の白いジオメトリの内部に、透明な厚さ1の壁が4方に張られていて、それと点のあたり判定を実施することで、壁にめり込まないようにしています。

球体の色付け

  • 最後にMeshSphereに色付けしていきます。MeshColorコンポーネントに接続しGraftしておきます。
  • 今回はランダムに色を生成したいので、Randomコンポーネントで0~255までのランダム値を整数で取得し、球体の数だけランダムな色を生成しています。
  • GraftしてMeshColorコンポーネントに接続すれば完成です。

完成

以上になります。kangaroo2の記事は他にもいくつか書いてますので、ご興味あれば是非ご参考ください。

-GH Tutorial, Grasshopper, Kangaroo2, Physics
-, , ,