Problem with Camera - Object collision

Started by indigo, October 27, 2011, 07:26:54 PM

Previous topic - Next topic

indigo

Hi,
First to introduce myself: I'm new here. Wowzah.

I did install JPCT-AE today and downloaded the basic example code, and I was able to compile and run it in the emulator. I then wanted to build a bit more around that barebone. I intended to make the camera moveable and colliding with objects.

I added/changed the following parts of the main class (just toying around):
onKeyDown (in HelloWorld) public boolean onKeyDown(int kc, KeyEvent e) {

if (kc == KeyEvent.KEYCODE_DPAD_UP) {
if (world.checkCameraCollision(Camera.CAMERA_MOVEIN, 2.f)) {
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Collision");
alertDialog.setMessage("Happens.");
alertDialog.show();
}

} else if (kc == KeyEvent.KEYCODE_DPAD_DOWN) {
        world.checkCameraCollision(Camera.CAMERA_MOVEOUT, 2.f);
} else {
                        return false;
                }

return true;

}

in onSurfaceChanged (in MyRenderer) cube = Primitives.getSphere(10); //ik...
cube.calcTextureWrapSpherical();
cube.setTexture("texture");
cube.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
cube.strip();
cube.build();

Of course I also did the necessary import for the AlertDialog.

Yet it doesn't work: I get neither an AlertDialog nor does the camera stop when it hits the sphere.

Is my code wrong and can you help me correct it or am I going entirely the wrong way?

Thanks!

EgonOlsen

Adding your changes to the original HelloWorld-example, the collision happens as it should. Here's my version of it:


package com.threed.jpct.example;

import java.lang.reflect.Field;

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.app.AlertDialog;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
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.BitmapHelper;
import com.threed.jpct.util.MemoryHelper;

/**
* A simple demo. This shows more how to use jPCT-AE than it shows how to write
* a proper application for Android. It includes basic activity management to
* handle pause and resume...
*
* @author EgonOlsen
*
*/
public class HelloWorld extends Activity {

// Used to handle pause and resume...
private static HelloWorld 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 float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Object3D cube = null;
private int fps = 0;

private Light sun = null;

protected void onCreate(Bundle savedInstanceState) {

Logger.log("onCreate");

if (master != null) {
copy(master);
}

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);
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
}

private void copy(Object src) {
try {
Logger.log("Copying data from master Activity!");
Field[] fs = src.getClass().getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
f.set(this, f.get(src));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public boolean onTouchEvent(MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

@Override
public boolean onKeyDown(int kc, KeyEvent e) {

if (kc == KeyEvent.KEYCODE_DPAD_UP) {
if (world.checkCameraCollision(Camera.CAMERA_MOVEIN, 2.f)) {
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Collision");
alertDialog.setMessage("Happens.");
alertDialog.show();
}

} else if (kc == KeyEvent.KEYCODE_DPAD_DOWN) {
world.checkCameraCollision(Camera.CAMERA_MOVEOUT, 2.f);
} else {
return false;
}

return true;

}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
}

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();
world.setAmbientLight(20, 20, 20);

sun = new Light(world);
sun.setIntensity(250, 250, 250);

// Create a texture out of the icon...:-)
Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
TextureManager.getInstance().addTexture("texture", texture);

cube = Primitives.getSphere(10); // ik...
cube.calcTextureWrapSpherical();
cube.setTexture("texture");
cube.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
cube.strip();
cube.build();

world.addObject(cube);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(cube.getTransformedCenter());

SimpleVector sv = new SimpleVector();
sv.set(cube.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;
sun.setPosition(sv);
MemoryHelper.compact();

if (master == null) {
Logger.log("Saving master Activity!");
master = HelloWorld.this;
}
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
cube.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
cube.rotateX(touchTurnUp);
touchTurnUp = 0;
}

fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}
}

indigo

Erm, sorry. Ostensibly I ran an old build or something (it worked now after I restarted the emulator).

Thanks for your time though!

EgonOlsen

No problem. Just keep in mind that the ellipsoid collision detection is better suited for most kinds of camera collisions than the ray/polygon-approach is that you are currently using.