2009年11月21日 星期六

PV3D 練習 - 開車

開車兜兜風…
http://www.asn.com.tw/flex/cardrive/cardrive.html

http://www.asn.com.tw/flex/cardrive/cardrive2.html with BOX2D

程式參考…
http://pv3d.org/2009/01/23/springcamera3d-and-driving-a-car/
重點在 driveCar() 及 updateCar() 兩個函式。

汽車控制幾乎都使用原作的,看別人的程式可以學到很多,沒想到原來不難,缺的大概就是經驗跟創意。

另一個重點是汽車的模型,在建模的時候就要先規畫好,要能配合程式運作,包括物件軸心、面向、四個輪子的軸心跟方向、子物件的名稱…。

圖檔及資源的讀取部份改寫如下…

使用一個陣列 push 所有需要讀取資源的 loader,並加入事件監聽,在收到完成的事件後再移出陣例,最後判斷是否己全數讀取完成,再進行其它的初始化工作。

        private var loadAssets:Array = new Array();
        private function initAssets():void
        {
            removeEventListener(Event.ADDED_TO_STAGE, initAssets);

            floorMaterial = new BitmapFileMaterial("assets/grassTexture.jpg");
            floorMaterial.addEventListener(FileLoadEvent.LOAD_COMPLETE,onLoadAssets);
            loadAssets.push(floorMaterial);

            bodyMaterial = new BitmapFileMaterial("assets/FocusBody.jpg");
            bodyMaterial.addEventListener(FileLoadEvent.LOAD_COMPLETE,onLoadAssets);
            loadAssets.push(bodyMaterial);

            wheelMaterial = new BitmapFileMaterial("assets/FocusWheel.jpg");
            wheelMaterial.addEventListener(FileLoadEvent.LOAD_COMPLETE,onLoadAssets);
            loadAssets.push(wheelMaterial);
        }
       
        private function onLoadAssets(e:FileLoadEvent):void
        {
            var idx:Number = loadAssets.indexOf(e.target);
            if( idx != -1 )
            {
                if( e.target is BitmapFileMaterial )
                    (e.target as BitmapFileMaterial).removeEventListener(FileLoadEvent.LOAD_COMPLETE,onLoadAssets);
                loadAssets.splice( idx, 1 );
                if( loadAssets.length == 0 )
                    initOther();
            }
        }

2009年11月20日 星期五

PV3D DAEMC2 練習

DAEMC2 是一個讓 PV3D 可以讀取 dae 動作模型的組件,藉由它,可以讓你在 PV3D 中控制撥放預先制作好的動作。

http://www.asn.com.tw/flex/BoxMan/BoxMan.html

程式參考 這裡,但改成了 DAEMC2 版 frame 的新的操作方式。

DAEMC2 教學可以參考 影片

2009年11月11日 星期三

Paper Vision 3D 正確 destory 物件的方法

由於 AS3 有 garbage collection 的機制,這樣的機制有好有壞,但千萬別以為有 garbage collection 就不用去在意 memory 的議題,因為不管 garbage collection 運作的原理是什麼,它總還是有一套運作的規則,不去依循這個規則的話,仍然會造成 memory leaks。

garbage collection 主要的扮演角色的是在程式背後的「管理程式」,記錄、管理使用者(這裡指程式設計師) 記憶體的使用狀況,它底層的意義就是在記錄某段記憶體是不是有物件(指標、參考…)指向它,若沒的話,便能進行釋放。

可以想像的到,一個環狀的參考一定會造成 garbage collection 的困擾,因此,在具備 garbage collection 的系統下寫程式,有些地方便要特別注意,才不會造成問題。

以前在 C++,常常會使用指標將自己 allocate 到的 memory 記錄下來,以便在物件 destroy 時一併釋放,但在 garbage collection 系統,這樣的習慣卻會造成「過多的」或「意外的」參考到了沒用到的記憶體,反而造成 garbage collection 無法正確運作。

因此在寫 AS3 時,儘量在要用到時才去 new 一個物件,而不需要在初始化時就把一切 new 出來放在私有變數裡去作準備,當然,這也不是通則,期待更好的 garbage collection 系統出現。

回歸正題,Paper Vision 3D 物件的創建跟刪除便出現了類似上述的問題,當你用「動態」的產生物件 (譬如 sphere 或 cube) 時,由於物件需要參考到 Material 材質,而材質又會記錄著使用這個 Material 的物件 list,於是當你刪除物件( 從 scene 移除並設為 null ) 卻發現 garbage collection 起不了作用,memory 依然被佔用住,這樣的 memory leaks 造成的後果會非常嚴重,memory 用量會不斷攀升,最後效能直線下降。

