1

Im writing a 3D sketch in which the user rotates the camera with peasyCam while left clicking and moving the mouse. The thing is that I want to move the objects while right click is pressed so that the user can drag the object across the screen's X and Y axis. Of course I know how to use mouseX and mouseY inputs to modify the translation but only across the 3D space coordinates as it shows on the GIF below:

example code of whats happening in the image:

import peasy.*;
import peasy.org.apache.commons.math.*;
import peasy.org.apache.commons.math.geometry.*;

PeasyCam cam;

float x=15;float y=15; float z=15;
float e;

void setup(){
  size (700,700,P3D);
  cam = new PeasyCam(this, 200);
  cam.setRightDragHandler(null);


}
void draw(){
  background(0);
  pushMatrix();
  translate(5, 5, 0);
  fill(255);
  stroke(255);
  sphere(5);
  popMatrix();
  pushMatrix();
  fill(255,0,0);
  stroke(255,0,0);
  translate(x, y, z);
  sphere(5);
  popMatrix();
  stroke(0,0,255);
  line(5,5,0,x,y,z);
  //obvoiusly not working method
  if(mousePressed && (mouseButton == RIGHT)){
    x= x+(mouseX-pmouseX);
    y= y+(mouseY-pmouseY);
  }
}
void mouseWheel(MouseEvent event) {
  e = event.getCount();
  z=z+e;
  println(e);
}
void mousePressed(){
  if (mouseButton==RIGHT){
    cam.setActive(false);
  }
}
void mouseReleased(){
 cam.setActive(true);
}

What I would need is to be able to drag the sphere only on the screens X/Y axis, at a fixed Z just like image below shows(simple simulation I made of the behaviour im looking for).

PeasyCam is for exploring the 3D space. The question might be difficult to undesrtand. The problem is about moving the object on the 3D world, using the screen/canvas 2D coordinates to make the object follow the cursor's movement. If the mouse goes to the left (x axis decreases), the object should move to the left on the screen, and not just on the worlds X axis. This is how the second example image behaves, but achieved by just simulating the 3D space with no actual rotations to the x,y,z axis.

I've been scratching my head with this thing and I cant seem to figure it out. I wouldn't have asked here otherwise. Thanks in advance guys.

  • Maybe this CameraWrapper can help you achieve your goal: https://github.com/jankapunkt/processing-sketches/tree/master/Graphics/CameraWrapper it is very flexible and supports several view modes. – Jankapunkt May 27 '17 at 11:45

2 Answers2

1

PeasyCam is a library that gives you a camera that by default is controlled by the mouse. This allows you to render 3D scenes and not worry about the camera, since the library handles it for you.

But it sounds like that's not what you want. You want to render a 3D scene and use the mouse to control the position of the shapes in that scene. Basically, your controls are fighting with the default controls provided by the PeasyCam library.

I see that you've already tried disabling the right-click controls here:

cam.setRightDragHandler(null);

So at the very least you probably want to do the same thing with the left drag handler.

But at that point, why are you using the PeasyCam library at all?

And even if you disable the default left controls, you'll notice that the dragging of shapes is "exaggerated" because the camera is closer to the red shape, so moving it a little bit looks like it's moving more. Just like an object right in front of your face looks like it's moving a lot more than an object that's far away.

It sounds like what you really want to do is get rid of the PeasyCam library, and then use standard Processing functions to calculate the position of the spheres based on the user input. Check out the modelX(), modelY(), and modelZ() function in the reference.

Edit: Here is a simple example that shows the model functions in action:

float x;
float y;

void setup() {
  size (700, 700, P3D);
}
void draw() {
  background(0);

  pushMatrix();
  translate(width/2, height/2, 0);
  fill(255);
  stroke(255);
  sphere(5);
  popMatrix();

  fill(255, 0, 0);
  stroke(255, 0, 0);

  if (mousePressed) {
    x= modelX(mouseX, mouseY, 0);
    y= modelY(mouseX, mouseY, 0);
  }
  translate(x, y, 15);
  sphere(5);
}

