ラベル Papervision3D の投稿を表示しています。 すべての投稿を表示
ラベル Papervision3D の投稿を表示しています。 すべての投稿を表示

2010年4月16日金曜日

[Pv3D] Meteor Attack(@wonderfl)の解説

一時的にだけど、[Pv3D] Meteor AttackがWonderflでデイリーのPVで一位になったのを記念に解説をこちらのほうでやってみます。


と言ってもこれはそんなに難しいことをしているわけではないんですよね。
やっていることをまとめると、
「球(スフィア)の配置」「カメラ、ライト移動のためのイベント」「画像のロード」「シェーダー、マテリアルの設定」「球(スフィア)のクリックイベント」「アニメーション」「バンプマップの更新」
ぐらいです。

全部説明するのは面倒疲れるので、「球(スフィア)のクリックイベント」「バンプマップの更新」だけ解説します。
該当部はここらへん。
//private function onMapComplete(e:Event):void {
private function onMapComplete():void {
 //var bmpData:BitmapData = new BitmapData(e.target.loader.width, e.target.loader.height);
 var loader1:Loader = imageArray.pop();
 var bmpData:BitmapData = new BitmapData(loader1.width, loader1.height);
 bmpData.draw(loader1);
 moonBmpData = bmpData;
 var loader2:Loader = imageArray.pop();
 bmpData = new BitmapData(loader2.width, loader2.height);
 bmpData.draw(loader2);
 bumpBmpData = bmpData;
 scene.addChild(light);
 
 shader = new PhongShader(light, 0xFFFFFF, 0x666666, 0, bumpBmpData);
 var material:ShadedMaterial = new ShadedMaterial(new BitmapMaterial(moonBmpData), shader);
 material.interactive = true;
 material.smooth = true;
 var sphere:Sphere = new Sphere(material, 100, 15, 15);
 sphere.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onObjectClick);
 scene.addChild(sphere);
 
 var particles:ParticleField = new ParticleField(new ParticleMaterial(0xffffff, 1, 1), 200, 2, 500, 500, 500);
 scene.addChild(particles);
}

private function onObjectClick(e:InteractiveScene3DEvent):void {
 var ball:Sphere = new Sphere(new ColorMaterial(0xEEEEEE), 10);
 scene.addChild(ball);
 var tween:ITween = BetweenAS3.tween(ball, {x: e.renderHitData.x * 0.9, y: e.renderHitData.y * 0.9, z: e.renderHitData.z * 0.9}, {x: e.renderHitData.x * 3.5, y: e.renderHitData.y * 3.5, z: e.renderHitData.z * 3.5});
 tween.play();
 tween.onComplete = function():void {
  var sp:Sprite = new Sprite();
  sp.graphics.beginFill(0xFFFFFF);
  sp.graphics.drawCircle(25, 25, 20);
  sp.graphics.endFill();
  sp.graphics.beginFill(0x000000);
  sp.graphics.drawCircle(25, 25, 17);
  sp.graphics.endFill();
  var bmpData:BitmapData = new BitmapData(50, 50, true, 0x00000000);
  bmpData.draw(sp);
  bumpBmpData.draw(bmpData, new Matrix(1, 0, 0, 1, e.x * 1000 - 25, e.y * 500 - 25));
  shader.bumpmap = bumpBmpData;
  scene.removeChild(ball);
 }
}
上のほうはシェーダーの設定です。
sphere.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onObjectClick);
でSphereのクリックイベントを設定しています。

で、イベントハンドラで、
(InteractiveScene3DEvent).x及び、(InteractiveScene3DEvent).yは、SphereのマテリアルのUV情報、
(InteractiveScene3DEvent).renderHitData.x(.y, .z)は、クリックしたXYZ座標の値を取ってくることができます。
UVについてはこちらが自分はわかりやすいと思いました。英語だけど。
要するに、UVの値からテクスチャにおける座標を取得したいと思ったら、UVそれぞれにテクスチャの幅と高さを掛けてやれば良いわけです。
(InteractiveScene3DEvent).x * (image).widthという感じで。

