★OSCを使ったGrasshopperとProcessingの連携
今回のテーマはProcessing3との連携です。Grasshopperで作成したパターンをCG的な表現で見せる場合、一旦Bakeして他の
CGソフトに渡す必要がありますが、もっとお手軽に、インタラクティブに操作ができる
方法としてProcessingと通信させる方法があります。
その際に使うのがgHowlというプラグインです。
★ウサギをGrasshopperのスライダーで動かすサンプル
試しにサンプルを作ってみました。スライダーでウサギの向きを変化させると、Processing上でウサギが追従して回転します。Step.1 objデータの準備
・画面に表示するデータを用意します。
・データは何でも良いですが、今回はstanford bunnyと呼ばれている、CG環境のマテリアル情報の検証等で使われるデータを用意しました。
※Googleで検索するとダウンロードサイトにたどり着きます。
Step.2 ノードの作成
・上図のようなノードを組みます。
・ダウンロードしたobjデータを適当なフォルダに格納し、Rhinocerosにインポートした後、上図のMesh inputにアサインするとGrasshopperは動作します。
Step.3 Prosessingのスクリプトを組む
・スクリプトを下記のように作成します。
・各種、必要なライブラリを追加でインポートします。(やり方はGoogle検索で)
・objデータは今回作成したsketchフォルダ直下にbunny.objという名前で置きます。
以下、ソースです↓
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import saito.objloader.*; | |
import processing.opengl.*; | |
import hypermedia.net.*; | |
import peasy.*; | |
PeasyCam cam; | |
UDP udp; | |
DRAW d;//DRAWクラスのインスタンスを宣言 | |
PShape obj; | |
PImage img; | |
float angle = 0.0; | |
void setup() { | |
size(1280, 960, P3D); | |
noStroke();//線無し | |
smooth();//アンチエイリアス | |
/*通信の設定*/ | |
udp = new UDP( this, 4000 );//4000番ポートで待ち状態 Grasshopper側もこれに合わせる | |
udp.listen( true ); | |
d = new DRAW();//DRAWクラスのインスタンスを作成 | |
/*カメラの設定*/ | |
cam = new PeasyCam(this, 100);// カメラワーク操作オブジェクト。親オブジェクトと距離?を指定 | |
cam.setMinimumDistance(10);// カメラの最小距離定義 | |
cam.setMaximumDistance(10000);// カメラの最大距離定義 | |
cam.setDistance(0); | |
frameRate(60);//フレームレートの設定 | |
/*objファイルのインポート*/ | |
obj = loadShape("bunny.obj"); | |
/*原点を中心に、上向きに回転*/ | |
obj.rotateX(radians(90)); | |
/*objファイルの色設定*/ | |
obj.setFill(color(200,200,200,255));//オブジェクトの色 R,G,B,α | |
obj.setSpecular(color(150)); | |
obj.setShininess(20); | |
//obj1 = createShape(SPHERE, 200); | |
//obj1.setStroke(true); | |
//obj1.setStrokeWeight(6.0f); | |
} | |
void receive( byte[] data){ // <-- extended handler | |
//int time = millis(); | |
String message = new String( data ); | |
d.prepareData(message);//受信データを整理するメソッド | |
} | |
void draw() { | |
background(0);//背景を黒にリセット | |
/*光源の設定*/ | |
ambientLight(20, 20, 20);//環境光(方向を持たないので陰影は付かない) R,G,B | |
lightSpecular(255, 255, 255);//光の鏡面反射色(ハイライト)を設定 directional lightの手前に書く | |
directionalLight(100, 100, 100, 0, 1, -1);//平行光(指向性がある)R,G,B,vx,vy,vz | |
lightFalloff(1,0,0); | |
translate(0,0,-1400);//初期の位置 | |
rotateY(frameCount * 0.005);//Y軸周りに回転 | |
/*objの描画*/ | |
pushMatrix();//初期の位置をセット | |
noStroke();//線表示無し | |
d.rotateMesh();//回転動作 | |
shape(obj);//objデータを表示 | |
popMatrix();//初期位置に戻す | |
} | |
public class DRAW{ | |
DRAW(){} //コンストラクタ | |
ArrayList<Vertex> v = new ArrayList<Vertex>(); | |
/*受信データを仕分けするメソッド*/ | |
public void prepareData(String udp_data){ | |
ArrayList<Vertex> v_tmp = new ArrayList<Vertex>();//受信1回につき仮に格納するアレイリストのオブジェクトを作成 | |
String lines[] = split(udp_data, '\n');//改行コードで分離して、lines配列にデータを格納 | |
String tmpLine = ""; | |
for(int i = 0; i < lines.length; i++){ | |
tmpLine = lines[i]; | |
String coords[] = tmpLine.split("x");//xで分離 | |
Vertex vert = new Vertex(float(coords[0]), float(coords[1]), float(coords[2]), float(coords[3])); | |
v_tmp.add(vert);//v_temp配列にxで区切った数値を格納 | |
} | |
if( v_tmp.size() == 0){v_tmp = null;} | |
v = v_tmp; | |
} | |
/*回転させるメソッド*/ | |
void rotateMesh(){ | |
//if( v == null) return; | |
for( Vertex vm : v ){ | |
rotate(radians(vm.angle),vm.vx,vm.vy,vm.vz); | |
} | |
} | |
} | |
/*アレイリストで座標値を格納するためのユーザー定義のクラス*/ | |
class Vertex{ | |
float vx,vy,vz,angle; | |
Vertex(float vx, float vy, float vz, float angle){ //コンストラクタ | |
this.vx = vx; | |
this.vy = vy; | |
this.vz = vz; | |
this.angle = angle; | |
} | |
} |
RhinocerosとProcessingでは座標系の向きが異なるので、合わせるのが結構面倒です・・・
0 件のコメント:
コメントを投稿