圖片來源:http://tw.freeimages.com/photo/blank-e-box-for-software-etc-4-1238246

圖片來源:http://tw.freeimages.com/photo/blank-e-box-for-software-etc-4-1238246

要進到這系列最後一篇文章了,這篇文章拖了很久,一直沒有時間整理,結果到最後 … 程式碼留下來了,記憶卻有些模糊了,這邊小蛙配著程式碼盡可能的把還記得的東西寫下來。

 

設計自己的物件

因為這邊要載入多個模型,而每個模型搭配的參數都不同,例如:刀鋒戰士要放大 10 倍並且往 y 軸位移 50、茶壺要 blablabla …,這邊可以根據自己的需求去做設計,小蛙隨意列了幾個可能會隨著不同模型調整的屬性

class MyObjs {
    private String symbol;
    private String obj;
    private String mtl;
    private List<String> textures;
    private float scale = 1;
    private float postScale = 1;
    // 0 度躺著正面朝上
    private float rotateX = 0;
    private float rotateY = 0;
    private float rotateZ = 0;
    private float traslateX = 0;
    private float traslateY = 0;
    private float traslateZ = 0;
    private Object3D target;
}

有看不懂的可以往前翻,屬性也不一一介紹了。

 

初始化物件

初始化這些物件,將每個要載入的物件及他的參數一一創建出來,

// 要觸發的圖片(ImageTarget)
private static List<String> SYMBOL = new ArrayList<>();
// 要呈現出來的 3D 模型
private List<MyObjs> objs = new ArrayList();
private void initObjs(){
    SYMBOL = Arrays.asList("stones", "chips", "tarmac");
    // 木頭櫃子
    MyObjs m = new MyObjs();
    m.symbol = SYMBOL.get(0);
    m.mtl = "Bedside_Table_D.mtl";
    m.obj = "Bedside Table D.obj";
    m.textures = Arrays.asList("Bedside_Table_D_default_1_1.png");
    m.scale = 5;
    m.rotateX = -1.5f;
    m.traslateX = -110;
    m.traslateY = -160;
    objs.add(m);
    // 灰色櫃子
    MyObjs w = new MyObjs();
    w.symbol = SYMBOL.get(2);
    w.mtl = "Bedside_Table_B.mtl";
    w.obj = "Bedside Table B.obj";
    w.textures = Arrays.asList("Bedside_Table_B_default_1_1.png");
    w.scale = 5;
    w.rotateX = -1.5f;
    w.traslateX = -110;
    w.traslateY = -160;
    objs.add(w);
    // 木桶
    MyObjs n = new MyObjs();
    n.symbol = SYMBOL.get(1);
    n.mtl = "MedievalBarrel_OBJ.mtl";
    n.obj = "MedievalBarrel_OBJ.obj";
    n.textures = Arrays.asList("MedBarrelDiffuse.jpg", "MedBarrelNormal.jpg");
    n.scale = 20;
    n.rotateX = -1.5f;
    n.traslateX = 0;
    n.traslateY = 0;
    objs.add(n);
}

在載入 obj 的範例中我們知道需要同時載入 mtl 搭配 textures,不然載進來的模型沒有材質貼圖。上面的例子中將屬性一一設定好,並且加入 objs 中,我們透過 m.symbol 來得知當出現哪張影像的時候,載入這個模型 (m.mtl, m.obj, m.textures), 並可設定縮放(scale)、翻轉(rotate)以及位移(traslate),這邊可以自己把自己要設定的屬性加上去。

 

載入物件

當把所有的物件都設定好之後,在 ImageTargetRenderer 建構子中載入這些物件們

... 以上省略 ...
initObjs();

try{
    for(int i = 0; i < objs.size(); i++){
        MyObjs m = objs.get(i);
        for(int j = 0; j < m.textures.size(); j++){
            TextureManager.getInstance().addTexture(
                m.textures.get(j),
                new Texture(mActivity.getAssets().open(TXT_PATH + m.textures.get(j)))
                );
        }
        Object3D[] tmp = Loader.loadOBJ(
            mActivity.getAssets().open(OBJ_PATH + m.obj),
            "".equals(m.mtl) ? null : mActivity.getAssets().open(MTL_PATH + m.mtl),
            m.scale
        );
        if(tmp != null && tmp.length >= 1){
            m.target = tmp[0];
        }

        m.target.strip();
        m.target.build();
        if(m.rotateX != 0)
            m.target.rotateX(m.rotateX);
        if(m.rotateY != 0)
            m.target.rotateY(m.rotateY);
        if(m.rotateZ != 0)
            m.target.rotateY(m.rotateZ);
        if(m.traslateX != 0 || m.traslateY != 0 || m.traslateZ != 0)
            m.target.translate(m.traslateX, m.traslateY, m.traslateZ);
        if(m.postScale != 1)
            m.target.scale(m.postScale);
        if("".equals(m.mtl)) {
            for(int z = 0; z < m.textures.size(); z++)
                m.target.setTexture(m.textures.get(z));
        }

        world.addObject(m.target);
        cam = world.getCamera();

        SimpleVector sv = new SimpleVector();
        sv.set(m.target.getTransformedCenter());
        sv.y -= 100;
        sv.z -= 100;
        sun.setPosition(sv);
    }
}catch(Exception e){
    e.printStackTrace();
}

將 objs 中的 MyObj 一一取出,並設定該物件之屬性,到這個階段,就可以依照不同影像載入不同模型,但,這還不夠。

 

移除模型

剩最後一個步驟,到上一個步驟會發現每個 render 出來的模型,他不會消失 … 不會消失 … 不會消失 … 加上這個步驟讓他消失吧!