上記のプログラムの32行目~は、外側が白で、内側が黒の円を描いて、円の中心がクリックした点になるように移動し、shader.bumpmap = bumpBmpData;でバンプマップを更新しているわけです。

バンプマップを更新したところで、地味で目立たないですね。
というかこれ、以前の記事のプログラムの流用です。

・・・解説下手だなー。

2009年10月24日土曜日

[Pv3D]UVマッピングの問題


UVマッピングを使用したテクスチャに、Shaderを適用すると出てくる例の黒い線を消すべくいろいろやってみた。

日本語のページを探してもこの問題の解決策を見つけられなかったので、英語で調べてみるとこんなものを見つけました。
まさに自分と同じ現象、しかも解決策書いてある!というわけで早速試してみました。

解決方法が書いてあるのはこの一文。
a fix is to change the shadercomposition mode to per_tri on the shader. This will be slower but remove the seams.
意訳すると、「シェーダーのshadercomposition modeをper_triにすれば、重くなるけど線消えるよ。」って感じでしょうか?

shadercomposition modeってのは、ShadedMaterialのプロパティにshaderCompositeModeというのがあるので多分これのことでしょう。
shaderCompositeModeのデフォルトの値は0。
また、ShaderCompositeModesに次のような記述があります。
public static var PER_LAYER:int = 0;
public static var PER_TRIANGLE_IN_BITMAP:int = 1;
per_triというのは、おそらくこのPER_TRIANGLE_IN_BITMAPのこと。
というわけで、
var material:ShadedMaterial = new ShadedMaterial(bitmapmaterial, shader, 1);
という風に記述しました。3つ目の引数がshaderCompositeModeです。

こちらが作ったswfファイルです。重いので反応遅れます。
ソースコードは右クリックで見られます。
他の目的で作ったものをブログ用に適当に改変してるので非効率的な書き方になってます。

上のファイルを見てもらえればわかりますが、この方法を試しても駄目でした。
例の線は消えてはいるようですが、それとはまた別のものが表示されるようになってしまいました。
原因はよくわかりません。

自分は解決しませんでしたが、これで解決する場合もあるかもしれません。

2009年10月12日月曜日

[Pv3D]Phong shadingとBump mapping[AS3.0]


久しぶりの更新です。
自転車で東京へ行くっていう馬鹿なことしてたので時間がありませんでした。

さて本題。
Papervision3DのPhongShaderを使ってバンプマッピングをしてみました。
バンプマッピングってのは白黒の画像で表面の凹凸を表現する方法のことらしいです。
こんな感じ。結構CPUに負荷かかるので気をつけてください。

クリックした場所のバンプマップを書き換えてます。
某アニメの最終話みたいに月に落書きします。
note.x | [PV3D2.0] BumpMapの動的書き換え
上の記事を参考に書きました。
月の画像はこちらのを使わせてもらいました。

