a question about collision detection

Started by Simdanfeg, May 18, 2011, 11:09:14 AM

Previous topic - Next topic

Simdanfeg

 ;D
I would like to ask the realization principle of collision detection,  I saw examples of that on the collision detection, but still very unclear, such as the following code, cube is how to detect a collision with those objects, and collision detection is how to achieve, ???


// Move method
public void move() {
if (up) {
SimpleVector t = cube.getZAxis();
t.scalarMul(SPEED);
moveRes.add(t);
}
if (down) {
SimpleVector t = cube.getZAxis();
t.scalarMul(-SPEED);
moveRes.add(t);
}
if (left) {
cube.rotateY((float) Math.toRadians(-1));
}
if (right) {
cube.rotateY((float) Math.toRadians(1));
}
// Avoid high speed
if (moveRes.length() > SPEED) {
moveRes.makeEqualLength(new SimpleVector(0, 0, MAXSPEED));
}
cube.translate(0, -0.02f, 0);

// collisionEllipsoid
cube.checkForCollisionEllipsoid(moveRes, ellipsoid, 8);
cube.translate(moveRes);

SimpleVector t = new SimpleVector(0, 1, 0);
t = cube.checkForCollisionEllipsoid(t, ellipsoid, 1);
cube.translate(t);

// damping
if (moveRes.length() > DAMPING) {
moveRes.makeEqualLength(new SimpleVector(0, 0, DAMPING));
} else {
moveRes = new SimpleVector(0, 0, 0);
}
}

EgonOlsen

That example code might be a bit too complex to start with, because it seems to be written for a very special case. What exactly do you want to achieve?

Simdanfeg

 ;D   Ah, I know, e.g. if a cube and a sphere to a collision, how to deal with it.

EgonOlsen

You have to set the collision modes and call the collision methods...it's not much more than that. Here's a hacky test case of mine that i used to optimize the collision detection. Maybe it helps.

package com.threed.jpct.example;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.res.Resources;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.MemoryHelper;

public class HelloWorld_col extends Activity {

   // Used to handle pause and resume...
   private static HelloWorld_col master = null;

   private GLSurfaceView mGLView;
   private MyRenderer renderer = null;
   private FrameBuffer fb = null;
   private World world = null;

   private RGBColor back = new RGBColor(50, 50, 100);


   private Object3D sphere1 = null;
   private Object3D sphere2 = null;
   private Object3D sphere3 = null;
   private Object3D cube=null;
   
   private SimpleVector move=new SimpleVector(0,0.3,1);
   private SimpleVector ellips=new SimpleVector(7,7,7);
   private SimpleVector tmp=new SimpleVector();


   protected void onCreate(Bundle savedInstanceState) {
      Logger.log("onCreate");

      if (master != null) {
         
      }

      super.onCreate(savedInstanceState);
      mGLView = new GLSurfaceView(getApplication());

      mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
            // Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
            // back to Pixelflinger on some device (read: Samsung I7500)
            int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
            EGLConfig[] configs = new EGLConfig[1];
            int[] result = new int[1];
            egl.eglChooseConfig(display, attributes, configs, 1, result);
            return configs[0];
         }
      });

      renderer = new MyRenderer();
      mGLView.setRenderer(renderer);
      setContentView(mGLView);
   }

   

   protected void onStop() {
      Logger.log("onStop");
      super.onStop();
   }


   class MyRenderer implements GLSurfaceView.Renderer {

      private int fps = 0;
      private long time = System.currentTimeMillis();

      private boolean stop = false;

      public MyRenderer() {
         Config.maxPolysVisible = 500;
         Config.farPlane = 1500;
         Config.glTransparencyMul = 0.1f;
         Config.glTransparencyOffset = 0.1f;
         Config.useVBO=true;
         
         Texture.defaultToMipmapping(false);
         Texture.defaultTo4bpp(true);
      }

      public void stop() {
         stop = true;
      }

      public void onSurfaceChanged(GL10 gl, int w, int h) {
         if (fb != null) {
            fb.dispose();
         }

         fb = new FrameBuffer(gl, w, h);

         if (master == null) {
            world = new World();
            Resources res = getResources();

            TextureManager tm = TextureManager.getInstance();

            Texture texture2 = new Texture(res.openRawResource(R.raw.alphatest));
            tm.addTexture("texture2", texture2);
           
            sphere1 =  Primitives.getSphere(20, 20);
            sphere1.calcTextureWrapSpherical();
            sphere1.setTexture("texture2");
           
            sphere2=sphere1.cloneObject();
            sphere3=sphere1.cloneObject();
            cube = Primitives.getCube(2);
           
            sphere2.translate(0, 0, 20);
            sphere3.translate(0, 0, 40);
           
            cube.translate(10, -40, -30);//-40
            cube.setAdditionalColor(RGBColor.GREEN);
           
            world.addObject(sphere1);
            world.addObject(sphere2);
            world.addObject(sphere3);
            world.addObject(cube);
           
           
            // Setup collision modes
            sphere1.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
            sphere2.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
            sphere3.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
           
            cube.setCollisionMode(Object3D.COLLISION_CHECK_SELF);

            world.setAmbientLight(255, 255, 255);
            world.buildAllObjects();

           
            Camera cam = world.getCamera();
            cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
            cam.moveCamera(Camera.CAMERA_MOVEUP, 60);
            cam.lookAt(sphere2.getTransformedCenter());

            MemoryHelper.compact();
           
         }
      }

      public void onSurfaceCreated(GL10 gl, EGLConfig config) {
         
         gl.glEnable(GL10.GL_BLEND);
         
         gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
      }

      public void onDrawFrame(GL10 gl) {

         try {
            if (!stop) {
               
            // Do collision dections
                SimpleVector trsn=cube.checkForCollisionEllipsoid(move, ellips, 5);
            //SimpleVector trsn=cube.checkForCollisionSpherical(move, 7);
            cube.translate(trsn);
           
            if (cube.getTranslation(tmp).z>100) {
            // Restart at the beginning...
            cube.clearTranslation();
            cube.translate(10, -40, -30);
            }
           
               fb.clear(back);
               world.renderScene(fb);
               world.draw(fb);

               fb.display();

               fps++;
               
               if (System.currentTimeMillis()-time>=1000) {
               System.out.println(fps+"fps");
               fps=0;
               time=System.currentTimeMillis();
               }
            } else {
               if (fb != null) {
                  fb.dispose();
                  fb = null;
               }
            }
         } catch (Exception e) {
            e.printStackTrace();
            Logger.log("Drawing thread terminated!", Logger.MESSAGE);
         }
      }

     
   }

}


