(Обработка) Как переместить 3D-объект в соответствии с осью XY экрана, вместо мировых X,Y,Z(PeasyCam)

Я пишу трехмерный эскиз, в котором пользователь поворачивает камеру с помощью peasyCam, щелкая левой кнопкой мыши и перемещая мышь. Дело в том, что я хочу перемещать объекты при нажатии правой кнопки мыши, чтобы пользователь мог перетаскивать объект по осям X и Y экрана. Конечно, я знаю, как использовать входы mouseX и mouseY для изменения перевода, но только по координатам трехмерного пространства, как показано на GIF ниже:

Пример кода того, что происходит на изображении:

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);
}

То, что мне нужно, это уметь перетаскивать сферу только по оси X/Y на экранах, при фиксированном Z, как показано на рисунке ниже (я сделал простое моделирование поведения, которое я искал).

PeasyCam для изучения трехмерного пространства. Вопрос может быть трудно понять. Проблема заключается в перемещении объекта в трехмерном мире с использованием 2D-координат экрана / холста, чтобы объект следовал за движением курсора. Если мышь перемещается влево (ось x уменьшается), объект должен перемещаться влево на экране, а не только по оси X миров. Вот как ведет себя второй пример изображения, но достигается просто моделированием трехмерного пространства без фактических поворотов по оси x,y,z.

Я царапал свою голову этой вещью, и я не могу понять это. Я бы не спросил здесь иначе. Заранее спасибо, ребята.

1 ответ

PeasyCam - это библиотека, которая предоставляет камеру, которая по умолчанию управляется мышью. Это позволяет вам рендерить 3D-сцены и не беспокоиться о камере, поскольку библиотека обрабатывает ее за вас.

Но, похоже, это не то, что вы хотите. Вы хотите визуализировать трехмерную сцену и использовать мышь для управления положением фигур в этой сцене. По сути, ваши элементы управления борются с элементами управления по умолчанию, предоставленными библиотекой PeasyCam.

Я вижу, что вы уже пытались отключить элементы управления правой кнопкой мыши здесь:

cam.setRightDragHandler(null);

Поэтому, по крайней мере, вы, вероятно, захотите сделать то же самое с левым обработчиком перетаскивания.

Но почему вы вообще используете библиотеку PeasyCam?

И даже если вы отключите левые элементы управления по умолчанию, вы заметите, что перетаскивание фигур "преувеличено", потому что камера ближе к красной форме, поэтому ее перемещение немного похоже на движение больше. Точно так же, как объект прямо перед вашим лицом выглядит так, как будто он движется намного больше, чем объект, который находится далеко.

Похоже, что вы действительно хотите сделать, это избавиться от библиотеки PeasyCam, а затем использовать стандартные функции обработки для расчета положения сфер на основе пользовательского ввода. Проверьте modelX(), modelY(), а также modelZ() Функция в ссылке.

Изменить: Вот простой пример, который показывает функции модели в действии:

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);
}

сферы

Возможно, вам стоит посмотреть в beginHUD() и endHUD();

Вот пример кода: (Код из 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();
}
Другие вопросы по тегам