あまりいい書き方ではないと思いますが、以下ソースコードです。
変数名とか関数名とかかなり適当。
package {
 import flash.display.Bitmap;
 import flash.events.Event;
 import flash.geom.Point;
 import flash.geom.Rectangle;

 import org.papervision3d.core.utils.InteractiveSceneManager;
 import org.papervision3d.core.utils.Mouse3D;
 import org.papervision3d.core.utils.virtualmouse.VirtualMouse;
 import org.papervision3d.lights.PointLight3D;
 import org.papervision3d.materials.BitmapMaterial;
 import org.papervision3d.materials.shaders.PhongShader;
 import org.papervision3d.materials.shaders.ShadedMaterial;
 import org.papervision3d.objects.primitives.Plane;
 import org.papervision3d.objects.primitives.Sphere;
 import org.papervision3d.view.BasicView;

 [SWF(backgroundColor="#ffffff")]
 public class sample_bump extends BasicView {
  // ヴァーチャルマウス
  private var vMouse:VirtualMouse;
  // 球(月)
  private var sphere:Sphere;
  // 月のバンプマップ埋め込み
  [Embed(source="moonbump1k.jpg")] private var bumpImage:Class;
  private var bumpMap:Bitmap = new bumpImage() as Bitmap;
  // シェーダー
  private var shader:PhongShader;

  /* constructor */
  public function sample_bump() {
   super(640, 480, true, true,"Target");

   // カメラ設定
   camera.x = 0;
   camera.y = 0;
   camera.z = 400;
   camera.focus = 1000;
   camera.zoom = 1;

   vMouse = viewport.interactiveSceneManager.virtualMouse;
   Mouse3D.enabled = true;

   /* 背景画像は画像を貼り付けたPlane(平面)を球(月)の奥に設置している */
   // 背景画像埋め込み
   [Embed(source="000191_m.jpg")] var wallpaper:Class;
   var wp:Bitmap = new wallpaper() as Bitmap;
   var star:BitmapMaterial = new BitmapMaterial(wp.bitmapData);
   star.doubleSided = true;
   star.smooth = true;
   var wall:Plane = new Plane(star, 1024, 681);
   wall.z = -200;
   scene.addChild(wall);

   // 月の画像埋め込み
   [Embed(source="moonmap1k.jpg")] var texture:Class;
   var tex:Bitmap = new texture() as Bitmap;
   // ライト設定
   var light:PointLight3D = new PointLight3D();
   light.x = 0;
   light.y = 200;
   light.z = 500;
   scene.addChild(light);

   var bmpMat:BitmapMaterial = new BitmapMaterial(tex.bitmapData);
   shader = new PhongShader(light, 0xFFFFFF, 0x666666, 50, bumpMap.bitmapData, tex.bitmapData);
   var material:ShadedMaterial = new ShadedMaterial(bmpMat, shader);
   material.smooth = true;
   material.interactive = true;

   sphere = new Sphere(material, 100, 16, 12);
   scene.addChild(sphere);

   startRendering();
  }

  // バンプマップ埋め込み
  [Embed(source="bump.png")] private var craterImage:Class;
  private var crater:Bitmap = new craterImage() as Bitmap;
  private function meteor():void {
   // バンプマップ合成
   bumpMap.bitmapData.merge(crater.bitmapData, new Rectangle(0, 0, crater.width, crater.height), new Point(vMouse.x*1000 - crater.width/2, vMouse.y*500 - crater.height/2), 128, 128, 128, 128);

   // バンプマップ更新
   shader.bumpmap = bumpMap.bitmapData;
  }

  override protected function onRenderTick(event:Event=null):void {
   // 回転
   sphere.yaw(0.25);
   if(InteractiveSceneManager.MOUSE_IS_DOWN) {
    meteor();
   }

   super.onRenderTick(event);
  }
 }
}

2009年9月3日木曜日

[Pv3D]Collada(.dae)にShader試してみた[AS3.0]

Papervision3DでShader試してみました。
Shaderってのは、3Dで光、それによって発生する影を表現するもの、と思っておけばいいです。自分も詳しくは知りません。
やはり影がないと3Dって感じがしないですよね。ベタ塗りだと奥行きとかわからないですし。

このようになりました。
ソースは右クリックで見てください。

おー、一気に3Dっぽくなったー。
PhongShaderだと重いので、今回はGouraudShaderを使用しました。マシンによっては重いかも。

まぁ見ればわかりますが、問題があります。
表面に黒い線のツギハギができてしまっています。

原因はテクスチャマッピング関係だと思います。

このサンプルのモデル、テクスチャ画像は下のようになっています。

つまりこの一枚の画像を、テクスチャマッピング(割り当て)をして、モデルに対応させて表示しています。

おそらく、この問題の原因は、テクスチャの継ぎ目のところに影を生成してしまってるからだと思います。

この問題を解決して綺麗に表示したいのですが方法がわかりません。
さてこれはどうしたものか・・・

--------------------------------------
追記
解決しませんでしたが、こちらで黒い線の問題を取り上げました。

さらに追記
別のライブラリを使って問題を解決してみました。
こちら。

