Это то, чего я хочу достичь: хочу нарисовать глобальные оси (только положительные полуоси) в эскизе 3D-обработки как x: red, y: green, g: blue. Затем я хочу поместить камеру в координаты xyz (20,20,30) и посмотреть на xyz (0,0,0), так что вектор Up камеры (почти) colinear с глобальной осью z. Таким образом, в конце я хочу видеть красную ось (x) влево, зеленую ось (y) вправо и синюю ось (z), направленную вверх, - и затем я хочу иметь взаимодействие с мышью, такое как PeasyCam, но в в отношении этой ориентации.Настройка ориентации камеры в процессе обработки?
Из-за Rotating camera around object axis with Peasycam, я знаю, что PeasyCam действительно не может сделать что-то подобное, поэтому я попытался использовать OCD: Obsessive Camera Direction. Ниже приведен MWE, который использует его, и эмулирует некоторые из взаимодействий мыши PeasyCam.
Проблема заключается в следующем: независимо от того, как я установил вектор вверх в ODC конструктора камеры, я получаю довольно много такое же поведение при перетаскивании (белый кружок на МФП указывает положение курсора мыши):
Очевидно, независимо от того, как установлен вектор Up, рендеринг показывает зеленый вектор для y, указывающий вниз.
На самом деле, если посмотреть на updateUp()
функции в ocd/src/damkjer/ocd/Camera.java
, можно увидеть, что первоначально установки компонентов заменяются на основе расположения камеры и цели, поэтому я думаю, не удивительно, почему эскиз не не реагируют по-разному на них; единственное, что может изменить вектор Up, по-видимому, является параметром roll, установленным с помощью метода roll()
.
Мой вопрос: что я могу сделать в коде ниже, для достижения того, что я хочу (взаимодействие с перетаскиванием камеры, но где вектор 0,0,1 визуализируется/остается вверх)?
Вот код MWE, Sketch.pde
:
// modification of example on http://mrfeinberg.com/peasycam/
// https://stackoverflow.com/questions/17683602/rotating-camera-around-object-axis-with-peasycam/26755516#26755516
// sdaau, 2014
import damkjer.ocd.*;
DCamera cam1; //Camera cam1; // (see subclass below)
int saveCount=500;
void setup() {
// Setup graphics
size(300, 200, P3D);
// only .roll() seems to be able to manipulate up vector?
cam1 = new DCamera(this, //Camera(this, // (parent,
40, 40, 60, // cameraX, cameraY, cameraZ,
0, 0, 0, // targetX, targetY, targetZ
// 0, 0, 1, // upX, upY, upZ // (seems ignored)
// 0, 1, 0, // upX, upY, upZ // (seems ignored)
1, 0, 0, // upX, upY, upZ // (seems ignored)
10, 500 // nearClip, farClip) //(doesn't clip as peasycam!)
);
//~ cam1.roll(radians(-90));
}
void draw() {
cam1.feed(); //"send what this camera sees to the view port"
// actual drawing:
background(0);
stroke(255,0,0); line(0,0,0, 1000,0,0); // x axis
stroke(0,255,0); line(0,0,0, 0,1000,0); // ... y
stroke(0,0,255); line(0,0,0, 0,0,1000); // ... z
fill(255,0,0);
box(30);
pushMatrix();
translate(0,0,20);
fill(0,0,255);
box(5);
popMatrix();
fill(-1);
// text("U 0,0,1", -20, 30, 6);
// text("U 0,1,0", -20, 30, 6);
text("U 1,0,0", -20, 30, 6);
if (mouseButton == LEFT) {
hint(DISABLE_DEPTH_TEST);
camera(); // must have after disable for 2D draw
ellipse(mouseX,mouseY,20,20);
saveFrame("images/image_" + saveCount + ".png");
saveCount++;
hint(ENABLE_DEPTH_TEST);
}
}
// this to emulate peasycam:
// these to replicate the peasycam interaction with OCD:
void mouseDragged() {
if (mouseButton == LEFT) {
// http://www.airtightinteractive.com/demos/processing/bezier_ribbon_p3d/BezierRibbons.pde
cam1.arc(radians(-(mouseY - pmouseY))/4);
cam1.circle(radians(-(mouseX - pmouseX))/4);
} else if (mouseButton == RIGHT) {
cam1.zoom(radians(mouseY - pmouseY)/2.0);
} else if (mouseButton == CENTER) {
// peasycam calls this .pan(); damkjer.ocd calls it .track()
cam1.track(-(mouseX - pmouseX), -(mouseY - pmouseY));
}
}
void mouseWheel(MouseEvent event) {
float e = event.getCount();
cam1.zoom(e*4.0);
}
public class DCamera extends damkjer.ocd.Camera {
// private final PApplet p; // in peasycam/src/peasy/PeasyCam.java; in ocd/src/damkjer/ocd/Camera.java it is called theParent! both are private!
private PApplet theParent; // replicate as in ocd/.../Camera.java; it helps, even if super has same name (must re-assign in ctor)
// directly from libraries/ocd/src/damkjer/ocd/Camera.java
public DCamera(PApplet aParent,
float aCameraX, float aCameraY, float aCameraZ,
float aTargetX, float aTargetY, float aTargetZ,
float aNearClip, float aFarClip)
{
super(aParent, aCameraX, aCameraY, aCameraZ, aTargetX, aTargetY, aTargetZ, aNearClip, aFarClip);
theParent = aParent;
}
// another constructor, to handle up vector:
public DCamera(PApplet aParent,
float aCameraX, float aCameraY, float aCameraZ,
float aTargetX, float aTargetY, float aTargetZ,
float anUpX, float anUpY, float anUpZ,
float aNearClip, float aFarClip)
{
super(aParent, aCameraX, aCameraY, aCameraZ, aTargetX, aTargetY, aTargetZ, anUpX, anUpY, anUpZ, aNearClip, aFarClip);
theParent = aParent;
}
}
/*
# https://stackoverflow.com/questions/3323619/how-to-sort-files-numerically-from-linux-command-line
# https://stackoverflow.com/questions/246215/how-can-i-list-files-with-their-absolute-path-in-linux
convert -delay 5 -loop 0 $(ls ./images/ | sort --version-sort -f) animate.gif
gifsicle -O2 --colors 8 animate.gif -o animate-O2.gif
*/