在 Paper Vision 3D 團隊還沒修正這段(bug?)或 改用更好的作法之前…
解決方法:

        private function destory3DObject():void
        {
            var objArray:Array = new Array();
            var obj:DisplayObject3D;
            for each ( obj in this.scene.objects )
                objArray.push(obj);
           
            for ( obj=objArray.pop(); obj; obj=objArray.pop() )
            {
                var mmArray:Array = new Array();
                var mm:MaterialObject3D;
                for each ( mm in obj.materials )
                    mmArray.push(mm);

                for ( mm=mmArray.pop(); mm; mm=mmArray.pop() )
                {
                    mm.interactive = false;
                    mm.unregisterObject(obj);
                    obj.materials.removeMaterial(mm);
                    mm.destroy();
                }
                obj.materials = null;
                //obj.material.animated = false;
                obj.material.interactive = false;
                obj.material.unregisterObject(obj);               
                this.scene.removeChild( obj );
                obj.material.destroy()
                obj.material = null;
            }
        }

 每個步驟的先後順序很重要,次序相反有可能還是沒清楚跟 garbage collection 系統交待好你不要這段 memory 了,你會發現,最後參考到這段 memory 的會是區域變數 var obj,如此才能保證在離開 scope 後沒有任何參考指標與該物件有關聯。

這個函式是一次清除所有的  DisplayObject3D物件,若只想清除物定物件,那可以使用 array 來裝你的 DisplayObject3D 物件即可,程式雷同。

所以其實 garbage collection 好壞見仁見智吧,好像只不過換了方式去管理你創出來的物件/記憶體罷了,恐怕還是需要瞭解黑箱下的作業方式,才能真正去掌握你所有的資源。

2009年11月10日 星期二

BOX2D + PV3D 物理運動模擬-線上測試盒

網址 :http://www.asn.com.tw/flex/box2dpv3d_world.htm

使用方法,在 creat 頁,填上整個 world 的 XML 描述檔,再按 creat 即可建立一個新的物理模擬世界,按 sample world 有範例可以參考。

說明:
這個程式是依據 boristhebrave Box2DWith 的 Box2D XML loader
線上建立 Box2D 物件,同時轉換成 PV3D 物件對應( 目前支援 CUBE、SPHERE )
支援 TAG 如下…(細節請參考 boristhebrave 的 b2XML.as 文件說明)

world
body
circle
box
distance
prismatic
revolute
gear


<body userData="PV3D" position="200 100" id="head">
<circle radius="15" density="1" friction="0.4" restitution="0.3">
</body>

即是在XY座標(200,100)的位置建立一個半徑15的圓,其密度=1,摩擦力=0.4,反彈=0.3
其中 userData="PV3D" 代表要同時建立一個 PV3D 的對應3D物件-球。

更新…
2009/11/13-PV3D物件增加z軸初始及物件厚度的解析。(BOX適用)
語法:userData="PV3D,Z,DEPTH"
範例:userData="PV3D,50,20" - 在z軸50的位置上建立厚度20的PV3D物件(CUBE)
*實際碰撞處理仍為BOX2D引擎。

2009年10月22日 星期四

繪圖型LCM模組當文字型輸出

繪圖型LCM模組 WG14432A 跟 文字型有相當程度的不同
但一樣可以當成文字型來使用

要注意RAM排列方式的不同,例如換行(設定DDRAM位址)指令…
void LCM_line2( void )
{
/// a = 0xC0; /// 文字型 LCM
a = 0x90; /// 繪圖型 LCM
LCM_WriteCommand();
}

2009年10月19日 星期一

IntraWeb 如何使用 POST/GET 傳遞參數

IntraWeb 的 WebApplication 要透過以前表單 POST/GET 的方式來傳遞參數該如何實現?

//// FROM METHOD="GET"
usrParam:=WebApplication.Request.QueryFields.Values['usr'];
pwdParam:=WebApplication.Request.QueryFields.Values['pwd'];

//// FORM METHOD="POST"
usrParam:=WebApplication.Request.ContentFields.Values['usr'];
pwdParam:=WebApplication.Request.ContentFields.Values['pwd'];

VirtualBox 空間減肥

sdelete64 -z c: VBoxManage  modifymedium  disk  "/Users/fellow/VirtualBox VMs/Win10/Win10.vdi"  --compact *.vdi 路徑可以在 VirtualBox 儲...