Author Topic: [ resolved ] picking of Object3D  (Read 899 times)

Offline cefengxu

  • int
  • **
  • Posts: 65
    • View Profile
[ resolved ] picking of Object3D
« on: December 02, 2015, 10:36:00 am »
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 :

 
Code: [Select]
     // 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 :

Code: [Select]
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
« Last Edit: December 14, 2015, 08:03:19 am by cefengxu »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11770
    • View Profile
    • http://www.jpct.net
Re: [ resolving ] picking of Object3D
« Reply #1 on: December 02, 2015, 12:49:43 pm »
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

Offline cefengxu

  • int
  • **
  • Posts: 65
    • View Profile
Re: [ resolving ] picking of Object3D
« Reply #2 on: December 04, 2015, 10:13:56 am »
thanks man , even i still can not solve it . i will try again in these day.  :'(

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11770
    • View Profile
    • http://www.jpct.net
Re: [ resolving ] picking of Object3D
« Reply #3 on: December 04, 2015, 04:12:28 pm »
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.

Offline cefengxu

  • int
  • **
  • Posts: 65
    • View Profile
Re: [ resolving ] picking of Object3D
« Reply #4 on: December 11, 2015, 10:06:13 am »
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:

Code: [Select]
@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];

}

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11770
    • View Profile
    • http://www.jpct.net
Re: [ resolving ] picking of Object3D
« Reply #5 on: December 11, 2015, 10:31:58 am »
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).

Offline cefengxu

  • int
  • **
  • Posts: 65
    • View Profile
Re: [ resolving ] picking of Object3D
« Reply #6 on: December 14, 2015, 08:03:09 am »
cool ~ got it !
Have to delete Title Bar completely and show the OpenGL Render View only.

Offline cefengxu

  • int
  • **
  • Posts: 65
    • View Profile
Re: [ resolved ] picking of Object3D
« Reply #7 on: December 14, 2015, 08:03:30 am »
thanks~!

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11770
    • View Profile
    • http://www.jpct.net
Re: [ resolving ] picking of Object3D
« Reply #8 on: December 14, 2015, 08:09:51 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...