3D Mouse click in a box

edited December 2017 in JavaScript Mode

Hi, I created a box beginShape, endShape and vertex. I want to be able to click on each one of the sides of the box. I was able to do it by using the picking library, but because i want to use it in an html file i want to find a way to do it with no library using screenX and screen Y. Thanks

Tagged:

Answers

  • edited December 2017
    `import picking.*;
    
    Picker picker;
    
    float moveX;
    float moveY;
    float varx;
    float vary;
    float varinc;
    int id;
    
    boolean ms;
    
    void setup() {
      size(displayWidth, displayHeight, P3D);
      picker = new Picker(this);
    }
    
    void draw() {
      background(100);
      translate(width/2, height/2);
      moveCube();
      cubeNoise();
      newBox();
      choose();
    }
    
    void newBox() {
      fill(255, 0, 0);
      picker.start(0);
      beginShape();
      vertex(-100, -100, 0);
      vertex(100, -100, 0);
      vertex(100, 100, 0);
      vertex(-100, 100, 0);
      endShape();
    
      fill(0, 255, 0);
      picker.start(1);
      beginShape();
      vertex(-100, -100, 0);
      vertex(-100, -100, -200);
      vertex(-100, 100, -200);
      vertex(-100, 100, 0);
      endShape();
    
      fill(0, 0, 255);
      picker.start(2);
      beginShape();
      vertex(-100, -100, 0);
      vertex(-100, -100, -200);
      vertex(100, -100, -200);
      vertex(100, -100, 0);
      endShape();
    
      fill(120, 200, 50);
      picker.start(3);
      beginShape();
      vertex(100, -100, 0);
      vertex(100, 100, 0);
      vertex(100, 100, -200);
      vertex(100, -100, -200);
      endShape();
    
      fill(30, 180, 30);
      picker.start(4);
      beginShape();
      vertex(-100, -100, -200);
      vertex(100, -100, -200);
      vertex(100, 100, -200);
      vertex(-100, 100, -200);
      endShape();
    
      fill(200, 0, 55);
      picker.start(5);
      beginShape();
      vertex(-100, 100, 0);
      vertex(-100, 100, -200);
      vertex(100, 100, -200);
      vertex(100, 100, 0);
      endShape();
    
      picker.stop();
    }
    
    void moveCube() {
      moveX= map(mouseX, 0, width, 0, 360);
      moveY= map(mouseY, 0, height, 0, 360);
      rot();
      cubeNoise();
    }
    
    void rot() {
      rotateX(-moveY * 0.01);
      rotateY(-moveX * 0.01);
      rotateZ(frameCount*0.03);
    }
    
    void cubeNoise() {
      varx = map(noise(varinc), 0, 1, -100, 100);
      vary = map(noise(varinc), 0, 1, -100, 100);
      translate(varx, vary);
      varinc+=0.003;
    }
    
    void choose() {
      id = picker.get(mouseX, mouseY);
    
      if (mousePressed == true) {
      switch (id) {
      case 0:
        println("1st");
      case 1:
        println("2nd");
      case 2:
        println("3rd");
      case 3:
        println("4th");
      case 4:
        println("5th");
      case 5:
        println("6th");
        break;
      }
      }
    }`
    
  • Who says you can't use libraries when you have an online sketch?

    Anyway, the Picking library works by rendering the scene a second time, using false coloring so that each object with an ID has a unique color, and determining the color of the pixel at the position that was clicked, thus yielding information about what was clicked. You can do this yourself if you try hard and can render to an off-screen buffer (can P5.js do that?).

    See: https://www.openprocessing.org/sketch/7707

    If your object is a cube with a fixed rotation - only around the Y axis, say - You might be able to get the screenX and screenY positions of the four corners, and then determine if the mouse's screenX and screenY is withing the quad those four corners define. You would have to take the rotation amount of the box into consideration too, however, because there would be no way to tell if you clicked the front face or the back face of the cube (unless you numbered the corners too and knew when a face was showing... hmm...)

  • THanks @TfGuy44.

    Who says you can't use libraries when you have an online sketch?

    How can I?

  • Thanks @GoToLoop,

    My question is how do i get the coordinates of the shapes while they rotating and translating?

  • Not good at trigonometry, sorry.
    I just wanted to call the attention that Pjs got screenX() too.
    So you can attempt to convert your library and have it working on the web:
    http://ProcessingJS.org/

  • @yanivasaf - @TfGuy44 's suggestion is a good one; but it looks like you're already applying a different colour to each face so you shouldn't even need an off-screen buffer or the Picker library. Try using get() to get the pixel value at the mouse coordinates (and not picker.get()). Check the returned colour's RGB values against the colour of each face. If you have a match then you've registered a hit on that face ;)

    Note: if you were to apply any kind of 3d lighting you wouldn't get an exact match and colour checking would become complex; or if you wanted the same colour on all faces you would obviously not be able to use this approach directly. It's then that you would draw a duplicate 3D object to a buffer (using PGraphics) where you would render flat colours and a different colour for each hit area and use myPGraphicsBuffer.get() instead.

    And this is much simpler than any mathematical approach to hit detection since the 3d renderer has already solved the issue of 'depth perception': the closest faces will always be drawn on top of the rear faces...

Sign In or Register to comment.