Alternativa3Dさわってみた。きほんのきほん。

flashでの3D表現。1年以上前にPapervision3Dを触った以来3Dから遠ざかっていたのだけれど少し機会があったので、
週末と休日にAlternativa3Dさわってみたのでめも。

Away3Dも一緒に落としてきてとりあえずサンプルからいろいろさわってみてたんだけども、
今の3Dすっげぇ!!ってなった。超今更だけど。
セミナーとかですごいのは見てたんだけど、やぱ実際に自分でコンパイルして、
動かしてみないと分からないもんですね。。

で、今回は Alternativa3Dの8.27.0。
Away3D 4.0さわってみた時も思ったんだけど、3Dライブラリ、バージョンアップする度にまったくそれまでの情報が
役に立たなくなってしまってかなり最初は困りますね。。使いこなせるようになれば問題なくバージョン移行にも
対応できるようになるんだろうけど、まだまだ苦労するんだろうな自分は。。

というわけで早速。

Alternativa3dダウンロード

swcを落としてくる。ここ
メアドとか入れたらダウンロードできる。この辺りは有料ライセンスだからとかですね。
(別にさわるくらいならお金いらない思う)
ちなみにAway3Dはfreeね!ただ現状の最新バージョンの情報がweb上に少なすぎだった。。

つくってみるもの

いつも通り、サウンドビジュアライザーいってみますかね。:-)

3Dはじめ

ていうか、まずそもそもなんだけど自分はカメラのセット時にz座標の+が手前に来るように
カメラ設定してるので、以下。(右手座標系っていうらしいですね)

// camera position
camera.rotationX = 180 * Math.PI / 180;
camera.x = 0;
camera.y = 0;
camera.z = 500;

この辺りはここで詳しい考え方を教えてもらいました。

Alternativa3Dのポリゴンの考え方を自分なりの理解でまとめると以下になった。
てか、思ってたポリゴンの分割方向と逆だった。(ちなみにこれをちゃんと理解したの割と最後の方…なのでまずは分からなくて全然おk)

座標から図形を描いてみる

まずはPlaneとかデフォルトのPrimitive?とかを使わずに頂点座標から
抽象的な3Dオブジェクトを自由に書いてみる練習。てかこれが出来たら音毎に入れていくだけだし!と思って。

そしていろいろ見てると、そもそもAlternativa3D 8.27の記事とかすげー少なくね。。?orz
でもでもそんな中、9ballsyndromeさん、なるとさんのblogが超勉強になりますた。:-)

Alternativa3D 8.8.0 Planeプリミティブ再考
Alternativa3D 8.8.0 で頂点制御(前編)
Alternativa3D 8.8.0 で頂点制御(後編)
初級編2.メッシュの構造を知る

ふむ。なんとなく Mesh + Geometry を使えば書けそうってことは分かった。
よし、自由自在に頂点操作できるようになるぞー。

で、上記のblogに合わせて、Alternativa3D_8.27.0のasdocを読んでいく。
Class Geometryでのサンプルとして以下が書いてあった。

  var attributes:Array = new Array();
  attributes[0] = VertexAttributes.POSITION;
  attributes[1] = VertexAttributes.POSITION;
  attributes[2] = VertexAttributes.POSITION;
  attributes[3] = VertexAttributes.TEXCOORDS[0];
  attributes[4] = VertexAttributes.TEXCOORDS[0];
  var geometry = new Geometry();
  geometry.addVertexStream(attributes);
  geometry.numVertices = 3;
  geometry.setAttributeValues(VertexAttributes.POSITION, new [x1,y1,z1,x2,y2,z2,x3,y3,z3]);
  geometry.setAttributeValues(VertexAttributes.TEXCOORDS[0], new [u1,v1,u2,v2,u3,v3]);
  geometry.indices = Vector.([0,1,2]);

最後の3行が分かれば頂点操作は出来そう。
alternativa.engine3d.core.内のClass VertexAttributesをまず読んでみる。
ん?てかこれ配列じゃね?Vector渡さないとだめよな?とか、いろいろ自分なりに読み解いて以下の結論。

geometry.numVertices = 3;
→ 頂点数 三角形1枚なので3。コンストラクタでの指定でもおk。new Geometry(3);とか。

geometry.setAttributeValues(VertexAttributes.POSITION, Vector.([]) );
→ x,y,z 頂点座標 3個で頂点1つを表す。

geometry.setAttributeValues(VertexAttributes.TEXCOORDS[0],Vector.([]) );
→ u,v 座標 2個で頂点1つを表す これの有用性が今のところまだ分からない。。

geometry.indices = Vector.([0, 1, 2]);
→ ポリゴンを描画する頂点の順番。時計回りに描かれる。

でわでわ両面の三角形を書いてみる。
(ちなみにfillMaterial,texMaterialはグローバル変数で持ってる)

// Mesh + Geometry = Plane(Triangle)
var mesh:Mesh = new Mesh();
var attributes:Array = new Array();
attributes[0] = VertexAttributes.POSITION;
attributes[1] = VertexAttributes.POSITION;
attributes[2] = VertexAttributes.POSITION;
attributes[3] = VertexAttributes.TEXCOORDS[0];
attributes[4] = VertexAttributes.TEXCOORDS[0];

// Geometry
var geometry:Geometry = new Geometry(6);	// 頂点数 3x2=6
geometry.addVertexStream(attributes);

