android3D物體的碰撞——正方體的碰撞

來源:互聯網
上載者:User

     
3D物體的碰撞和2D類似,都是根據座標來計算物體的距離,判斷是否碰撞。下面舉個簡單的列子吧,我這個列子比較局限,簡單,只是為了說明這個方法而已,大家可以參照方法進行改進,下面看看代碼吧。

 

 

 

 

 

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:id="@+id/main_liner"    android:layout_width="fill_parent"    android:layout_height="fill_parent"></LinearLayout>

 

 

 

 

package yy.cal;import android.app.Activity;import android.os.Bundle;import android.widget.LinearLayout;public class GLSurfaceViewActivity extends Activity {private MySurfaceView mSurfaceView;//聲明MySurfaceView對象    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);             mSurfaceView=new MySurfaceView(this);//建立MySurfaceView對象        mSurfaceView.requestFocus();//擷取焦點        mSurfaceView.setFocusableInTouchMode(true);//設定為可觸控        LinearLayout ll=(LinearLayout)this.findViewById(R.id.main_liner);//獲得線性布局的引用        ll.addView(mSurfaceView);    }@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();mSurfaceView.onPause();}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();mSurfaceView.onResume();}  }

 

 

 

package yy.cal;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.opengl.GLSurfaceView;import android.opengl.GLU;import android.view.KeyEvent;import android.view.MotionEvent;public class MySurfaceView extends GLSurfaceView{private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度縮放比例    private SceneRenderer mRenderer;//情境渲染器    private float mPreviousX;//上次的觸控位置X座標public MySurfaceView(Context context) {        super(context);        mRenderer = new SceneRenderer();//建立情境渲染器        setRenderer(mRenderer);//設定渲染器        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//設定渲染模式為主動渲染       }//觸摸事件回調方法    @Override     public boolean onTouchEvent(MotionEvent e) {        float x = e.getX();        switch (e.getAction()) {        case MotionEvent.ACTION_MOVE:            float dx = x - mPreviousX;//計算觸控筆X位移            mRenderer.angle += dx * TOUCH_SCALE_FACTOR;//設定沿x軸旋轉角度            requestRender();                       //重繪畫面        }           mPreviousX = x;//記錄觸控筆位置        return true;    }public boolean onKeyDown(int keyCode,KeyEvent event){if(keyCode==KeyEvent.KEYCODE_DPAD_UP){mRenderer.x +=0.5f;}if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){mRenderer.x -=0.5f;}if(keyCode==KeyEvent.KEYCODE_DPAD_LEFT){ mRenderer.angle+=90;}if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT){ mRenderer.angle+=90;}return super.onKeyDown(keyCode, event);}private class SceneRenderer implements GLSurfaceView.Renderer     {       Cube cube=new Cube();//立方體    float angle=45;//總旋轉角度    float x=0,y=0,z=0;        public void onDrawFrame(GL10 gl) {    //設定為開啟背面剪裁    gl.glEnable(GL10.GL_CULL_FACE);    //設定著色模型為平滑著色               gl.glShadeModel(GL10.GL_SMOOTH);                //清除顏色緩衝於深度緩衝        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);        //設定當前矩陣為模式矩陣            gl.glMatrixMode(GL10.GL_MODELVIEW);            //設定當前矩陣為單位矩陣            gl.glLoadIdentity();                            GLU.gluLookAt//不太可能變形的視角——小視角            (            gl,             0f,   //人眼位置的X            10f, //人眼位置的Y            15.0f,   //人眼位置的Z            0, //人眼球看的點X            0f,   //人眼球看的點Y            0,   //人眼球看的點Z            0,             1,             0            );                          //旋轉總座標系            gl.glRotatef(angle, 0, 1, 0);                        //繪製右立方體            gl.glPushMatrix();            gl.glTranslatef(x, y, z);            cube.drawSelf(gl);            gl.glPopMatrix();                                    gl.glPushMatrix();            gl.glTranslatef(2, 0, 0);            cube.drawSelf(gl);            gl.glPopMatrix();            if(x>1.0f&&x<3.0f){            ColorRect.flag=false;            }else{            ColorRect.flag=true;            }        }                public void onSurfaceChanged(GL10 gl, int width, int height) {            //設定視窗大小及位置         gl.glViewport(0, 0, width, height);        //設定當前矩陣為投影矩陣            gl.glMatrixMode(GL10.GL_PROJECTION);            //設定當前矩陣為單位矩陣            gl.glLoadIdentity();            //計算透視投影的比例            float ratio = (float) height/width ;            //調用此方法計算產生透視投影矩陣            //gl.glFrustumf( -1, 1,-ratio, ratio, 1, 100);   //可能變形的視角——大視角              gl.glFrustumf( -1, 1,-ratio, ratio, 8f, 100);     //不太可能變形的視角——小視角        }        public void onSurfaceCreated(GL10 gl, EGLConfig config) {            //關閉抗抖動         gl.glDisable(GL10.GL_DITHER);        //設定特定Hint項目的模式,這裡為設定為使用快速模式            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);            //設定螢幕背景色黑色RGBA            gl.glClearColor(0,0,0,0);                        //啟用深度測試            gl.glEnable(GL10.GL_DEPTH_TEST);        }    }}

 

 

package yy.cal;import javax.microedition.khronos.opengles.GL10;import static yy.cal.Constant.*;public class Cube {//用於繪製各個面的顏色矩形ColorRect cr=new ColorRect(SCALE,SCALE);public void drawSelf(GL10 gl){//總繪製思想:通過把一個顏色矩形旋轉移位到立方體每個面的位置//繪製立方體的每個面gl.glPushMatrix();//繪製前小面gl.glPushMatrix();gl.glTranslatef(0, 0, UNIT_SIZE*SCALE);cr.drawSelf(gl);gl.glPopMatrix();//繪製後小面gl.glPushMatrix();gl.glTranslatef(0, 0, -UNIT_SIZE*SCALE);gl.glRotatef(180, 0, 1, 0);cr.drawSelf(gl);gl.glPopMatrix();//繪製上大面gl.glPushMatrix();gl.glTranslatef(0,UNIT_SIZE*SCALE,0);gl.glRotatef(-90, 1, 0, 0);cr.drawSelf(gl);gl.glPopMatrix();//繪製下大面gl.glPushMatrix();gl.glTranslatef(0,-UNIT_SIZE*SCALE,0);gl.glRotatef(90, 1, 0, 0);cr.drawSelf(gl);gl.glPopMatrix();//繪製左大面gl.glPushMatrix();gl.glTranslatef(UNIT_SIZE*SCALE,0,0);gl.glRotatef(-90, 1, 0, 0);gl.glRotatef(90, 0, 1, 0);cr.drawSelf(gl);gl.glPopMatrix();//繪製右大面gl.glPushMatrix();gl.glTranslatef(-UNIT_SIZE*SCALE,0,0);gl.glRotatef(90, 1, 0, 0);gl.glRotatef(-90, 0, 1, 0);cr.drawSelf(gl);gl.glPopMatrix();gl.glPopMatrix();}}

 

   

 

 

package yy.cal;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.IntBuffer;import javax.microedition.khronos.opengles.GL10;public class ColorRect {private FloatBuffer   mVertexBuffer;//頂點座標資料緩衝    private IntBuffer   mColorBuffer,mColorBuffer1,mColor;//頂點著色資料緩衝    int vCount=0;//頂點數量    static boolean flag=true;    public ColorRect(float width,float height)    {    //頂點座標資料的初始化================begin============================        vCount=6;        final float UNIT_SIZE=1.0f;        float vertices[]=new float[]        {        0,0,0,        width*UNIT_SIZE,height*UNIT_SIZE,0,        -width*UNIT_SIZE,height*UNIT_SIZE,0,        -width*UNIT_SIZE,-height*UNIT_SIZE,0,        width*UNIT_SIZE,-height*UNIT_SIZE,0,        width*UNIT_SIZE,height*UNIT_SIZE,0        };        //建立頂點座標資料緩衝        //vertices.length*4是因為一個整數四個位元組        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);        vbb.order(ByteOrder.nativeOrder());//設定位元組順序        mVertexBuffer = vbb.asFloatBuffer();//轉換為Float型緩衝        mVertexBuffer.put(vertices);//向緩衝區中放入頂點座標資料        mVertexBuffer.position(0);//設定緩衝區起始位置        //特別提示:由於不同平台位元組順序不同資料單元不是位元組的一定要經過ByteBuffer        //轉換,關鍵是要通過ByteOrder設定nativeOrder(),否則有可能會出問題        //頂點座標資料的初始化================end============================                //頂點著色資料的初始化================begin============================        final int one = 65535;        int colors[]=new int[]//頂點顏色值數組,每個頂點4個色彩值RGBA        {        one,one,one,0,        0,0,one,0,        0,0,one,0,        0,0,one,0,        0,0,one,0,              0,0,one,0,        };                //建立頂點著色資料緩衝        //vertices.length*4是因為一個int型整數四個位元組        ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);        cbb.order(ByteOrder.nativeOrder());//設定位元組順序        mColorBuffer = cbb.asIntBuffer();//轉換為int型緩衝        mColorBuffer.put(colors);//向緩衝區中放入頂點著色資料        mColorBuffer.position(0);//設定緩衝區起始位置                        int colors1[]=new int[]                             {                            0,0,one,0,                             0,0,one,0,                                   0,0,one,0,                             one,one,one,0,                             0,0,one,0,                             0,0,one,0,                             };                             ByteBuffer cbb1 = ByteBuffer.allocateDirect(colors1.length*4);                             cbb1.order(ByteOrder.nativeOrder());                             mColorBuffer1 = cbb1.asIntBuffer();//轉換為int型緩衝                             mColorBuffer1.put(colors1);//向緩衝區中放入頂點著色資料                             mColorBuffer1.position(0);//設定緩衝區起始位置        //特別提示:由於不同平台位元組順序不同資料單元不是位元組的一定要經過ByteBuffer        //轉換,關鍵是要通過ByteOrder設定nativeOrder(),否則有可能會出問題        //頂點著色資料的初始化================end============================                                     }    public void drawSelf(GL10 gl)    {                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//啟用頂點座標數組        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//啟用頂點顏色數組        //為畫筆指定頂點座標資料        gl.glVertexPointer        (        3,//每個頂點的座標數量為3  xyz         GL10.GL_FLOAT,//頂點座標值的類型為 GL_FIXED        0, //連續頂點座標資料之間的間隔        mVertexBuffer//頂點座標資料        );                        if(flag){        mColor=mColorBuffer;        }else{        mColor=mColorBuffer1;        }        //為畫筆指定頂點著色資料        gl.glColorPointer        (        4, //設定顏色的組成成分,必須為4—RGBA        GL10.GL_FIXED, //頂點顏色值的類型為 GL_FIXED        0, //連續頂點著色資料之間的間隔        mColor//頂點著色資料        );                //繪製圖形        gl.glDrawArrays        (        GL10.GL_TRIANGLE_FAN, //以三角形方式填充        0,  //開始點編號        vCount//頂點的數量        );    }}

 

 

 

 

package yy.cal;public class Constant { public static final float UNIT_SIZE=1.0f;//單位尺寸 public static final float SCALE=0.5f;//尺寸縮放比}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.