Papervision3DのCubeにはまった

最近、Papervision3Dを触り始めたのですが、Cubeで少しはまったのでメモ。

Cubeクラスを使用すると、簡単に3Dの立方体を作成する事が出来ますが、その立方体の上面と下面を非表示にして筒状にしようと試みたところではまった。。
まず、普通に立方体を作成するとこんな感じになる。

ソース抜粋

var materialList:MaterialsList = new MaterialsList();
materialList.addMaterial(new ColorMaterial(0xDF2975), "front");
materialList.addMaterial(new ColorMaterial(0xFF5B4F), "back");
materialList.addMaterial(new ColorMaterial(0x624FFF), "right");
materialList.addMaterial(new ColorMaterial(0x4FF2FF), "left");
materialList.addMaterial(new ColorMaterial(0x4FFF88), "top");
materialList.addMaterial(new ColorMaterial(0xDCFF4F), "bottom");

this.cube = new Cube(materialList, 30, 30, 30);


この立方体を筒状にするため、上面と下面を消す。
ColorMaterialが継承しているMaterialObject3Dのプロパティinvisibleをtrueに設定する事で可能になります。
残りの4面を裏表の両方が見えるように設定してあげればいいはず。

が、、ここで一つ面倒な事が。。
ColorMaterialのコンストラクタでinitObjectという引数を指定出来ます。(Papervision3Dリビジョン443にて)
なので、このinitObjectに対してinvisibleプロパティを設定してあげれば良さそうだ。
という事で下記のようにしてみた。

ソース抜粋

var materialList:MaterialsList = new MaterialsList();
materialList.addMaterial(new ColorMaterial(0xDF2975, 1, {doubleSided : true}), "front");
materialList.addMaterial(new ColorMaterial(0xFF5B4F, 1, {doubleSided : true}), "back");
materialList.addMaterial(new ColorMaterial(0x624FFF, 1, {doubleSided : true}), "right");
materialList.addMaterial(new ColorMaterial(0x4FF2FF, 1, {doubleSided : true}), "left");
materialList.addMaterial(new ColorMaterial(0x4FFF88, 1, {invisible : true}), "top");
materialList.addMaterial(new ColorMaterial(0xDCFF4F, 1, {invisible : true}), "bottom");

this.cube = new Cube(materialList, 30, 30, 30);


↓結果


何も変わってない・・
ColorMaterialクラスを見てみると、、なんと引数にinitObjectを設定する事が出来るのに見てない・・
完全に放置プレイ。。

soundkitchen氏とも話したが完全にバグだという結論にいたった。
後で、New Issueするかな。

そうすると、ColorMaterialのインスタンス計6個をせっせと生成してあげて、プロパティdoubleSidedとinvisibleを設定してあげないといけないのかー。。
面倒だなー。。

そんな会話の中でsoundkitchen氏から助言を頂いた。
「doubleSidedとinvisibleの設定はCubeクラスのコンストラクタで指定できるよ。」と。

おぉー・・そういえば、、そんなの見かけたなwww

試してみた。

ソース抜粋

var materialList:MaterialsList = new MaterialsList();
materialList.addMaterial(new ColorMaterial(0xDF2975), "front");
materialList.addMaterial(new ColorMaterial(0xFF5B4F), "back");
materialList.addMaterial(new ColorMaterial(0x624FFF), "right");
materialList.addMaterial(new ColorMaterial(0x4FF2FF), "left");
materialList.addMaterial(new ColorMaterial(0x4FFF88), "top");
materialList.addMaterial(new ColorMaterial(0xDCFF4F), "bottom");

var insideFaces:int = Cube.ALL - (Cube.TOP + Cube.BOTTOM);
var excludeFaces:int = Cube.TOP + Cube.BOTTOM;
this.cube = new Cube(materialList, 30, 30, 30, 1, 1, 1, insideFaces, excludeFaces);


↓結果


おかしい。。
excludeFacesは効いているが、insideFacesが効いていないような感じだ。。


・・・


結局、思いつく範囲で試してみたものは全滅。。

仕方がないので、素直にColorMaterialのインスタンスを生成するようにした。

素直にColorMaterialインスタンスを生成

// front両面表示
var front:ColorMaterial = new ColorMaterial(0xDF2975);
front.doubleSided = true;

// back両面表示
var back:ColorMaterial = new ColorMaterial(0xFF5B4F);
back.doubleSided = true;

// right両面表示
var right:ColorMaterial = new ColorMaterial(0x624FFF);
right.doubleSided = true;

// left両面表示
var left:ColorMaterial = new ColorMaterial(0x4FF2FF);
left.doubleSided = true;

// top非表示
var top:ColorMaterial = new ColorMaterial(0x4FFF88);
top.invisible = true;

// bottom非表示
var bottom:ColorMaterial = new ColorMaterial(0xDCFF4F);
bottom.invisible = true;

var materialList:MaterialsList = new MaterialsList();
materialList.addMaterial(front, "front");
materialList.addMaterial(back, "back");
materialList.addMaterial(right, "right");
materialList.addMaterial(left, "left");
materialList.addMaterial(top, "top");
materialList.addMaterial(bottom, "bottom");

this.cube = new Cube(materialList, 30, 30, 30, 1, 1, 1);


↓結果


とりあえず、こうする事でイメージ通りのものが作れた。
でもよく見ると、筒を横に倒した状態で横方向にぐるぐる回転させるとおかしくなる。

doubleSidedをtrueにした面同士が極端に近づいた時に起きてしまうようだ。
これはセグメント数を上げると気にならない程度に抑える事が出来る。

セグメント数を上げる

// front両面表示
var front:ColorMaterial = new ColorMaterial(0xDF2975);
front.doubleSided = true;

// back両面表示
var back:ColorMaterial = new ColorMaterial(0xFF5B4F);
back.doubleSided = true;

// right両面表示
var right:ColorMaterial = new ColorMaterial(0x624FFF);
right.doubleSided = true;

// left両面表示
var left:ColorMaterial = new ColorMaterial(0x4FF2FF);
left.doubleSided = true;

// top非表示
var top:ColorMaterial = new ColorMaterial(0x4FFF88);
top.invisible = true;

// bottom非表示
var bottom:ColorMaterial = new ColorMaterial(0xDCFF4F);
bottom.invisible = true;

var materialList:MaterialsList = new MaterialsList();
materialList.addMaterial(front, "front");
materialList.addMaterial(back, "back");
materialList.addMaterial(right, "right");
materialList.addMaterial(left, "left");
materialList.addMaterial(top, "top");
materialList.addMaterial(bottom, "bottom");

// セグメント数を1→8へ修正
this.cube = new Cube(materialList, 30, 30, 30, 8, 8, 8);


↓結果


やっと完成。。
Cube一個作るのにかなり時間かかった。。


CubeクラスのinsideFacesとexcludeFacesについては調査中ですが、何か気付いた方はツッコミお願いします。