// x,y,z
var pos:Vector. = geometry.getAttributeValues(VertexAttributes.POSITION);
for (var i:uint=0; i < geometry.numVertices/2; i++){
	pos[i*3 ]	 = 200*Math.random() - 100;		// 適当に3点作る
	pos[i*3 + 1] = 200*Math.random() - 100;
	pos[i*3 + 2] = 200*Math.random() - 100;
}
geometry.setAttributeValues(VertexAttributes.POSITION, pos );

// u,v
pos = Vector.([0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1]);
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[0], pos );

// indices
geometry.indices = Vector.([0, 1, 2, 2, 1, 0]);	// 両面なので頂点使い回し

// Material 貼付け
mesh.addSurface( fillMaterial, 0, 2 ); // 0
mesh.setMaterialToAllSurfaces(texMaterial);	// meshにaddSurfaceされてないとそもそもsetMaterialToAllSurfaces使えない

// meshのgeometryと紐付け、sceneに追加
mesh.geometry = geometry;
_objs[0] = scene.addChild(mesh);

かけた。:-)

Planeの頂点操作をやってみる

これでMeshの構造とかは分かったので用意されてるPlaneとかでも同じ事をやってみる。
当たり前だけど基本は全く同じ。PlaneもMeshからの派生だしね。
ということでsceneに配置したplane(_objs[0])を頂点操作するにはこんな感じで行けた。

var geo:Geometry = _objs[0].geometry;
var pos:Vector. = geo.getAttributeValues(VertexAttributes.POSITION);
var numVertex:uint = geo.numVertices;
var theta:Number = count * 10 * rad;
for (var i:int = 0; i < numVertex; i++){
	pos[uint(i * 3 + 2)] = 20 * Math.sin(theta + (i / 2 >> 0) * 4 * rad);
}
geo.setAttributeValues(VertexAttributes.POSITION, pos);
geo.upload(stage3D.context3D);

sceneに配置されてるMeshからx,y,zのgeometryを取ってきて
座標ごにょごにょしてからsetして、stage3Dにuploadするって流れか。かんたーん。:-)

※ ちなみにFillMaterialで作ったplaneに対して後からTextureMaterialとかを動的に変更させようとしても
Stage3Dにその情報がuploadされてないのでそんなリソースねーよみたいな感じで無視される。
こんな時も後から、BitmapTextureResource.upload(stage3D.context3D);
で、TextureMaterialのリソース(Bitmapdata)をuploadする。
ちなみに当たり前だけど始めからアップロードされてるものは使える。(コンストラクタとかで読み込んであったものなら使える)
一瞬ハマったのだけど下記に9ballsyndromeさんが書いてくれてた。:-)

ほいできた。つぎ。

WireFrame

これ!線が書きたかったの!!\(^o^)/

WireFrameはMeshじゃなくてObject3Dの派生らしい。ほう。だからprimitivesになかったのか。
ていうかなんでprimitivesじゃだめなんだ。new WireFrame(); みたいな使い方しない。
なんか使いづらいぞ。

var vec:Vector. = new Vector.;	// 頂点配列
var wf_L:WireFrame = WireFrame.createLinesList( vec, 0x00FFFF );		// 線を1本ずつ引いていく。奇数からのラインは無視されるみたい。(1→2,3→4 etc)
var wf_C:WireFrame = WireFrame.createLineStrip( vec, 0xFFFFFF );		// 線をひとまとめとして引いてくれる。
var wf_R:WireFrame = WireFrame.createEdges( plane, 0xFF00FF );		// Meshオブジェクトから線を引いてくれる。

でWireFrameの頂点操作はこんな感じでいけた。

if(line) scene.removeChild(line);
vec.push( new Vector3D( X, Y, Z) );
line = WireFrame.createEdges( vec, 0xeeeeee );
scene.addChild(line);
WireGeometry( line.getResources()[0] ).upload(context3D);

WireFrame.getResources()で返ってくるVector.配列の1つめにWireGeometryが入ってたので
それを改めてStage3Dにuploadしてやるといけた。

ちなみに頂点操作したMeshをWireFrame.createEdgesでlineだけ描画する場合は
Stage3DにuploadするのはWireFrameのGeometryだけで大丈夫。
なのでPlaneをsceneに追加もしなくていいし頂点操作後のgeometry.uploaも必要なし。

これはSphereをWireFrame.createEdgesしたやつ。

デカルト座標から極座標変換

で、3Dグラフィックでごにょごにょ遊ぶ時にどうしても座標変換が必要になったので、
座標変換のメモ。デカルト座標(x,y,z)と極座標(ρ,θ,φ)の変換は

x = r * sinθ * cosφ
y = r * sinθ * sinφ
z = r * cosθ

できたやつ(完全にアウトー

と、こんな感じのことをいろいろ覚えたので早速ビジュアライザーで遊んでみた。
どこかにこれ使ってもいいよっていう音とか映像、優しいPV持ってる人とかっていないのかな。。?
(ちらっと調べたら日本のPV以外はそもそも著作権とかないとか書いてあったんだけどほんと??)

( 2012.4.5 → って言ってたらPerfume Global Siteでモーションキャプチャデータ&楽曲データ配布が始まった!!それでつくったのはこっち。)

下のサムネをクリックで始まるよ。軽さとか考えずにとりあえずで作ったら超重い。。それでもGPU使えればFPS35くらいは出てるの確認。頂点の数を調整したら大分変わるね。:-) 始まるまで10秒くらいかかるかも。サビ位まで見てみて下さいw ayakotaniguchi.jp みたいに格好良くビジュアライズってのはまだまだ先ですねw

To view this page ensure that Adobe Flash Player version 11.0.0 or greater is installed.

全画面で見る時はこちら

とりあえずこの筆でしばらく遊んでみようかなぁ。楽しい。:-)

you