» codelab : http://codelab.fr/accueil » Forum : Processing : http://codelab.fr/processing » sélection d'objets avec la souris dans environnement 3D : http://codelab.fr/4104 Ceci est la version imprimable d'un sujet du forum, pour retourner à la version complète : sélection d'objets avec la souris dans environnement 3D |
Marty — 2013-03-03 12:39:57 |
Hello ! Led[] ledCube = new Led[64]; // detection tollerance for mouse hovering led int tollerance = 5; float ledPosArray[][]; // coordinates of leds on screen (see method for use) int cubeSize = 150; // widht and height of window int wWidth = 640; int wHeight = 480; // scene center int cx = wWidth/2; int cy = wHeight/2; int cz = -cubeSize/2; // camera positions float camEyeX = 0; float camEyeY = 0; float camEyeZ = 0; float viewX = 0; float viewY = 0; float viewZ = 0; float camUpX = 0; float camUpY = 1; float camUpZ = 0; // Polar coordinates for camera float theta = 0; float phi = 90; float rho = 300; //distance from cam to point of view void setup(){ int c = 0; // counter = number of leds ledPosArray = new float[64][2]; // init screen coordinates array for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { ledCube[c] = new Led(j,-i,-k, false, 120, col, i+1); c++; } } } size(wWidth,wHeight, P3D); } void draw(){ background(0); pointLight(150,255,255,200,200,200); noLights(); noStroke(); noSmooth(); fill(160); drawAxis(); // debug updateCamPosition(); camera(camEyeX,camEyeY,camEyeZ,viewX,viewY,viewZ,camUpX,camUpY,camUpZ); translate(-(cubeSize / 2), (cubeSize / 2), (cubeSize / 2)); updateArray(); // update coordinates of spheres on screen for mouse hover detection box(8); // debug : identifies start point for the construction of the cube drawCube(); } // One Led (sphere) of the cube and its properties class Led { int x; int y; int z; boolean isOn; // true when led is lit boolean isHover = false; // true when mouse hover color ledColor; int activeCol; // columns 1 to 16 (in dev, not used yet) int activePlan; // number of cube active plan where the Led belongs (1 low level to 4 high level) (in dev, not used yet) // constructor Led (int xPos, int yPos, int zPos, boolean state, color col, int column, int line) { x = xPos; y = yPos; z = zPos; isOn = state; // Led On/Off ledColor = col; activeCol = column; // position of LED in cube (x and z axis) (in dev, not used yet) activePlan = line; // position of LED in cube (plane = y axis) (in dev, not used yet) } // Led display method void display() { pushMatrix(); translate(x * (cubeSize / 3), y * (cubeSize / 3), z * (cubeSize / 3)); if (isOn) { fill(color(0,0,255)); } else if (isHover) { fill(color(255,0,0)); } else { fill(color(166,166,166)); } box(4); popMatrix(); } } // for debug : draw axis x (green), y (blue) and z (red) void drawAxis(){ stroke(0,255,0); line(0,0,0,100,0,0); stroke(0,0,255); line(0,0,0,0,100,0); stroke(255,0,0); line(0,0,0,0,0,-100); noStroke(); } // draw cube with spheres void drawCube() { for (int i = 0; i < 64; i++) { ledCube[i].display(); } } // calculate x and y screen : list[led_number][coordinates] with coordinates = 0 (x) and 1 (y) void updateArray(){ for (int i = 0; i < 64; i++) { ledPosArray[i][0] = (int)screenX(ledCube[i].x,ledCube[i].y,ledCube[i].z); ledPosArray[i][1] = (int)screenY(ledCube[i].x,ledCube[i].y,ledCube[i].z); } } // update position of camera moved with mouse click and drag void updateCamPosition(){ camEyeX = rho * cos(radians(theta)) * cos(radians(phi)); camEyeY = rho * sin(radians(theta)); camEyeZ = rho * cos(radians(theta)) * sin(radians(phi)); //Prevent flipping if camera moves past top or bottom of cube if ((theta > 90.0 && theta < 270.0) || (theta < -90.0 && theta > -270.0)) { camUpY = -1.0; } else { camUpY = 1.0; } } // colorize spheres when mouse hover or selected void mousePressed() { for (int i=0 ; i < 64 ; i++) { if (ledCube[i].isHover && !ledCube[i].isOn) ledCube[i].isOn = true; else if (ledCube[i].isHover && ledCube[i].isOn) ledCube[i].isOn = false; } } // rotate camera whith mouse click and drag void mouseDragged(){ if (mouseButton == LEFT){ theta = theta + (pmouseY - mouseY); phi = phi - (pmouseX - mouseX); } if (mouseButton == RIGHT){ rho = rho - (pmouseY - mouseY); } } // detects mouse hover and change state void mouseMoved() { for (int i=0 ; i < 64 ; i++) { if (mouseX >= ledPosArray[i][0] - tollerance && mouseX <= ledPosArray[i][0] + tollerance && mouseY >= ledPosArray[i][1] - tollerance && mouseY <= ledPosArray[i][1] + tollerance) //if (mouseX >= ledCube[i].x - tollerance && mouseX <= ledCube[i].x + tollerance && mouseY >= ledCube[i].y + tollerance && mouseY <= ledCube[i].y - tollerance) { ledCube[i].isHover = true; } else ledCube[i].isHover = false; } } |
Mushussu — 2013-03-03 14:00:28 |
Bonjour, Led[] ledCube = new Led[64]; int cubeSize = 150; int wWidth = 640; int wHeight = 480; //camera positions float camEyeX = 0; float camEyeY = 0; float camEyeZ = 0; float viewX = 0; float viewY = 0; float viewZ = 0; float camUpX = 0; float camUpY = 1; float camUpZ = 0; //Polar coordinates float theta = 0.01; float phi = 90; float rho = 300; //distance from cam to point of view void setup() { size(wWidth, wHeight, P3D); int c = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { ledCube[c] = new Led(j, -i, -k, false, 120); c++; } } } ledCube[0].bColor = color(255, 255, 255); ledCube[12].bColor = color(255, 0, 0); ledCube[48].bColor = color(0, 255, 0); ledCube[60].bColor = color(0, 0, 255); noLights(); noStroke(); noSmooth(); } void draw() { background(0); //pointLight(150, 255, 255, 200, 200, 200); testCube(); fill(160); drawAxis(); updateCamPosition(); camera(camEyeX, camEyeY, camEyeZ, viewX, viewY, viewZ, camUpX, camUpY, camUpZ); translate(-(cubeSize / 2), (cubeSize / 2), (cubeSize / 2)); drawCube(); } void testCube() { pushMatrix(); translate(-(cubeSize / 2), (cubeSize / 2), (cubeSize / 2)); for (int i = 0; i < 64; i++) { ledCube[i].display(64 + i * 2); } if (mousePressed) { int c = ((int)brightness(get(mouseX, mouseY)) - 64) / 2; if ((c >= 0) && ( c < 64)) { ledCube[c].setEtat(); } } popMatrix(); } class Led { int x; int y; int z; boolean isOn; color bColor; Led (int xPos, int yPos, int zPos, boolean state, color col) { x = xPos; y = yPos; z = zPos; isOn = state; bColor = col; } void display() { pushMatrix(); translate(x * (cubeSize / 3), y * (cubeSize / 3), z * (cubeSize / 3)); if (isOn) { fill(255, 0, 0); } else { fill(bColor); } box(3); popMatrix(); } void display(int niveauGris) { pushMatrix(); translate(x * (cubeSize / 3), y * (cubeSize / 3), z * (cubeSize / 3)); fill(niveauGris); box(3); popMatrix(); } void setEtat() { isOn = !isOn; } } void drawAxis() { stroke(0, 255, 0); line(0, 0, 0, 100, 0, 0); stroke(0, 0, 255); line(0, 0, 0, 0, 100, 0); stroke(255, 0, 0); line(0, 0, 0, 0, 0, -100); noStroke(); } void drawCube() { for (int i = 0; i < 64; i++) { ledCube[i].display(); } } void updateCamPosition() { camEyeX = rho * cos(radians(theta)) * cos(radians(phi)); camEyeY = rho * sin(radians(theta)) ; camEyeZ = rho * cos(radians(theta)) * sin(radians(phi)); //Prevent flipping if camera moves past top or bottom of cube if ((theta > 90.0 && theta < 270.0) || (theta < -90.0 && theta > -270.0)) { camUpY = -1.0; } else { camUpY = 1.0; } } void mouseDragged() { if (mouseButton == LEFT) { theta = theta + (pmouseY - mouseY); println(theta); phi = phi - (pmouseX - mouseX); } if (mouseButton == RIGHT) { rho = rho - (pmouseY - mouseY); } } Il permet de cliquer sur les cubes. Il faudrait l'améliorer et mette une petite temporisation pour éviter le déselectionnement rapide. |
Marty — 2013-03-03 14:21:17 |
Salut, |
Mushussu — 2013-03-03 23:07:30 |
Attention dans ton calcul de la projection des coordonnées, tu ne prenais pas les coordonnées d'affichage. Dans le tableau ledCube les coordonnées sont celles du cube par rapport aux autres de 0 à 3. C'est dans l'affichage que l'on transforme en coordonnées d'affichage. Donc la fonction est la suivante : void updateArray(){ for (int i = 0; i < 64; i++) { ledPosArray[i][0] = (int)screenX(ledCube[i].x * (cubeSize / 3), ledCube[i].y * (cubeSize / 3), ledCube[i].z * (cubeSize / 3) ); ledPosArray[i][1] = (int)screenY(ledCube[i].x * (cubeSize / 3), ledCube[i].y * (cubeSize / 3), ledCube[i].z * (cubeSize / 3) ); } } |
cgiles — 2013-03-04 08:07:53 |
as tu regardé comment marchais le picking ? |
Mushussu — 2013-03-04 08:45:54 |
J'ai utilisé cette méthode de picking dans le bout de code proposé. Le voici avec le survol des cubes actif et la temporisation : Si il y a des passages abscons, dit le moi. |
Marty — 2013-03-04 12:14:33 |
Elémentaire mon cher Watson !! |