2009年8月14日金曜日

ちょっと遊び

Parpervision3Dの2.1が公開されてますね。
DAEまわりが改善されてるようで嬉しいです。
変えてみたら以前はエラーが出てたものが動くようになったりしました。

というわけでちょっと更新。
内容自体は前のとほとんど変わりません。

初音ミクのモデルデータに落書きをできるようにしてみた。→■
かなーり適当です。左右対称に描かれてしまうところが多いです。
ちなみに、このプログラムはPv3Dが2.0だとエラーが出て動きません。2.1だと動いたので公開してみました。

モデルのデータはこちらからいただきました。謝々。

2009年7月16日木曜日

[Pv3D][Flex]Collada(.dae)にお絵かき[AS3.0]

これまた前回の続きです。

こんな感じです。
現時点で不具合は多いですが、基本の動作としてはこんな感じかな~と・・・
右下の「編集する」を選択すると編集モードに入ります。

[PV3D2.0] virtualMouse axis on DAE
Flash Player 10でPV3D上の落書きを保存してみる
↑2つを参考にし、matsu4512さんに助けてもらいながら作りました。

ソースコード
demo.mxml World3D.as

現時点でお絵かきが上手くいってない原因はここらへんが原因かなー。
material = new MovieMaterial(movieClip, false, true, false, new Rectangle(0, 0, bmpData.width, bmpData.height));


---
お絵かきをするにはクリックしたマテリアルの情報を得る必要があるのですが次のように行ってます。

private function modelComplete(e:FileLoadEvent):void {
var dae_rootNode:DisplayObject3D = dae.getChildByName("COLLADA_Scene");
var targetMesh:DisplayObject3D = dae_rootNode.getChildByName("Model").getChildByName("mesh1");
targetMesh.addEventListener(InteractiveScene3DEvent.OBJECT_MOVE, drawModel);
}

private function drawModel(e:InteractiveScene3DEvent):void {
if(isModelOver) {
targetMaterial = int(e.renderHitData.material.name);
}
}

mesh1っていうDisplayObject3Dからマテリアルの名前をどうやって取得するかわからなかったので、Flex Builderの補完機能をつかってそれっぽいのを片っ端から試してたら、
『e.renderHitData.material.name』で取得することができることが判明。
この"renderHitData"って調べてもあまり情報がないんですよね~。
まあ問題なく(?)動いてるので大丈夫かな。

ちなみに、「getChildByName("Model").getChildByName("mesh1")」の"Model"と"mesh1"は

<library_visual_scenes>
<visual_scene id="SketchUpScene" name="SketchUpScene">
<node id="Model" name="Model">
<node id="mesh1" name="mesh1">
<instance_geometry url="#mesh1-geometry">
<bind_material>
<technique_common>
<instance_material symbol="material0" target="#material0ID">
<bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
<instance_material symbol="material1" target="#material1ID">
<bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
中略
<instance_material symbol="material6" target="#material6ID">
<bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
</technique_common>
</bind_material>
</instance_geometry>
</node>
<node id="mesh2" name="mesh2">
<instance_geometry url="#mesh2-geometry">
<bind_material>
<technique_common>
<instance_material symbol="ForegroundColor" target="#ForegroundColorID"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
中略
</visual_scene>
</library_visual_scenes>

daeファイルのこの部分の『node』の名前からきてます。
mesh1のほかにもmesh2とかがありますが、マテリアルが含まれてるのはmesh1のほうなのでそっちです。
書き出したソフトによって多少違いがあるとは思いますが他も同じようなもののはず。

2009年7月3日金曜日

[Pv3D][Flex]Collada(.dae)のマテリアル張り替え

前回の続き?

前回3DギャラリーからとってきたCollada形式のデータはテクスチャの枚数が多かったので今回は自分でGoogle SketchUpを使ってモデルを作ってみました。形はかなり適当ですが・・・

動作サンプル
ソースコードは右クリックで表示できます。

