Picking in 3D (PGraphicsOpenGL+ PShape + Peasycam)

Hello all,

I want to do picking in 3D on a wall size screen. I am using OPENGL as the renderer and I don't want to use Shape3D library. Recently I found the discussion between Chrisir and quark, which is very helpful. But the resolution greatly reduces the frameRate when I draw 100+ spheres on the screen. How can I modify the code to keep the frameRate around 60 fps? Thank you all in advance!

import processing.opengl.*;
import peasy.*; 
PeasyCam cam;

int nCircles = 100;
Circle circles[] = new Circle[nCircles];

Circle picked = null;
PGraphicsOpenGL pg;


void setup() 
{
  size(800, 600, OPENGL);
  cam = new PeasyCam(this, 200);

  for (int i = 0; i < circles.length; i++) 
  {
    circles[i] = new Circle("" + (i+1), color_2(), 0xff000000 + i, new PVector(random(-80, 80), random(-80, 80), random(-80, 80)));
  }
  pg = (PGraphicsOpenGL)createGraphics(width, height, OPENGL);
}


void draw() 
{
  background(0);
  frame.setTitle(int(frameRate) + " fps");

  pushMatrix();
    lights(); 
    picked = pickCube(mouseX, mouseY);
    for (int i = 0; i < circles.length; i++)  circles[i].render();

    if (picked != null) 
    {    
      picked.col = color_1();

      cam.beginHUD();  
      fill(255);
      textSize(20);
      text(picked.myTitle, 20, 20);
      cam.endHUD();
    }
    else
    {
      for (int i = 0; i < circles.length; i++)  circles[i].col = color_2();
    }  
  popMatrix(); 
}


int color_1() 
{
  return color(255,0,0);
}
int color_2() 
{
  return color(0,255,0);
}


Circle pickCube(int x, int y) 
{
  Circle 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 < circles.length; i++)  circles[i].displayForPicker(); 
  int c = pg.get(x, y);
  pg.endDraw();

  for (int i = 0; i < circles.length; i++) 
  {
    if (circles[i].pickCol == c) 
    {
      cube = circles[i];
      break;
    }
  }
  return cube;
}


class Circle 
{
  float sphereSize_1;
  String myTitle;
  PShape mySphere_1, mySphere_1pg;
  int col, pickCol;
  PVector pos;

  Circle(String _myTitle, int _col, int _pickCol, PVector _pos) 
  {
    this.pos = _pos;   
    this.myTitle = _myTitle;   
    this.sphereSize_1 = 4;
    this.mySphere_1 = createShape(SPHERE, this.sphereSize_1);    
    this.mySphere_1pg = createShape(SPHERE, this.sphereSize_1);
    this.col = _col;
    this.pickCol = _pickCol;   
  }

  void render() 
  {
    mySphere_1.setFill(color(col));
    mySphere_1.setStroke(false);

    pushMatrix();
      translate(this.pos.x, this.pos.y, this.pos.z);
      shape(mySphere_1); 
    popMatrix();

    fill(255, 80);
    textSize(10);
    text(this.myTitle, pos.x + 8, pos.y, pos.z);
  }

  void displayForPicker() 
  {
    mySphere_1pg.setFill(color(pickCol));
    mySphere_1pg.setStroke(false);  

    pg.pushMatrix();
      pg.translate(this.pos.x, this.pos.y, this.pos.z);
      pg.shape(mySphere_1pg); 
    pg.popMatrix();  
  }
}
Sign In or Register to comment.