Alternativa3D 8.8.0で追加されたWireFrameクラス。
このクラスは大きく分けて2つの機能がある。
単純に3D空間上に線を引く機能と、ワイヤーフレームマテリアルのようなものを実現する機能だ。
まず、WireFrameクラスのコンストラクタは基本的に使わない。呼び出せるけどgeometryを作ってくれないらしい
じゃあどうするのかっていうとstaticメソッドを使う。
createLinesList(points:Vector, color:uint = 0, alpha:Number = 1, thickness:Number = 1):WireFrame [static]
createLineStrip(points:Vector, color:uint = 0, alpha:Number = 1, thickness:Number = 1):WireFrame [static]
この2つはほとんどいっしょでVector.<Vector3D>から線を引く。線のプロパティ(色、アルファ、線の太さ)は残りの引数。
createLinesList()は2つのVector3Dをセットにしてその2点を結んだ線を作る。
与えたVector.<Vector3D>が奇数だった場合は最後の要素は無視されちゃう。
2Dで言うと
for (var i:int = 0; i < point.length; i++){
if (i % 2 == 0){
graphics.moveTo(point[i].x, point[i].y);
} else {
graphics.lineTo(point[i].x, point[i].y);
}
}
createLineStrip()はVector3Dで与えられた線を順番に結んでいく。
2Dで言うと
graphics.moveTo(point[0].x, point[0].y);
for (var i:int = 1; i < point.length; i++){
graphics.lineTo(point[i].x, point[i].y);
}
あとWireFrameインスタンス1つにつき設定できる線の種類は1つだけ。
色を変えたいときなどはもう1つWireFrame作りましょう。
package { import alternativa.engine3d.objects.WireFrame; import flash.geom.Vector3D; /** * ... * @author */ public class Main extends AlBasicView { public function Main(){ stage.frameRate = 60; var cameraController:RoundCameraController = new RoundCameraController(camera, stage); // var vec:Vector.<Vector3D> = new Vector.<Vector3D>(); vec.push(new Vector3D(0, 0, 0)); vec.push(new Vector3D(100, 100, 100)); vec.push(new Vector3D(100, 200, -100)); vec.push(new Vector3D(400, -100, 500)); var line:WireFrame = WireFrame.createLineStrip(vec, 0x00ff00); scene.addChild(line); // request(); } } }
早速前回のクラスを使ってます。
static functionの返り値が作成されたWireFrameオブジェクトなのでこれをsddChild()したり座標を動かしたりできる。
ところでこのWireFrameオブジェクトのgeometryはWireGeometryというクラスらしい。
おそらくResourceのサブクラスなんだろうけどドキュメントに載ってない。addLine()という素敵なメソッドもあるみたいなんだけどまずgeometryプロパティにアクセスできない。flashdevelopeではpublicって出てるんだけど、privateなんだろうか。
一応
var geo:WireGeometry = line.getResources(true, WireGeometry)[0] as WireGeometry;
でWireGeometryはもってこれたけど結局addLine()もprivateなのかアクセスできなかった。
完全に内部で線を引くためだけのメソッドなのかもしれん。
これで3D空間内の線は引けるね!
createEdges(mesh:Mesh, color:uint = 0, alpha:Number = 1, thickness:Number = 1):WireFrame [static]
こっちはMeshからワイヤーフレームを作成する。
WireFrameMaterialねーのかようって思ってたけど、これがかわりになるのかな。
プリミティブを突っ込むのが簡単な使い方。
いくつか注意があって、まず対象となるMeshは3DシーンにaddChild()されてなくてもかまわない。
MeshのGeometryから読み込むだけだろうし。
加えて対象MeshのGeometryリソースはupload()されている必要もない。
完全にCPUのMeshからデータを取ってきてるみたい。
重要なのがこのワイヤーフレームも1つのObject3Dってこと。マテリアルじゃない。
たとえばモデルとなったMeshを動かしてもWireFrameは動かないし逆も然り。
WireFrameもObject3DなのでモデルのMeshにaddChild()しておけばモデルに合わせて動かせるけどね。
すでにマテリアルとしてテクスチャを貼り付けたMeshにそのWireFrameをaddChild()すればPV3DのCompositeMaterialのようなものになる。
でもたぶん頂点の数は倍だよね...。
ワイヤーフレームはこんなかんじ(要 Flash Player 11)
package { import alternativa.engine3d.materials.FillMaterial; import alternativa.engine3d.objects.WireFrame; import alternativa.engine3d.primitives.GeoSphere; import flash.events.Event; /** * ... * @author */ public class Main extends AlBasicView { private const RAD:Number = Math.PI / 180; private var theta:Number = 0; private var wire:WireFrame; private var sphere:GeoSphere; public function Main(){ stage.frameRate = 60; var cameraController:RoundCameraController = new RoundCameraController(camera, stage); // sphere = new GeoSphere(200); sphere.setMaterialToAllSurfaces(new FillMaterial(0x00ff00)); scene.addChild(sphere); wire = WireFrame.createEdges(sphere, 0xff0000); scene.addChild(wire); // request(); } override public function onRender(e:Event):void { super.onRender(e); round(); } private function round():void { wire.x = 1000 * Math.cos(theta); wire.y = 1000 * Math.sin(theta); theta += 2 * RAD; } } }
ワイヤーフレームにモデルとなったGeoSphereが追従してないのが分かる。
念願のワイヤーフレームは作れるようになったけど、マテリアルじゃないからちょと使いにくいかもしれないなぁ。
頂点制御したときのワイヤーフレームへの更新をやろうとしてるんだけどうまくいかない...。
どうやるんだろ。
Author:9ballsyn
ActionScriptについて
最近はMolehill