背景が白いところでドラッグ&ドロップで視点移動、マウスホイールでズームイン&アウトします。
ズームは正確にはズームではなく、カメラごと対象に近づく(or遠ざける)ようになってます。
「ロード」ボタンを押してから、「はりかえ」ボタンを押すとテクスチャがランダムに変わります。
エラーが出ると思うので、「ロード」を押す前に「はりかえ」を押さないでください。

DAEに渡すマテリアルリストの作成は次のようにやってます。

var material0:BitmapMaterial = new BitmapFileMaterial("model3/images/texture0.jpg");
var material1:BitmapMaterial = new BitmapFileMaterial("model3/images/texture1.jpg");
var material2:BitmapMaterial = new BitmapFileMaterial("model3/images/texture2.jpg");
var material3:BitmapMaterial = new BitmapFileMaterial("model3/images/texture3.jpg");
var material4:BitmapMaterial = new BitmapFileMaterial("model3/images/texture4.jpg");
var material5:BitmapMaterial = new BitmapFileMaterial("model3/images/texture5.jpg");
var material6:BitmapMaterial = new BitmapFileMaterial("model3/images/texture6.jpg");
var material7:BitmapMaterial = new BitmapFileMaterial("model3/images/texture7.jpg");
var material8:BitmapMaterial = new BitmapFileMaterial("model3/images/texture8.jpg");
var material9:BitmapMaterial = new BitmapFileMaterial("model3/images/texture9.jpg");
var myMaterials:Object = {
material0: material0,
material1: material1,
material2: material2,
material3: material3,
material4: material4,
material5: material5,
material6: material6,
material7: material7,
material8: material8,
material9: material9
}
texture = new MaterialsList(myMaterials);

myMaterialsの中身の『material0: material0』ですが、
これは、『Colladaファイルのマテリアルの名前: 上で宣言しているBitmapMaterial型の変数material0』です。名前同じでわかりづらいですね、すみません。
で、「Colladaファイルのマテリアルの名前」はCollada(DAE)ファイルを調べればわかります。
ColladaってのはXMLで書かれているので、適当なテキストエディタで開くと、次のようになっています。

<library_images>
<image id="material0-image" name="material0-image">
<init_from>../images/texture0.jpg</init_from>
</image>
<image id="material1-image" name="material1-image">
<init_from>../images/texture1.jpg</init_from>
</image>
中略
<image id="material8-image" name="material8-image">
<init_from>../images/texture8.jpg</init_from>
</image>
<image id="material9-image" name="material9-image">
<init_from>../images/texture9.jpg</init_from>
</image>
</library_images>
<library_materials>
<material id="material0ID" name="material0">
<instance_effect url="#material0-effect"/>
</material>
<material id="FrontColorNoCullingID" name="FrontColorNoCulling">
<instance_effect url="#FrontColorNoCulling-effect"/>
</material>
<material id="material1ID" name="material1">
<instance_effect url="#material1-effect"/>
</material>
<material id="material2ID" name="material2">
<instance_effect url="#material2-effect"/>
</material>
中略
<material id="material8ID" name="material8">
<instance_effect url="#material8-effect"/>
</material>
<material id="material9ID" name="material9">
<instance_effect url="#material9-effect"/>
</material>
<material id="ForegroundColorID" name="ForegroundColor">
<instance_effect url="#ForegroundColor-effect"/>
</material>
</library_materials>

書き出したソフトによって記述に多少の違いはありますが、『<material id="material0ID" name="material0">』のnameがマテリアルの名前になります。

あとは、

dae.load("○○.dae", 作成したマテリアルリスト);

と書けばロードされます。
普通はCollada自体でもテクスチャを指定してありますが、これで渡したマテリアルリストのほうが優先されるっぽいです。

マテリアルの張り替えには「replaceMaterialByName」を使ってます。こんな感じで。

var material:BitmapMaterial = new BitmapFileMaterial("model3/images/texture" + Math.round(Math.random()*9) + ".jpg");
dae.replaceMaterialByName(material, "material0");



