Switch mouse control between PeasyCam and just 3d mode [solved]

Hello there. This is my first post on this forum. I am using PeasyCam in my code and the problem is that I want to click on one of the spheres and draw a 3d curve continuously from it to the second sphere (and so cut the curve by clicking on the second sphere). But, It seems that PeasyCam has a huge control over mouse. So, the question is that how can I switch off the control of mouse from PeasyCam, draw the curve, and give the control of the mouse back to PeasyCam?

import peasy.*;
PeasyCam cam;

void setup() {
  size(500, 500, P3D);
  cam = new PeasyCam(this, 500);
}

void draw() { 
  background(255);
  
  translate(100, 100, 0);
  noStroke();
  lights();
  fill(0, 0, 255);
  sphere(5);
  
  translate(-40, -40, 0);
  noStroke();
  lights();
  fill(0, 0, 255);
  sphere(5);
}
1 Like

you can use setActive

public void setActive(boolean active)

like cam.setActive(false); or true

1 Like

Thank You Chrisir. I add these lines to the code. But, I mixed up with coordinates. My goal is to click on spheres and get their coordinates.

  if(keyPressed) {
    if (key == 'a' || key == 'A') {
      cam.setActive(false);
    }
    else {
      if (key != 'a' || key != 'A') {
        cam.setActive(true);
        
    // get 3d spital coordinates of spheres and draw a curve between them with mouse.  
        
      }
    }
  }

Okay the stopping of the Peasycam works?

Next step is

screenX()

Takes a three-dimensional X, Y, Z position and returns the X value for where it will appear on a (two-dimensional) screen

This is useful to get the screen position of the center
of sphere.

Then you can use dist() as if it where 2D to find out whether the mouse is on it or not.

See https://processing.org/reference


The 3D coordinates of the spheres are given in the translate(). So there you have the coordinates.

Do you want to drag the spheres?

1 Like

Hey and welcome to the forum! Great to have you here!

A curve as opposed to a straight line is not totally easy I guess…

I have several ideas for example collect the mouse positions in an ArrayList and use curveVertex (edited: not curvepoints) to display it. But since you draw in 3D space with a 2D mouse the points will be unexpected in their position.

The z position is trivial. Use lerp().


I don’t know how it works out, post your progress here.

