Qualcomm Vuforia 教學 (6) – 3D model -> .obj -> .h
終於來到 Vuforia 記錄的最後一篇了,這篇參考到網路上神人的做法,怎麼把一個 3D model 轉換成 Vuforia 可以使用的 .h 檔,這邊之後都直接使用 Android NDK (JNI) 版本來實作,原因在這篇文章。
2016-07-07 更新:本篇為 3.x 版本,目前 Vuforia 以更新到 5.5.9,新版本使用方式請參考
Android Vuforia 系列:
- 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) – 多重模型載入,以 obj 為例
之前小蛙卡了很久,不知道怎麼把 3D model 轉換成 OpenGL 可以繪圖的座標,找到 參1 的資料後,卻因為一開始使用 Qualcomm Vuforia 教學 (3) – 替換茶壺 – Android 版本,在編譯上出現「The code of method xxx is exceeding the 65535 bytes limit」一直無法解決,直到 … 改成用 Qualcomm Vuforia 教學 (4) – 使用 Android NDK 版本並開啟多重偵測 才能正常運作。
花了一個下午的時間,看看 Blender 是怎麼進行 3D 塑模的動作,發現這似乎需要非常強大的天分才能夠駕馭 … 不過至少知道透過 Blender 可以把其他檔案格式匯入後,再轉出我們需要的 .obj 格式,雖然可能有些資訊會無法正常呈現,或者一些奇奇怪怪的問題,不過小蛙對這種軟體不是很了解,在這邊遇到問題的捧由只能自己 Google 了。
講一下大概的運作方式,首先必須先有 3D model (廢話),這個 3D model 格式只要是一般常見的 blender, unity, 3dmax … 等格式,或是你使用的塑模軟體有辦法吃進去並且轉出 .obj 格式都可以,有一點要特別特別特別注意,Vuforia 繪圖只能使用一張材質,也就是說如果一個房子有屋頂、牆壁、門、窗戶、地板、煙囪 … 等等材質,這些材質必須最後轉出成一個檔案,這部份可能要專業的 3D 塑模師才能做到 (小蛙摸了半天,結果令人失望),如果網路上下載來的專案檔包含了很多不同圖檔,就會發現 Vuforia 只會貼一張圖檔,其他的會變成殘缺樣,解套方案除了上面提到的將多材質轉製成一個影像檔,另一個比較麻煩,實作上也比較困難,就是把模型裡的每個不同貼圖的部份拆出來 (光聽就覺得超麻煩 …)
整個運作流程為:
1. 從網路上找免費的 3D 模型測試 (google free 3d model 有很多,不過大多是要註冊會員),如果自己會建模就可以省掉這麻煩,小蛙用的是 Blender,根據 參3 支援匯入的檔案格式有
1
2
3
4
5
6
7
8
9
|
Collada (.dae) Motion Capture (.bvh) Scalable Vector Graphics (.svg) Stanford (.ply) Stl (.stl) Autodesk 3ds Max (.3ds) Autodesk FBX (.fbx) Wavefront (.obj) X3D Extensible 3D (.x3d) |
2. 匯出 (Export) 成 Object (.obj) 格式,以 Blender 為例,匯出時必須勾選以下選項
1
2
3
4
5
6
|
apply Modifiers Include Edges Write Normals Include UVs Write Materials Object as OBJ Objects |
3. 下載 參1 中的轉換程式與範例:OBJ2OPENGL.ZIP,並解壓縮到 obj2opengl 資料夾,裡面主程式是 obj2opengl.pl 以及,banana 跟 cube 兩種範例。
4. 由於 obj2opengl 是以 perl 執行,點選 參4 下載並安裝,安裝過程一直下一步即可,安裝完成後開啟 cmd 輸入 perl -v 如果成功安裝可以在這邊看到 perl 的版本細節
5. 使用 cmd 進入 obj2opengl 資料夾後,輸入「perl obj2opengl.pl banana.obj」(如果是用 Qualcomm Vuforia 教學 (3) – 替換茶壺 – Android 版本 的話,產出的 .h 檔會因為資料量太大無法把資訊放入 MeshObject.java 中,所以要使用 Qualcomm Vuforia 教學 (4) – 使用 Android NDK 版本並開啟多重偵測 才可以進行),如果訊息如下並且沒看到任何 error 會產生出一個新的 banana.h 並把原本的覆蓋掉
01
02
03
04
05
06
07
08
09
10
|
Input file : .\banana.obj Output file : .\banana.h Object name : banana Center : <2289.89534195908, 599.62239347371, -8421.71066976487> Scale by : 0.000175074008952644 ---------------- Vertices : 4032 Faces : 8056 Texture Coords : 4420 Normals : 4032 |
6. 接著參考 Qualcomm Vuforia 教學 (5) – 替換茶壺 – Android JNI 版本 中的步驟,banana.h 放到 jni 目錄下,banana.jpg 放在 assets 目錄下。
7. 修改 ImageTargets.java
1
2
3
4
5
6
7
8
|
private void loadTextures() { //mTextures.add(Texture.loadTextureFromApk("TextureTeapotBrass.png", getAssets())); mTextures.add(Texture.loadTextureFromApk( "TextureTeapotBlue.png" , getAssets())); mTextures.add(Texture.loadTextureFromApk( "banana.jpg" , getAssets())); mTextures.add(Texture.loadTextureFromApk( "TextureTeapotRed.png" , getAssets())); mTextures.add(Texture.loadTextureFromApk( "Buildings.jpeg" , getAssets())); } |
8. 修改 jni 下的 ImageTargets.cpp
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
// 在上方加入 #include "banana.h" // glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &teapotVertices[0]); // 改成 glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid*) &bananaVerts[0]); // glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &teapotNormals[0]); // 改成 glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid*) &bananaNormals[0]); // glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &teapotTexCoords[0]); // 改成 glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, ( const GLvoid*) &bananaTexCoords[0]); // glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT, (const GLvoid*) &teapotIndices[0]); // 改成 glDrawArrays(GL_TRIANGLES, 0, cubeNumVerts); |
9. 開啟 cmd 到 jni 目錄下執行 ndk-build,沒有任何錯誤的話,重新整理專案後執行即可,上個範例我們把茶壺換成方塊,現在可以換成香蕉了。
經過這系列的文章,應該都可以把 Qualcomm Vuforia 運行起來,並且支援多重偵測,也有辦法自行把茶壺更換掉、更換貼圖、產出必須的 .h 檔案,下面貼幾張有趣的例子,這是網路上找到的免費 3D model,左上為模型的樣子-一間木屋,看到門開開的,走進去看看,右上為站在門口往裡看的樣子,左下是走進房子往天花板看的樣子,右下是從房子裡面往窗戶外面看的樣子,讓人不禁覺得 Qualcomm Vuforia 好強大啊!
Qualcomm Vuforia 系列:
- Qualcomm Vuforia 教學 (1) – 安裝 Vuforia
- Qualcomm Vuforia 教學 (2) – Create Image Target
- Qualcomm Vuforia 教學 (3) – 替換茶壺 – Android 版本
- Qualcomm Vuforia 教學 (4) – 使用 Android NDK 版本並開啟多重偵測
- Qualcomm Vuforia 教學 (5) – 替換茶壺 – Android JNI 版本
- Qualcomm Vuforia 教學 (6) – 3D model -> .obj -> .h
參考資料
- obj2opengl: convert obj 3D models to arrays compatible with iPhone OpenGL ES @ Heiko Behrens
http://heikobehrens.net/2009/08/27/obj2opengl/ (連結已失效) - blender.org
- Blender @ 維基百科
- ActivePerl Downloads
您好,其實我也採用了同樣的方法來做。效果也跟您的一樣。但是您有沒有發現,那個香蕉的紋理貼圖其實是有問題的,不知道這個應該如何解決?
感謝分享!剛好最近也要嘗試替換 model~