今回参考にさせてもらったサイト
http://pv3d.org/2008/12/26/switching-a-moviematerial-on-the-face-of-a-cube-replacematerialbyname/
http://d.hatena.ne.jp/matsu4512/20090701

2009年6月18日木曜日

[Pv3D]Papervision3Dをやってみた その3[AS3.0]


今回はCollada形式(DAE)のファイルをPv3Dで読み込んでみました。

完成品とソースコード

まずGoogleの3Dギャラリーから適当なファイルをダウンロード。
利用規約は読んだけど多分問題はないはず。

拡張子daeのファイルがあるので、それをソースフォルダに持っていき、あとは、
var dae:DAE = new DAE();
dae.load("model.dae");
scene.addChild(dae);

と書けば表示されます。
だたし、こちらで解説されているように"org/papervision3d/core/proto/MaterialObject3D.as"の"tiled"の値を"true"にしないと正しく表示されません。

これだけだったらあまり苦労はしません。
Flex Builder上で実行するのにはエラーはでません。しかし、生成したswfファイルを実行すると、「ローカルファイルシステムの SWF および信頼されているローカル SWF ファイルのみがローカルリソースにアクセスできます。」といったエラーが発生します。
これを解決するには、モデルとテクスチャのファイルの埋め込みが必要になります。
今回一番苦労したのがこれです。


テクスチャファイルの埋め込みと、そのマテリアルリストの作成はこんな感じです。
[Embed(source='model/images/texture0.jpg')]
private var texture0:Class;    // 画像埋め込み
var material0:Bitmap = new texture0() as Bitmap;
var myMaterials:Object = {
material_2_1_8_image: new BitmapMaterial(material0.bitmapData)
}

上の「material_2_1_8_image」の部分は、daeファイルをテキストエディタで開き、画像ファイル名を検索すると、このようになっています。
<image id="material_0_23_8_image" name="material_0_23_8_image">
<init_from>../images/texture0.png</init_from>
</image>

この"id"と"name"の値です。
自分が使用したdaeファイルは、この値が「material_0_23_8-image」というようになっていましたが、"-"を含むとASでエラーになるので、"_"に置換しています。


モデルデータの埋め込みとロードはこんな感じです。
[Embed(source="model/model.dae", mimeType="application/octet-stream")]
var daeFile:Class;
var daeObject:DAE = new DAE();
daeObject.load(XML(new daeFile()), new MaterialsList(myMaterials));


テクスチャの画像が多いと埋め込みが非常に面倒です。
鮭さんのほうで紹介されていたこちらを使わせてもらいました。便利便利。
今回の完成品ですが、一部のテクスチャの表示がうまくいってません。見逃してください。


今回の参考サイトはこちらです。
http://sakeprog.cocolog-nifty.com/sake/2008/08/papervision3d38_7285.html
http://blog.r3c7.net/?p=113
http://d.hatena.ne.jp/sakusan_net/20080702/1215003280


----------------------------------------
2009/10/18 追記
一部訂正しました。→こちら

2009年5月26日火曜日

[Pv3D]Papervision3Dやってみた その1[AS3.0]

今回は球を表示させるだけの簡単なプログラム。
カメラを動かさないとなんだがなんだが3Dな感じがしませんね。

実行結果
ソースコードはすごい短いです。

package {
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;

[SWF(backgroundColor="#ffffff")]
public class lets3d extends BasicView {
public function lets3d() {
var ball:Sphere = new Sphere(null, 500, 50, 50);
scene.addChild(ball);
startRendering();
}
}
}

今回はこちらを参考にさせてもらいました。
ソースコードが短いのは6行目の"extends BasicView"をしてるおかげみたいです。Pv3Dの便利機能の1つと考えていいんでしょうか。

BasicViewを使わない方もいらっしゃいます。鮭さんとかそうですね。
勉強がてら自分も"extends BasicView"をしないで挑戦してみました。

というわけで、まず動作を理解するためにBasicView.asの中身を見てみます。

