Hi master :
i want to know the model do some reply when i touch it on the screen, so i use the Picking of jpct-ae to realized it.
example
i add a cube with six diff. faces and add setCollisionMode respectively :
// Front
front = new Object3D(2);
front.addTriangle(upperLeftFront,0,0, lowerLeftFront,0,1, upperRightFront,1,0, TextureManager.getInstance().getTextureID("frontt"));
front.addTriangle(upperRightFront,1,0, lowerLeftFront,0,1, lowerRightFront,1,1,TextureManager.getInstance().getTextureID("frontt"));
cube.addChild(front);
world.addObject(front);
front.setCollisionMode( Object3D.COLLISION_CHECK_SELF);
// Back...
// Upper...
// Lower...
// Left...
// Right ...
cube.strip();
cube.build();
world.addObject(cube);
cube.setCulling(false);
cube.scale( 0.05f);
cube.setCollisionMode( Object3D.COLLISION_CHECK_SELF);
and then , i use the touch event to know which face was triggered when i touched the screen :
public int Pickint( int fX, int fY){
//fY = fb.getHeight() - fY;
SimpleVector dir = Interact2D.reproject2D3DWS( cam, fb, fX, fY).normalize();
Object[] res=world.calcMinDistanceAndObject3D(cam.getPosition(), dir, 10000 );
Object3D picked = (Object3D)res[1];
Object3D picked = (Object3D)res[1];
if( picked == null){
return -1;
}
if( picked.getID() == front.getID())
Log.i("jpctae", "touch front");
else if( picked.getID() == back.getID())
Log.i("jpctae", "touch back");
else if( picked.getID() == upper.getID())
Log.i("jpctae", "touch upper");
else if( picked.getID() == lower.getID())
Log.i("jpctae", "touch lower");
else if( picked.getID() == left.getID())
Log.i("jpctae", "touch left");
else if( picked.getID() == right.getID())
Log.i("jpctae", "touch right");
return 1;
}
However, the questions is :
1- the picked.getID() output only have some respond when i touch the top left corner of every face of cube.
2- or some time the picked always = null
The first thing to keep in mind is, that one "face" doesn't mean one polygon. Each side of your cube consists of 2 polygons. In your code, you seem to pick only the first one (or whatever...I'm not sure where you got these IDs from).
The other thing, especially on Android is that the framebuffer coordinates don't match the touch coordinates because of some title bars. More info here: http://www.jpct.net/forum2/index.php/topic,2191.msg16277.html#msg16277 (http://www.jpct.net/forum2/index.php/topic,2191.msg16277.html#msg16277)
thanks man , even i still can not solve it . i will try again in these day. :'(
It might help to check for Object3D.COLLISION_NONE as first array element to see, if you actually has a collision or not. Just to see if your polygon detection is wrong or simple the picking doesn't return anything.
hi master:
i have spent lots of time to try it but got some strange result.
the faces of cube just valid at some part , as the attached shown.
my test code is every simple , i think it's correct absolutely:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
glViewport(0, 0, width, height);
fb = new FrameBuffer( width, height); // OpenGL ES 1.x constructor
world = new World();
sun = new Light(world);
sun.setIntensity(200, 20, 200);
loadOBJ("cube.obj" , "cube.mtl" , "cube_triangle.png");
cubeColor.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
world.addObject(cubeColor);
cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(cubeColor.getTransformedCenter());
sv.set(cubeColor.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;
sun.setPosition(sv);
MemoryHelper.compact();
}
@Override
public void onDrawFrame(GL10 gl) {
glClear(GL_COLOR_BUFFER_BIT);
if (touchTurn != 0) {
cubeColor.rotateY(touchTurn);
touchTurn = 0;
}
if (touchTurnUp != 0) {
cubeColor.rotateX(touchTurnUp);
touchTurnUp = 0;
}
if (actionEventDown_x != -1) {
SimpleVector dir= Interact2D.reproject2D3DWS(cam, fb, (int)actionEventDown_x, (int)actionEventDown_y).normalize();
Object[] res = world.calcMinDistanceAndObject3D(cam.getPosition(), dir, 10000 /*or whatever*/);
actionEventDown_x = -1;
actionEventDown_y = -1;
if(res[1] != null){
Log.i("jPCT_Picking", "res[0]="+res[0]+" , res[1]="+res[1]);
}
}
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++;
}
private InputStream mod = null;
private InputStream mtl = null;
private Object3D cubeColor = null;
private Object3D[] other = null;
public void loadOBJ(String strObjFileName, String strMtlFileName , String strTexFileName) {
try {
mod = this.context.getAssets().open(strObjFileName);
mtl = this.context.getAssets().open(strMtlFileName);
TextureManager.getInstance().addTexture(strTexFileName, new Texture(context.getAssets().open(strTexFileName)));
} catch (Exception e) {
e.printStackTrace();
}
other = Loader.loadOBJ(mod, mtl,10.0f);
cubeColor = other[0];
}
It's most likely caused by what I mentioned above:
Quote
The other thing, especially on Android is that the framebuffer coordinates don't match the touch coordinates because of some title bars.
You have to take the title bar into account when giving the screen coordinates to the reproject-method (you can obtain the dimensions somehow from the Android API, I don't remember the exact call but google will be your friend).
cool ~ got it !
Have to delete Title Bar completely and show the OpenGL Render View only.
thanks~!
Quote from: cefengxu on December 14, 2015, 08:03:09 AM
cool ~ got it !
Have to delete Title Bar completely and show the OpenGL Render View only.
That's one way. The other would have been to query the title bar about its dimensions and add the height to the touch coordinates. Anyway, do whatever works best for you...