- 2007-07-28 16:03
- papervision3d
Papervision3Dに元々準備されている3Dオブジェクトを試してみます。
今まではPlaneという紙のようなオブジェクトだけでしたが、ここではより3Dらしくなります。
Sphereのコンストラクタはこうなっています。
public function Sphere( material:MaterialObject3D = null, // マテリアル radius:Number = 100, // 球の半径 segmentsW:int = 8, // 水平方向の分割数 segmentsH:int = 6, // 垂直方向の分割数 initObject:Object = null // その他のプロパティ )
今回は以下の様なSphereを作ります。
var size : int = 200; var segment : int = 24; obj = new Sphere( material, size, segment, segment );
結果は以下の通りです。
他のオブジェクトに関してもこのソースコードを使い回します。
基本的に「オブジェクト生成」の部分が変わるだけです。
package { import flash.display.*; import flash.events.*; import org.papervision3d.core.proto.*; import org.papervision3d.scenes.*; import org.papervision3d.objects.*; import org.papervision3d.cameras.*; import org.papervision3d.materials.*; [SWF(backgroundColor="0xffffff", width="400", height="400", frameRate="45")] public class MySphere extends Sprite { private var container : Sprite; private var scene : Scene3D; private var camera : Camera3D; private var rootNode : DisplayObject3D; private var obj : DisplayObject3D ; //オブジェクト private var size : int = 200;//オブジェクトの長さ private var segment : int = 24; //面の分割数 private var material : MaterialObject3D; //---------------------------------------------Constructor public function MySphere():void { //ステージ this.stage.quality = "MEDIUM"; this.stage.scaleMode = "noScale"; this.stage.align = StageAlign.TOP_LEFT; this.stage.addEventListener(Event.ENTER_FRAME, loop); this.stage.addEventListener(Event.RESIZE, onStageResize); //コンテナ生成 container = new Sprite(); container.x = this.stage.stageWidth / 2; container.y = this.stage.stageHeight / 2; addChild( container ); //シーン生成 scene = new Scene3D( container ); //rootNode生成 rootNode = new DisplayObject3D( "rootNode" ); scene.addChild( rootNode ); //マテリアル設定 material = new WireframeMaterial(0xcccccc); //オブジェクト生成 obj = new Sphere( material, size, segment, segment ); rootNode.addChild( obj ); //camera設定 camera = new Camera3D(); camera.z = -size; camera.focus = 50; camera.zoom = 1; } //---------------------------------------------loop private function loop( event:Event ):void { // 回転 obj.rotationY += container.mouseY / 100; obj.rotationX += container.mouseX / 100; //再レンダリング scene.renderCamera( camera ); } //---------------------------------------------stage private function onStageResize(e:Event):void{ container.x = this.stage.stageWidth / 2; container.y = this.stage.stageHeight / 2; } } }
Cylinderのコンストラクタはこうなっています。
public function Cylinder( material:MaterialObject3D = null, // マテリアル radius:Number = 100, // 底面の半径 height:Number = 100, // 高さ segmentsW:int = 8, // 円の分割数 segmentsH:int = 6, // 高さの分割数 topRadius:Number = 0, // 上面の半径 initObject:Object = null // その他のプロパティ )
上面の半径がデフォルト値で0となっているのは、0であると底面と同じ値になるようになっているからです。
具体的にはCylinder.asの135行目には
if (topRadius==0) topRadius = radius;
となっています。
少し横道にそれました。
以下の様なCylinderを作ります。上面の半径は未指定にして、底面の半径と同じにします。
obj = new Cylinder( material, size, size, segment, segment);
material、size、segmentの値はSphereと変わりません。
結果はこうなります。
Cubeのコンストラクタはこうなっています。
public function Cube( material:MaterialObject3D = null, // マテリアル width:Number = 500, // 幅 depth:Number = 500, // 奥行き height:Number = 500, // 高さ __segmentsS:Number = 1, // 幅方向の分割数 __segmentsT:Number = 1, // 奥行き方向の分割数 __segmentsH:Number = 1, // 高さ方向の分割数 initObject:Object = null // その他のプロパティ )
以下の様なCubeを作ります。
obj = new Cube( material, size, size, size, segment, segment, segment );
幅、奥行き、高さが全て同じ値なので立方体ですね。
結果はこうなります。
Coneのコンストラクタはこうなります。
public function Cone( material:MaterialObject3D = null, // マテリアル radius:Number = 100, // 底面の半径 height:Number = 100, // 高さ segmentsW:int = 8, // 底円の分割数 segmentsH:int = 6, // 高さの分割数 initObject:Object = null // その他のプロパティ )
ところで、Papervision3D 1.5のConeは上面の半径が0のCylinderとして実装されています。
具体的なソースコード(Cone.as)はこうなっています。
public class Cone extends Cylinder { public function Cone( material:MaterialObject3D=null, radius:Number=100, height:Number=100, segmentsW:int=8, segmentsH:int=6, initObject:Object=null ) { super( material, radius, height, segmentsW, segmentsH, 0, initObject ); } }
本当にシンプルにCylinderのコンストラクタを呼び出しています。
感の良い方ならお気づきでしょう。
これはバグですね。
何故かというと、Cylinderの実装を思い出してください。確かCylinderの上面の半径が0のとき、底面の半径が反映される設定でした。ということは、Coneは常に円柱になってしまいます。
仕方ないので、ここではCylinder.asを少し修正します。
上面の半径が未指定のときに底面の半径が適用されるのは便利なので、ここでの修正は以下のようにしました。
Cylinder.asの135行目付近とコンストラクタの仮引数のデフォルト値を変更しています。
public function Cylinder( material:MaterialObject3D=null, radius:Number=100, height:Number=100, segmentsW:int=8, segmentsH:int=6, topRadius:Number=-1, initObject:Object=null ) { // (中略) //135行目付近 if (topRadius < 0) topRadius = radius; //(中略) }
コンストラクタの仮引数topRadiusのデフォルト値を-1にして、135行目付近の条件分を変更しています。
この条件文をコメントアウトすれば良さそうに思うのですが、そうすると、CylinderでtopRadiusを指定していないオブジェクトは全てtopRadiusが0になってしまい、Coneになってしまいます。CylinderでtopRadiusを指定しない多くのユーザは円柱になることを期待していると思うので、こういう修正にしました。
なを、修正前のCylinder.asはこうなっています。ご参考までに。
public function Cylinder( material:MaterialObject3D=null, radius:Number=100, height:Number=100, segmentsW:int=8, segmentsH:int=6, topRadius:Number=0, initObject:Object=null ) { // (中略) //135行目付近 if (topRadius == 0) topRadius = radius; //(中略) }
かなり、話がそれました。
では、ようやくConeの結果です。
以上、「Sphere」「Cylinder」「Cube」「Cone」の4つのプリミティブオブジェクトを試してみました。
基本的にSphereで紹介したソースコードの51行目のオブジェクト生成の部分をそれぞれのコンストラクタに置き換えるだけで、3Dオブジェクトが簡単に楽しめます。
Comments:2
- Marcus 08-04-13 (日) 1:23
-
Hi! Nice job, i like to know how i could make a Cylinder with his top and his botton empty? With no segments or texture…
thanks a lot, cya
- adamrocker 08-04-13 (日) 10:32
-
Thank you for your comment, Marcus.
It’s “NOT” possible to make the cylinder with top and bottom empty by default primitive.
You can make it to edit the “Cylinder.as” file.
Easy to do!
You delete this block.if (j==0||j==(iVerNum-1)) { for (i=0;i<(iHorNum-2);i++) { ... } }
Like this.
/* DELETE THIS BLOCK if (j==0||j==(iVerNum-1)) { for (i=0;i<(iHorNum-2);i++) { ... } } */This block make the top and bottom polygons.
Plese try this.Thanx.
Trackbacks:0
- Trackback URL for this entry
- http://www.adamrocker.com/blog/134/papervision3d_sphere_cylinder_cube_cone.html/trackback/
- Listed below are links to weblogs that reference
- Papervision3Dのプリミティブ・オブジェクト - Cone, Cube, Cylinder, Sphere - from throw Life