package org.papervision3d.view
{
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.cameras.DebugCamera3D;
import org.papervision3d.core.view.IView;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
/* @author Ralph Hauwert
* 中略 */
public class BasicView extends AbstractView implements IView
{
/* 中略 */
public function BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
{
super();

scene = new Scene3D();
viewport = new Viewport3D(viewportWidth, viewportHeight, scaleToStage, interactive);
addChild(viewport);
renderer = new BasicRenderEngine();

switch(cameraType)
{
case CameraType.DEBUG:
_camera = new DebugCamera3D(viewport);
break;
case CameraType.TARGET:
_camera = new Camera3D(60);
_camera.target = DisplayObject3D.ZERO;
break;
case CameraType.SPRING:
_camera = new SpringCamera3D();
_camera.target = DisplayObject3D.ZERO;
break;
case CameraType.FREE:
default:
_camera = new Camera3D(60);
break;
}

cameraAsCamera3D.update(viewport.sizeRectangle);
}

/**
* Exposes the camera as a Camera3D
*/
public function get cameraAsCamera3D():Camera3D
{
return _camera as Camera3D;
}
/* 略 */
}
}

これも"extends AbstractView"となっているので、AbstractView.asの中身も覗いてみます。

package org.papervision3d.view
{
import flash.display.Sprite;
import flash.events.Event;

import org.papervision3d.core.proto.CameraObject3D;
import org.papervision3d.core.view.IView;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;

/**
* @Author Ralph Hauwert
*/
public class AbstractView extends Sprite implements IView
{
protected var _camera:CameraObject3D;
protected var _height:Number;
protected var _width:Number;

public var scene:Scene3D;
public var viewport:Viewport3D;
public var renderer:BasicRenderEngine;

public function AbstractView()
{
super();
}

public function startRendering():void
{
addEventListener(Event.ENTER_FRAME, onRenderTick);
viewport.containerSprite.cacheAsBitmap = false;
}

/* 中略 */
protected function onRenderTick(event:Event = null):void
{
renderer.renderScene(scene, _camera, viewport);
}

/* 略 */
}
}

今回使わなかった部分は略しました。
ところでこれって勝手に載せていいんですかね?問題はないと思うけど。

上2つを参考に最初のプログラムを書きなおします。

package {
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;

[SWF(backgroundColor="#ffffff")]
public class lets3d2 extends Sprite {
public var scene:Scene3D;
public var camera:Camera3D;
public var viewport:Viewport3D;
public var renderer:BasicRenderEngine;

public function lets3d2() {
scene = new Scene3D();
camera = new Camera3D(60);
viewport = new Viewport3D(0, 0, true, true);
renderer = new BasicRenderEngine();
addChild(viewport);

camera.target = DisplayObject3D.ZERO;
camera.update(viewport.sizeRectangle);

var ball:Sphere = new Sphere(null, 500, 50, 50);
scene.addChild(ball);

addEventListener(Event.ENTER_FRAME, renderTick);
viewport.containerSprite.cacheAsBitmap = false;
}

protected function renderTick(event:Event = null):void {
renderer.renderScene(scene, camera, viewport);
}
}
}

最初のに比べるとソースコードは長くなりました。
実行結果はこちら

見事同じものができました。

結論:
BasicViewがつかえるのなら、使ったほうがいいんでね?

2009年5月25日月曜日

[Pv3D]Papervision3Dをやろうかな

Papervision3Dって名前長いですね。
というわけでこれからは「Pv3D」とでも略そうかと思ふ。

とりあえずGoogle Codeからswcファイルをダウンロードして、Flex Builderで開発環境そろえました。

ちなみに、Papervision3D 2.0(Great White)です。
なんか2.0は結構違うらしいので、どうせ覚えるのなら新しいほうがいいかな、と。

http://rainyday.jp/blog/flash/pv3d/75.html
http://sakeprog.cocolog-nifty.com/sake/2008/05/papervision3d_c48d.html
http://labs.anthill.jp/2008/04/as30greatwhitepapervision3d_20.html
とりあえず↑を読んで勉強します。