// The render function.
private void renderFrame() {
    // clear color and depth buffer 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    // get the state, and mark the beginning of a rendering section
    State state = mRenderer.begin();
    // explicitly render the video background
    mRenderer.drawVideoBackground();        

    float[] modelviewArray = new float[16];
    // did we find any trackables this frame?
    for (int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++) {
        // get the trackable
        TrackableResult result = state.getTrackableResult(tIdx);
        Trackable trackable = result.getTrackable();
        printUserData(trackable);

        Matrix44F modelViewMatrix = Tool.convertPose2GLMatrix(result.getPose());                      
        Matrix44F inverseMV = SampleMath.Matrix44FInverse(modelViewMatrix);            
        Matrix44F invTranspMV = SampleMath.Matrix44FTranspose(inverseMV);

        try{world.removeAllObjects();}catch (Exception e){}
        for(int i = 0; i < objs.size(); i++){
            MyObjs m = objs.get(i);
            if(m.symbol.equals(trackable.getName())){
                world.addObject(m.target);
                SimpleVector sv = new SimpleVector();
                sv.set(m.target.getTransformedCenter());
                sv.y -= 100;
                sv.z -= 100;
                sun.setPosition(sv);
            }
        }

        modelviewArray = invTranspMV.getData();
        updateModelviewMatrix(modelviewArray);

    }                      
    // hide the objects when the targets are not detected
    if (state.getNumTrackableResults() == 0) {
    	float m [] = {
    		1,0,0,0,
    		0,1,0,0,
    		0,0,1,0,
    		0,0,-10000,1
    	};
    	modelviewArray = m;
    	updateModelviewMatrix(modelviewArray);
    }    	

    mRenderer.end();
}

這個 function 小蛙已經忘記哪些是小蛙自己加的,哪些是原本的 code 了,就整個附上來試試看吧!

小蛙之前也遇過有網友詢問動畫的部份,經過這一段時間的研究發現 … 如果真的要用到會動的 3D model,就直接使用 Unity 吧!畢竟在 native code 中要讓做到動畫真的太麻煩了 >< 之前 survey 了好久,因為變數太大、複雜度也太高,直接放棄轉向 render 動畫原本就是強項的 Unity。祝各位好運囉!

 

Android Vuforia with jPCT-AE 系列文章

Android Vuforia with jPCT-AE (1) – 基本範例
Android Vuforia with jPCT-AE (2) – 載入 obj 測試
Android Vuforia with jPCT-AE (3) – 載入 md2 測試
Android Vuforia with jPCT-AE (4) – 載入 3ds 測試
Android Vuforia with jPCT-AE (5) – 多重模型載入

 

 

相關文章

Android Vuforia with jPCT-AE (2) – 載入 obj 測試

上一篇 Android Vuforia with jPCT-AE (1) –
2016-07-06 08:24:55
hans

18

Qualcomm Vuforia 教學 (6) – 3D model -> .obj -> .h

終於來到 Vuforia 記錄的最後一篇了,這篇參考到網路上神人的做法,怎麼把一個 3D model 轉換成 Vuforia 可以使用的 .h 檔,這邊之後都直接使用 An
2014-12-10 11:25:50
hans

18

在 Eclipse 上開發 PHP 程式(以 Moodle、EGit、PDT 為例)

最近受命必須要研究 moodle,並且希望可以用 Eclipse 這種比較聰明的 IDE 來開發,而 moodle 本身是 PHP 寫的,之前只有使用 Eclipse 開發過 Java,這篇文章只是簡單記錄怎麼讓 Eclipse 可以開發
2012-12-19 17:24:56
hans

18

java/lang/NoClassDefFoundError: java/lang/Object

今天小蛙要使用 Eclipse 的時候發現開啟的時候,馬上就又瞬間關閉,連個錯誤訊息都沒有看到,有錯誤訊息大概還能看一下問題出在哪,最怕這種完全沒有任何訊息的問題 ... 花了五分鐘 Google 搞定,這邊記錄一下,免得下次又發生這種情況
2012-09-07 17:45:40
hans

18

SSL For Free – 免費又有綠色鎖頭的 SSL Certificates

之前聽說 Google 會優先搜尋有 https 的網頁 (參考:
2016-07-07 23:00:54
hans

8

Android Vuforia with jPCT-AE (4) – 載入 3DS 測試

延續 jPCT-AE Loader 載入模型的部份,這篇要記錄載入 3ds 檔案格式的方法,基本上跟前面幾個 obj, md2 的方法差不多,只有一些小小的變化而已。
2016-07-06 10:24:33
hans

8

Android Vuforia with jPCT-AE (3) – 載入 md2 測試

前兩篇介紹如何直接透過 jPCT-AE 直接繪圖以及載入 .obj 檔案,這邊繼續介紹 jPCT-AE 載入 md2 的方法,載入動作大致上類似,唯一不同的只有 texture 設定部份。
2016-07-06 09:24:43
hans

8

Android Vuforia with jPCT-AE (1) – 基本範例

說來慚愧,從 Google Adsense 被 ban 之後,就好久沒有發文了,站上 Vuforia 的文章也已經是好久以前的事情了 (遠目),最近有專案要用到 Vuforia,爬以前的文回來看,蛙哩咧 ... 現在已經更新到 Vu
2016-07-06 07:57:58
hans

8

我的股票精算師備份功能

常遇到使用者詢問「我的股票精算師」要怎麼備份,這篇記錄一下,需要寫怎麼備份表示軟體設計上有很大的問題,造成使用者使用上的困難,但小蛙最近沒有時間去做修改 ... 只好委屈精算師的使用者了 ><
2015-02-06 18:32:07
hans

8




 回覆

你可以使用以下語法 HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="">

(required)

(required)

   
© 2012 蛙齋 Suffusion theme by Sayontan Sinha