note.x

[Away3D] Away3D 2.4 Feature – Explode

ワーカーホリック野郎な日々を送ってる間にAway3Dがバージョンアップ。
Away3d: 2.4 & 3.4 released!

とりあえず地味な機能から試してみる。

ExplodeTest(要:FlashPlayer9)

Explodeクラスは、指定したObject3Dインスタンス内の全Faceを位置関係をそのままに、バラバラのMeshやFaceに分解してくれるジオメトリモディファイア。
Away3DはもともとFace単位でvisibleプロパティを持ってるので、表示/非表示をFace単位で行うことができていたけど、Face単位で大きさ変えたりすることはできなかった。その名のとおり、簡易的な爆発表現なんかに使えそうだし、演出面で結構使えるかもしれない。

具体的には以下のようにして使う。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import away3d.geom.Explode;
 
- 中略 -
 
//適当なメッシュを用意
var wcMat:WireColorMaterial = new WireColorMaterial(0x0099CC, {wirecolor:0x00CCFF});
var sphere:Sphere = new Sphere({material:wcMat, radius:100, segmentsW:8, segmentsH:6});
 
//Explodeでメッシュを分解
var _explode:Explode = new Explode(true, true);
var _explodedObj:ObjectContainer3D = _explode.apply(sphere) as ObjectContainer3D;
 
//分解されたメッシュが束ねられたObjectContainer3Dをシーンに追加
scene.addChild(_explodedObj);

Explodeのコンストラクタに渡す引数は以下のようになってる模様。

  • 第1引数:分解したFaceを個別のMeshとして定義するかどうか
    trueなら、Faceの数分Meshが生成される。falseなら、共有していた頂点をFaceの数だけ用意してそれぞれ単独の面として扱えるようにする。

  • 第2引数:再定義後のMeshの中心点をFaceの重心にもってくるかどうか
    falseなら、元になったObject3Dの原点が中心点のままになる

コンストラクタの第1引数をtrueにして、個別のMeshを生成した場合は、

for each(var item:Mesh in _explodedObj.children)
{
    item.scaleX = 0.5;
}

などとして、それぞれのMeshを制御する。

理屈では、Colladaメッシュにも適用できる。

dae Explode(要:FlashPlayer9)

ただ、現状のExplode.asには、元にしたメッシュがFace単位でマテリアル指定されているような場合、マテリアルが引き継がれないという問題があって、テクスチャが無効になってしまう。そこで、Explode.asを以下のように書き換えることで暫定的に対処した。ついでに「bothsides、backの要素が引き継がれない」という問題にも対処。

Explode.as 61行目

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
for(i=0;i<loop;++i){
 
    face = obj.faces[i];
    mesh = new Mesh();
 
    va = new Vertex(face.v0.x, face.v0.y, face.v0.z);
    vb = new Vertex(face.v1.x, face.v1.y, face.v1.z);
    vc = new Vertex(face.v2.x, face.v2.y, face.v2.z);
    uva = new UV(face.uv0.u, face.uv0.v);
    uvb = new UV(face.uv1.u, face.uv1.v);
    uvc = new UV(face.uv2.u, face.uv2.v);
 
    mesh.addFace(new Face(va, vb, vc, obj.material as ITriangleMaterial, uva, uvb, uvc));
    _container.addChild(mesh);
}

これを、

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
for(i=0;i<loop;++i){
 
    face = obj.faces[i];
    mesh = new Mesh();
 
    va = new Vertex(face.v0.x, face.v0.y, face.v0.z);
    vb = new Vertex(face.v1.x, face.v1.y, face.v1.z);
    vc = new Vertex(face.v2.x, face.v2.y, face.v2.z);
    uva = new UV(face.uv0.u, face.uv0.v);
    uvb = new UV(face.uv1.u, face.uv1.v);
    uvc = new UV(face.uv2.u, face.uv2.v);
 
    var setMaterial:ITriangleMaterial;
    if (obj.material) setMaterial = obj.material as ITriangleMaterial;
    else setMaterial = face.material as ITriangleMaterial;
 
    var fc:Face = new Face(va, vb, vc, setMaterial, uva, uvb, uvc);
    mesh.addFace(fc);
    _container.addChild(mesh);
    mesh.bothsides = obj.bothsides;
    fc.back = obj.back as ITriangleMaterial;
}

とする。

あとは、バラバラになった後のMeshが、もともとのFaceの法線方向をforwardベクトルにしてくれるといいのになぁと思ったけど面倒くさそうだったのでとりあえず保留。
また、Explodeコンストラクタの第1引数をtrueにして、FaceごとのMeshを生成すると当然負荷が増大するので、パフォーマンス重視の場合はMeshを生成せずに、Faceレベルでコントロールする方法を確立しないとダメっぽい。


Trackback URL : http://blog.r3c7.net/as3-software-rendering/420/trackback/

Leave a Reply