2009年11月11日星期三

Away3DLite 使用 Collada

Away3DLite 1.0 出一陣子了:
http://away3d.com/away3d-lite-v1-0-fastest-and-smallest-3d-engine-in-flash

號稱很小、很快,因為使用了 Flash Player 10 提供的 3D 語法,所以限制一定要使用 FP10 瀏覽才行。

以下,我作一個簡單的範例,載入一個 Collada 格式的 *.dae 模型檔案,這個 *.dae 可由各種 3D 建模軟體加上外掛輸出而成,或是像我偷懶去網路上找現成的借用一下。

Collada Test Model Bank: https://collada.org/owl/
我沒研究這個地方的版權說明,總之,借用者別用作營利用途就好~

範例原始碼:


package
{
import away3dlite.core.base.Object3D;
import away3dlite.loaders.Collada;
import away3dlite.materials.WireframeMaterial;
import away3dlite.templates.BasicTemplate;

import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;

[SWF(width=640, height=480)]
public class Away3DLite_TestCollada extends BasicTemplate
{
public function Away3DLite_TestCollada()
{
super();
}

private const ROTATION_DY_MAX:Number = 5;
private var rotation_dy:Number = 0;

private const ROTATION_DX_MAX:Number = 5;
private var rotation_dx:Number = 0;

private var _myCollada:Object3D

override protected function onInit():void{
camera.z = 0;
camera.zoom = 300;

view.mouseEnabled3D = false;

var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onColladaLoaded);
loader.load(new URLRequest("collada.dae"));
}

private function onColladaLoaded(e:Event):void{
addColladaObj((e.currentTarget as URLLoader).data);

stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
}

private function addColladaObj(data:*):void{
var collada:Collada = new Collada();
collada.material = new WireframeMaterial();
_myCollada = collada.parseGeometry(data);

scene.addChild(_myCollada);
}

private function onMouseMove(e:MouseEvent):void{
var dmx:Number = mouseX - width/2;
dmx = Math.min(Math.max(dmx, -width/2), width/2);
rotation_dy = ROTATION_DY_MAX * (dmx / (width/2));

var dmy:Number = mouseY - height/2;
dmy = Math.min(Math.max(dmy, -height/2), height/2);
rotation_dx = ROTATION_DX_MAX * (dmy / (height/2));
}

private function onMouseWheel(e:MouseEvent):void{
camera.z += (10 * e.delta);
camera.z = Math.min(camera.z, 0);
}

override protected function onPreRender():void{
if(_myCollada!=null){
_myCollada.rotationY += rotation_dy;
_myCollada.rotationX += rotation_dx;
}
}

}
}


載入 *.dae 後,可用滑鼠在畫面上移動,根據滑鼠 x, y 座標來使模型沿著 y 軸旋轉、x 軸旋轉,另外可用滑鼠滾輪控制 camera 的前進後退。

看效果:
http://sites.google.com/site/benrbchang/Away3DLite-Collada

6 意見:

當加菲貓愛上CK鼠 提到...

我想問一問 onenterframe 係可以點用
因為當我現在需要 用onterframe去不停重複一個 time frame, 但係但 time bar 只係有一個time frame 果時, onenterframe 就可以好正常咁用, 但當我+多一個time frame 係個onenterframe 前面, 佢一call onenterframe 就重複埋第一個time frame
例如: 有個start page, 按完start 入去game scenc, 但一call 個onenterfame
佢又去返個start page 但我只想 重複game scenc, 唔知可以點做呢?

Ben Chang 提到...

我不是很確定您的問題,如果使用中文不容易表達的話,您可以使用英文。

另一個我不是很確定的問題是:你的開發環境?是使用 Flash IDE 還是其他?在時間軸上總共設計了幾個 frame,每個 frame 上寫了哪些程式?

因為我腦袋中無法清楚的想像出你的原始檔模樣,所以無法回答您要如何處理。不過,你可以試試看,在 game scene 的那個 frame 記得加上 stop() 確保時間軸能停在該 frame,然後 onEnterFrame 應該就會在最後那一個 frame 中不斷執行才對。

匿名 提到...

您好:

我是著run你的程是碼,但是出現下列的錯誤:
1007: super 陳述式只能在類別實體建構函式內使用。
請問何解呢?

Ben Chang 提到...

可見得您不是直接使用我的 code,而是整合進你其他的 code 吧?!

不然你先把 super() 拿掉試試看,但是既然你是整合到你的程式中,那我也不能保證這樣的做法是否 OK~

匿名 提到...

謝謝邦大,關於super()的問題,我已經找到解法...您的程式碼對我幫助很大

另外,我想要貼圖在匯入的dae擋上,請問要如何做?不知邦大可否提點一些。

Ben Chang 提到...

要花點時間研究

可能會有兩種作法:

1.
*.dae 在產出時,也就是由 3D 軟體輸出時,就可以輸出 貼圖資訊 包含其中,譬如使用某個 *.jpg 來貼圖,只要彼此的檔案路徑正確的話,應該 flash 端不用做甚麼事情就會自動呈現了。

2.
*.dae 中,應該會定義許多的 材質,在 flash 端可以針對各個材質的 id,定義一組對照表。

因為不確定 Away3DLite 實作到甚麼程度,所以要嘗試過才知道,方法2 我以前在 PV3D 有試過,方法1 好像也用某種 lib 嘗試過應該可行,你再自己試試看吧~

關於我






* ben {dot} chang {at} ben {dot} idv {dot} tw
* FriendFeed

贊助我1元美金:

Plurk

標籤雲