Android下利用min3D引擎實現擴增實境的簡單例子
前段時間研究了一下Min3D遊戲開發引擎,發現這個引擎很好用,例子非常細,使用起來很方便,尤其給的最後一
個例子“ExampleAccelerometer”,很有意思,結合重力感應,這對於最近在做的擴增實境專案有一點啟發,
於是這裡把自己探索的過程和大家分享一下。
這裡對於min3D我就不詳細介紹了,以後我會在寫篇關於min3D的文章, 大家可以先
到http://code.google.com/p/min3d/去了解,在這裡為了更好地理解我的意思,建議大家把我提到的那個例子執行一下,體驗一下效果.
我先把做好的效果說明一下,先上圖:
背景是手機的攝像頭,作為實時的預覽,在預覽圖層的上面利用min3D繪製一個三維影象,而且這是一個md2檔案
,當第一次點選螢幕時,3D人物會“跳舞”,再次點選螢幕時,停止動畫。另外,我還結合了加速度感測器,這樣,當
螢幕向左傾斜時,人物向右移動,向右傾斜時,任務向左移動。
好了,下面該說說原理了。
總的來說,實現步驟有四個:
1、開啟攝像頭,並將預覽影象作為底層;
2、利用min3D在預覽圖層上繪製或者匯入一個虛擬人物;
3、新增觸屏事件,在觸屏時播放動畫;
4、獲得感測器資料,動態設定虛擬人物的位置。
下面該是分解動作了:
一、開啟攝像頭,並將預覽影象作為底層
直接上程式碼:下面是Screen類,專門用來定義攝像頭檢視的
package com.example.animalar;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
//這個類是用來開啟攝像頭的
public class Screen extends SurfaceView implements SurfaceHolder.Callback {
public Screen(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
previewHolder = this.getHolder();
previewHolder.addCallback(this);
//************
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* Initialize the hardware camera. holder The holder
*/
public void surfaceCreated(SurfaceHolder holder) {
//************
if(!isPreviewRunning)
mCamera = Camera.open();
else
mCamera.stopPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
try {
if (mCamera!=null) {
//**********
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
//**********
mCamera=null;
isPreviewRunning=false;
}
} catch (Exception e) {
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(mCamera!=null&&isPreviewRunning!=true)
{
try{
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(w, h);
mCamera.setPreviewDisplay(holder);
//mCamera.setParameters(p);
mCamera.setPreviewCallback(null);
mCamera.startPreview();
}
catch (IOException e) {
e.printStackTrace();
}
isPreviewRunning = true;
}
}
private Camera mCamera;
private SurfaceHolder previewHolder;
private boolean isPreviewRunning=false;
//private Camera.PreviewCallback imageCaptureCallback;
}
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
//這個類是用來開啟攝像頭的
public class Screen extends SurfaceView implements SurfaceHolder.Callback {
public Screen(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
previewHolder = this.getHolder();
previewHolder.addCallback(this);
//************
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* Initialize the hardware camera. holder The holder
*/
public void surfaceCreated(SurfaceHolder holder) {
//************
if(!isPreviewRunning)
mCamera = Camera.open();
else
mCamera.stopPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
try {
if (mCamera!=null) {
//**********
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
//**********
mCamera=null;
isPreviewRunning=false;
}
} catch (Exception e) {
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(mCamera!=null&&isPreviewRunning!=true)
{
try{
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(w, h);
mCamera.setPreviewDisplay(holder);
//mCamera.setParameters(p);
mCamera.setPreviewCallback(null);
mCamera.startPreview();
}
catch (IOException e) {
e.printStackTrace();
}
isPreviewRunning = true;
}
}
private Camera mCamera;
private SurfaceHolder previewHolder;
private boolean isPreviewRunning=false;
//private Camera.PreviewCallback imageCaptureCallback;
}
|
這個類是用來開啟攝像頭的,繼承自surfaceview,要注意出現"//********"的地方,這些地方很容易導致錯誤。
這個只是一個SurfaceView定義,還沒有加到圖層中去,所以別急
哦,對了,忘了說佈局檔案了,看程式碼吧:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<FrameLayout android:id="@+id/abc1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<FrameLayout android:id="@+id/abc2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<div align="\"left\""></FrameLayout> </div>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<FrameLayout android:id="@+id/abc1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<FrameLayout android:id="@+id/abc2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<div align="\"left\""></FrameLayout> </div>
|
繪製圖形的部分就體現出min3D的優勢了,很短的函式就能把完整的md2檔案匯入進去,這裡再次建議大家看一看
min3D的程式碼,有助於下面的理解。
min3D的程式碼,有助於下面的理解。
二、利用min3D在預覽圖層上繪製或者匯入一個虛擬人物
public void initScene() {
scene.backgroundColor().setAll(0x00000000);
scene.lights().add(new Light()); // 新增光源
IParser parser = Parser.createParser(Parser.Type.MD2, getResources(),
"com.example.animalar:raw/ogro", false);
parser.parse();
ogre = parser.getParsedAnimationObject();
ogre.scale().x = ogre.scale().y = ogre.scale().z = .07f;
ogre.rotation().z = -90;
ogre.rotation().x = -90;
ogre.position().z = -4f;
ogre.position().y = -2f;
scene.addChild(ogre);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_UI);
}
scene.backgroundColor().setAll(0x00000000);
scene.lights().add(new Light()); // 新增光源
IParser parser = Parser.createParser(Parser.Type.MD2, getResources(),
"com.example.animalar:raw/ogro", false);
parser.parse();
ogre = parser.getParsedAnimationObject();
ogre.scale().x = ogre.scale().y = ogre.scale().z = .07f;
ogre.rotation().z = -90;
ogre.rotation().x = -90;
ogre.position().z = -4f;
ogre.position().y = -2f;
scene.addChild(ogre);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_UI);
}
|
繪製圖形的部分就體現出min3D的優勢了,很短的函式就能把完整的md2檔案匯入進去,這裡再次建議大家看一看
min3D的程式碼,有助於下面的理解。
min3D的程式碼,有助於下面的理解。
三、新增觸屏事件,在觸屏時播放動畫;
public boolean onTouchEvent(MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
if (twice == false) {
ogre.setFps(30);
ogre.play();
twice = true;
} else {
ogre.pause();
twice = false;
}
}
return true;
}
if (e.getAction() == MotionEvent.ACTION_DOWN) {
if (twice == false) {
ogre.setFps(30);
ogre.play();
twice = true;
} else {
ogre.pause();
twice = false;
}
}
return true;
}
|
注意boolean twice這個變數,當twice=false,判定為第一次觸控螢幕,播放動畫。
當twice=true時,判定為再次觸摸螢幕,此時停止播放動畫
四、獲得感測器資料,動態設定虛擬人物的位置。
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
//float Acc_Z = (float) event.values[2];
mAccVals.x = (float) (-event.values[1] * FILTERING_FACTOR + mAccVals.x
* (1.0 - FILTERING_FACTOR));
mAccVals.y = (float) (event.values[0] * FILTERING_FACTOR + mAccVals.y
* (1.0 - FILTERING_FACTOR));
// mAccVals.x=-event.values[1];
scene.camera().position.x = mAccVals.x * .5f;
scene.camera().position.y = mAccVals.y * .2f;
scene.camera().target.x = scene.camera().position.x;
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
關於Android下感測器的使用方法這裡就不在贅述了,網上的教程挺多的。其實這裡的程式碼是min3D引擎中的
ExampleAccelerometer例子的原始碼
相關文章
- 十行HTML實現擴增實境HTML
- 利用PHP SOAP擴充套件實現簡單Web ServicesPHP套件Web
- 實現一個簡單的模板引擎
- 150行JavaScript程式碼實現擴增實境JavaScript
- ar擴增實境遊戲有什麼 ar擴增實境遊戲推薦遊戲
- ar擴增實境應用有哪些 ar擴增實境軟體推薦
- ar擴增實境是什麼意思 ar擴增實境技術介紹說明
- Python簡單實現多執行緒例子Python執行緒
- Java實現簡單的增刪改查操作Java
- 利用Wireshark和OSS的API文件簡單實現上傳和下載API
- python下ssh的簡單實現Python
- Android中SharePreferences的簡單實現Android
- AR擴增實境可應用的場景
- AR擴增實境的發展趨勢分析
- 什麼是虛擬現實和擴增實境、混合現實?區別請看這裡
- 前端資料渲染及mustache模板引擎的簡單實現前端
- 用java實現一個簡單的序列化的例子(轉)Java
- 用java實現一個簡單的序列化的例子 (轉)Java
- 出版行業可以利用AR擴增實境技術大作文章行業
- Android應用加固的簡單實現方案Android
- Mybatis-plus實現簡單增刪改查MyBatis
- ARKit:擴增實境技術在美團到餐業務的實踐
- 利用JQuery實現更簡單的Ajax跨域請求jQuery跨域
- VR(虛擬現實)和AR(擴增實境)會是下一個大產業???VR產業
- 虛擬現實(VR)和擴增實境(AR)背後的核心技術是什麼?VR
- 使用Mongoose類庫實現簡單的增刪改查Go
- 利用 Redis 的 bitmap 實現簡單的布隆過濾器Redis過濾器
- KOA的簡易模板引擎實現方式
- 實現簡單的BitMap
- ArrayList的簡單實現
- AOP的簡單實現
- 簡單的 HashMap 實現HashMap
- 簡單的Filter實現Filter
- Promise的簡單實現Promise
- Android應用加固的簡單實現方案(二)Android
- Android 時間軸的實現(RecyclerView更簡單)AndroidView
- android簡單的登入介面的實現1Android
- Android Tab 選項卡的簡單實現薦Android