spheres

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • PeasyCam is for exploring the 3D space. The question is difficult to undesrtand I see. The problem is about moving the object on the 3D world, using the screen/canvas 2D coordinates to make the object follow the cursor's movement. If the mouse goes to the left (x axis decreases), the object should move to the left on the screen, and not just on the worlds X axis. This is how the second example image behaves, but achieved by just simulating the 3D space with no actual rotations to the x,y,z axis. – ross ross ross May 26 '17 at 01:21
  • @rossrossross I understood your question perfectly. Your problem is caused by PeasyCam moving the camera when you drag, which is what the library does by default. – Kevin Workman May 26 '17 at 01:24
  • edited the comment before your second reply, my bad Kevin. Thanks for the time. Going to add this to the actual question. – ross ross ross May 26 '17 at 01:26
  • @rossrossross Did you try looking into the model functions I mentioned in my answer? – Kevin Workman May 26 '17 at 01:32
  • I'm failing to see how those funtions could help. In what way would you implement them? I'm right now searching if it's posible to get the mouse coordinates on the 3D space with openGL functions, so that I could translate the object to those coordinates ( with a fixed "z" I guess). – ross ross ross May 26 '17 at 02:27
  • @rossrossross That's, um, exactly what the model functions do? They take a screen coordinate as a parameter, and return to you the model coordinate at that screen coordinate. That would allow you to take a mouse coordinate and turn it into a coordinate in your scene. – Kevin Workman May 26 '17 at 02:37
  • A screen coordinate as a parameter? You mean something like modelX(mouseX, mouseY, 0); ? I'm probably stupid, but I cant see how. – ross ross ross May 26 '17 at 03:24
  • @rossrossross Yes, that's exactly what I mean. What happened when you tried that? – Kevin Workman May 26 '17 at 03:38
  • It does not work. It's probably not returning what you think, I guess. here is how I modified lines 35 and 36: x= modelX(mouseX,mouseY,0); y= modelY(mouseX,mouseY,0); probably you are thinking about a different implementation of modelX/modelY/modelZ. – ross ross ross May 26 '17 at 03:57
  • @rossrossross Please stop saying that I'm not understanding your question or that I'm thinking of a different implementation. I understand your question perfectly, and the model functions do exactly what you're looking for. Please see my edited answer which includes a working example that does what you're asking about. If you have follow-up questions, please work form this simple example and post a new question in its own post. Good luck. – Kevin Workman May 26 '17 at 04:24
  • Your code doesnt involve any kind of rotation of the camera which is what causes the problem on the first place. Your use of modelX and modelY just the same as saying `if (mousePressed) { x= mouseX; y= mouseY; }` Your working example clearly doesnt have anything to do with what I'm asking kevin. – ross ross ross May 26 '17 at 04:42
  • @rossrossross Just a word to the wise: you might want to consider how you come across in your comments. People are much more willing to spend time explaining things if you're polite. Less so if you come off as rude. Anyway I'll happily spend my time elsewhere, so I'll just wish you good luck and move on. – Kevin Workman May 26 '17 at 05:13
  • Thanks for spending the time man. I've just been recommended to look into peasyCam's getRotations(); so I will update in case I find the answer. Cheers – ross ross ross May 26 '17 at 05:29
0

May be you should be looking in beginHUD() and endHUD();

Here is the example code: (Code from https://forum.processing.org/one/topic/2-questions-on-camera-view.html)

import peasy.*;
PeasyCam cam;

void setup() {
  size(300,200,P3D);
  // either put it here like this:
  // cam = new PeasyCam(this, 50, 0, 0, 100);
  cam = new PeasyCam(this, 0, 0, 0, 100);
  cam.setMinimumDistance(50);
  cam.setMaximumDistance(500);
  // or separate like this:
  cam.lookAt(50,0,0);
}

void draw() {
  background(0);

  //3D object
  pushMatrix();
  fill(255,0,0);
  translate(50,0,0);
  rotateX(-.5);
  rotateY(-.5);
  box(30);
  popMatrix();
 
  //2D object that is not affected  by the camera
  cam.beginHUD();
  fill(0,0,255);
  rect(200, height/2 -25 , 50, 50);
  cam.endHUD();
}
Jay Babani
  • 103
  • 1
  • 8