Thanks again. Yes, the stopping of the PeasyCam works. I’m newbie to Processing, but totally enthusiastic. I’ll go ahead on your hints. My basic strategy about joining the spheres was a kind of extension of this snippet to 3d:

  if (mousePressed == true) {
    line(mouseX, mouseY, pmouseX, pmouseY);

But, based on your explanations it seems that there are some expectations between 2d coordinates and 3d.

No, I don’t want to drag them. I want to just join them with an arbitrary curve using mouse.

you can use a to switch cam off

and click spheres, 1 or 2 gets printlnd



import peasy.*;
PeasyCam cam;

PVector pvSphere2D1, pvSphere2D2; 

// ----------------------------------------------------------

void setup() {
  size(500, 500, P3D);
  cam = new PeasyCam(this, 500);
}

void draw() { 
  background(255);

  if (keyPressed) {
    if (key == 'a' || key == 'A') {
      cam.setActive(false);
    } else {
      if (key != 'a' && key != 'A') {
        cam.setActive(true);

        // get 3d spital coordinates of spheres and draw a curve between them with mouse.
      }
    }
  }

  pushMatrix(); // new
  pvSphere2D1=new PVector(screenX(100, 100, 0), screenY(100, 100, 0)); 
  translate(100, 100, 0);
  noStroke();
  lights();
  fill(0, 0, 255);
  sphere(65);
  popMatrix(); // new

  pushMatrix(); // new
  pvSphere2D2=new PVector(screenX(-40, -40, 0), screenY(-40, -40, 0)); 
  translate(-40, -40, 0);
  noStroke();
  lights();
  fill(0, 255, 255);
  sphere(65);
  popMatrix(); // new
}

void mousePressed() {
  // println("A");
  if (pvSphere2D1.dist(new PVector(mouseX, mouseY)) < 64) 
    println("1");
  if (pvSphere2D2.dist(new PVector(mouseX, mouseY)) < 64) 
    println("2");
}
//

Hello,

you need to click the mouse on the center of a sphere and start dragging the mouse and release later

this version works but only when you haven’t moved peasycam before (or double click it prior to drawing)

this line is to blame:

list.add(new PVector(mouseX-width/2, mouseY-height/2, lerp( 60, 0, amt ) ));

maybe a guru like @GoToLoop can be so kind to explain how to
retrieve the Matrix set by peasyCam and change the line in a way that the
mouse position reflects the matrix of the cam.

I can’t find gotoloop’s post with peasycam Matrix.

Remark
(((
It also reminds me of

// kind of similar (not really)
// see https://discourse.processing.org/t/pro-question-place-a-point-in-3d-with-mouse/6664/3
// see https://discourse.processing.org/t/p3d-formula-opposite-of-screenx-and-screeny-is/10121/2

))

Greetings,

Chrisir




// get 3d spital coordinates of spheres and draw a curve between them with mouse.

// doesn't work because of peasyCam 

// kind of similar (not really)
// see https://discourse.processing.org/t/pro-question-place-a-point-in-3d-with-mouse/6664/3
// see https://discourse.processing.org/t/p3d-formula-opposite-of-screenx-and-screeny-is/10121/2


import peasy.*;
PeasyCam cam;

// 2D coordinates on screen for both spheres
PVector pvSphere2D_Number1, pvSphere2D_Number2; 

// dragging yes/no
boolean mouseDown=false;

// list 
ArrayList<PVector> list = new ArrayList();

// ----------------------------------------------------------

void setup() {
  size(1500, 500, P3D);
  cam = new PeasyCam(this, 500);
}

void draw() { 
  background(255);

  if (keyPressed) {
    if (key == 'a' || key == 'A') {
      cam.setActive(false);
    } else if (key==' ') {
      list.clear();
    } else if (key != 'a' && key != 'A') {
      // hit another key than a to make cam active again
      cam.setActive(true);
    }
  }//if

  // show 2 spheres 

  pushMatrix(); // new
  pvSphere2D_Number1=new PVector(screenX(300, 100, 60), screenY(300, 100, 60)); 
  translate(300, 100, 60);
  noStroke();
  lights();
  fill(0, 0, 255);
  sphere(65);
  popMatrix(); // new

  pushMatrix(); // new
  pvSphere2D_Number2=new PVector(screenX(140, 140, 0), screenY(140, 140, 0)); 
  translate(140, 140, 0);
  noStroke();
  lights();
  fill(0, 255, 255);
  sphere(65);
  popMatrix(); // new

  // During mouse down (dragging) we record the points 
  if (mouseDown) {
    float amt = 0.5; // map( dist( mouseX,mouseY,  ) ); 
    list.add(new PVector(mouseX-width/2, mouseY-height/2, lerp( 60, 0, amt ) ));
  }

  // display the recorded points 
  beginShape(); 
  noFill(); 
  stroke(255, 0, 0); 
  for (PVector pvMy : list) {
    curveVertex(pvMy.x, pvMy.y, pvMy.z);
  }
  endShape();
  //
}

// --------------------------------------------------------------------------------------------

void mousePressed() {
  // start dragging but only when on a sphere
  // println("A");
  if (pvSphere2D_Number1.dist(new PVector(mouseX, mouseY)) < 64) {
    println("1");
    mouseDown=true;
  }
  if (pvSphere2D_Number2.dist(new PVector(mouseX, mouseY)) < 64) { 
    println("2");
    mouseDown=true;
  }
}

void mouseReleased() {
  // end dragging
  mouseDown=false;
}
//

Lots of new things for me. I understand your solution. And the blaming line of code: It is not vital for me. So, I get the solution of my question.

There is another question about creating global variables to reserve the mouse position: I add these lines to create a durable sphere in the mouse coordinate:

float xx;
float yy;
PVector pvSphere2D_new;
void mouseWheel() { // create a new sphere using mouseWheel
  xx = mouseX;
  yy = mouseY;
  pushMatrix();
  pvSphere2D_new=new PVector(screenX(xx, yy, 60), screenY(xx, yy, 60)); 
  translate(xx, yy, 60);
  noStroke();
  lights();
  fill(0, 0, 255);
  sphere(65);
  popMatrix();
}

But, it is temporary. Why?

Moreover, the relation between coordinate system of PeasyCam and the conventional one of Processing is somehow strange. ;))

*Sorry, if it needs a new topic, please aware me. *