Simdanfeg


Simdanfeg

Why is the efficiency of the program up and running so low, fps only 1 or 2, Is there any way to optimize it, the following is the information displayed in Logcat,   :(


05-21 09:25:33.636: INFO/System.out(224): 2fps
05-21 09:25:33.726: DEBUG/dalvikvm(224): GC freed 16112 objects / 519040 bytes in 177ms
05-21 09:25:33.726: INFO/System.out(224): 2fps
05-21 09:25:36.886: DEBUG/dalvikvm(224): GC freed 15199 objects / 487848 bytes in 120ms
05-21 09:25:38.426: INFO/System.out(224): 2fps
05-21 09:25:39.776: DEBUG/dalvikvm(224): GC freed 14251 objects / 457592 bytes in 244ms
05-21 09:25:40.256: INFO/System.out(224): 1fps
05-21 09:25:41.786: INFO/System.out(224): 1fps
05-21 09:25:42.906: DEBUG/dalvikvm(224): GC freed 17772 objects / 570376 bytes in 221ms
05-21 09:25:43.617: INFO/System.out(224): 1fps
05-21 09:25:45.246: INFO/System.out(224): 1fps
05-21 09:25:45.937: DEBUG/dalvikvm(224): GC freed 17038 objects / 546856 bytes in 219ms
05-21 09:25:47.056: INFO/System.out(224): 1fps

EgonOlsen

Is that from running may test case? In that case, make sure that you are using the latest beta from the "new version" thread. That test case is pretty demanding btw...that's its purpose.

Simdanfeg

yes, i know ,but i found a program from the website that 'http://www.jpct.net/wiki/index.php/Collision_detection'; running low too, how can i optimize it, hope you give me some advise or some examples , thank you. ;D

EgonOlsen

You still haven't said anything about the version you are using. Judging from the lot of garbage collections that occur, this doesn't look like the latest beta to me. Which hardware are you using btw?

Simdanfeg

 :-[, i running it on emulator, which version is 2.1-update1, i change it to 2.3.1,but running slowly too.
btw,i have a htc g1.

EgonOlsen

The emulator (as well as the G1) emulates the FPU in software. All kinds of collision detection will be very slow on these devices. That's the reason why my Alien Runner game only uses simple ray-polygon-intersection tests. There's nothing you can do about this except for using a simpler scene, doing less collision detection...or getting a faster device with an onboard FPU.

Simdanfeg

well,thanks for you answer,and maybe it is right,but its speed i can't accept ,as you know,one game running slowly(fps only 1~3) would't popular. :P

EgonOlsen

No, but then it's simply not the right kind of game/collision detection for these devices. Try Alien Runner...that's close to the maximum performance you can get from these devices (i developed it on a Samsung Galaxy (not S), which is pretty similar to the G1 performance wise. Doing ellipsoid collision detection on devices without a dedicated FPU is too slow in almost every case.

Simdanfeg

ok i know,very very grateful for your patience and answers