Picking 3D without lib - but peasyCam and lights() - wth?

edited May 2016 in How To...

hello all,

simple question, but I couldn't find anything about it.

I want to do a Picking with 3D boxes.

I don't want to use the shapes lib.

All boxes have different colors, So I just wanted to take the color via get(mouseX, mouseY), bu I realized that doesn't work since I use lights().

Then I decided to draw everything in a second PGraphics and do the get(mouseX, mouseY) there - but since I use peasyCam, the boxes on the screen and in PGraphics don't match. So it doesn't work.

So my question here is: How can I do a picking without lib but with lights() and peasyCam in use?

Or in other words: How can I impose peasyCam on my PGraphics?

(or can I use modelX etc. and use it to paint my boxes in my PGraphics?)

Thank you all!

Greetings, Chrisir ;-)

  • part of my class:

    void display() {

    noStroke();
    stroke(0);
    fill(boxFillColor);
    
    if (selected) {  // only outline
      noFill();
      strokeWeight(2);
      stroke(boxFillColor);
    }
    
    if (allNoFill) { // only outline
      noFill();
      strokeWeight(2);
      stroke(boxFillColor);
    }
    
    //pg.beginDraw();
    pg.pushMatrix();
    pg.fill(boxFillColor);
    pg.noStroke();
    pg.translate (Position.x, Position.y, Position.z);
    pg.box ( boxSize.x );
    pg.popMatrix();
    // pg.endDraw();
    
    // the box
    pushMatrix(); 
    translate (Position.x, Position.y, Position.z);
        box ( boxSize.x ); 
    
        popMatrix();
    
    }
    
Tagged:

Answers

  • edited June 2014

    The answer is to copy the drawing matrix from the visible surface to the buffer then switch off lights etc before drawing to the buffer. This can be seen in the Shape3D class pickShape method (line 169)

  • edited June 2014

    @ quark: would that work also with peasyCam?

  • I think so but I am not in a position to test it at the moment. I suggest you install the Shapes3D library and modify the shape picking example (remove the rotation code) and add PeasyCam.

    If the pickShape method works then there's your answer :)

    Test the pickShape method from draw() if that doesn't work try it from the mouseReleased() method.

  • edited June 2014

    ok, thanks a lot!

    ;-)

  • edited June 2014

    Its a pain, doesn't work at all....

    how can I impose the peasyCam values on the PGraphicsOpenGL var please?

  • Answer ✓

    There are no comments in the code below but it should make sense. Each cube has two colours the display colour and the pick colour. This allows you to change the display colour without affecting the picking process and also means cubes with the same display colour can be distinguished.

    HTH

    import peasy.test.*;
    import peasy.org.apache.commons.math.*;
    import peasy.*;
    import peasy.org.apache.commons.math.geometry.*;
    
    Cube[] cubes;
    Cube picked = null;
    int nbrCubes = 10;
    boolean clicked = false;
    
    PGraphicsOpenGL pg;
    PeasyCam pcam;
    
    void setup() {
      size(400, 400, P3D);
      cursor(CROSS);
      pg = (PGraphicsOpenGL)createGraphics(width, height, OPENGL);
    
    
      cubes = new Cube[nbrCubes];
    
      for (int i = 0; i < cubes.length; i++) {
        cubes[i] = new Cube("Box " + (i+1), randomColor(), 0xff000000 + i);
      }
      pcam = new PeasyCam(this, 200);
    }
    
    void draw() {
      background(128);
      pushMatrix();
      lights();
      for (int i = 0; i < cubes.length; i++)
        cubes[i].display();
      popMatrix();
    
      if (clicked) {
        clicked = false;
        picked = pickCube(mouseX, mouseY);
        if (picked != null) {
          picked.col = randomColor();
          println(picked.tag);
        }
      }
    }
    
    
    Cube pickCube(int x, int y) {
      Cube cube = null;
      pg.beginDraw();
      pg.camera.set(((PGraphicsOpenGL)g).camera);
      pg.projection.set(((PGraphicsOpenGL)g).projection);
      pg.noLights();
      pg.noStroke();
      pg.background(255);
      for (int i = 0; i < cubes.length; i++)
        cubes[i].displayForPicker();
      int c = pg.get(x, y);
      pg.endDraw();
      for (int i = 0; i < cubes.length; i++) {
        if (cubes[i].pickCol == c) {
          cube = cubes[i];
          break;
        }
      }
      return cube;
    }
    
    void mouseClicked() {
      clicked = true;
    }
    
    int randomColor() {
      return color(random(100, 255), random(100, 255), random(100, 255));
    }
    
    public class Cube {
      String tag;
      PVector pos = new PVector(random(-50, 50), random(-50, 50), random(-50, 50));
      float size = random(5.0, 20);
      int col;
      int pickCol;
    
      public Cube(String name, int col, int pickCol) {
        tag = name;
        this.col = col;
        this.pickCol = pickCol;
      }
    
      public void display() {
        pushMatrix();
        translate(pos.x, pos.y, pos.z);
        noStroke();
        fill(col);
        box(size);
        popMatrix();
      }
    
      public void displayForPicker() {
        pg.pushMatrix();
        pg.translate(pos.x, pos.y, pos.z);
        pg.noStroke();
        pg.fill(pickCol);
        pg.box(size);
        pg.popMatrix();
      }
    }
    
  • hi dear quark,

    thanks a ton. I'll try tonight.

    Thank you very much!

    Chrisir

  • it works now, I had a stupid mistake somewhere else...

    took me all night

    thanks a ton!

Sign In or Register to comment.