2014-11-05 3 views
0

Это то, чего я хочу достичь: хочу нарисовать глобальные оси (только положительные полуоси) в эскизе 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 конструктора камеры, я получаю довольно много такое же поведение при перетаскивании (белый кружок на МФП указывает положение курсора мыши):

/tmp/Sketch/animate-O2.gif

Очевидно, независимо от того, как установлен вектор 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 
*/ 

ответ

0

Ну, я решил попробовать ProScene (Javadocs: proscene API), и оказывается, что он делает то, что я хочу:

/tmp/Sketch/animate-O2-2.gif

. то есть он может начинаться с вектора z (синий) вверх - и затем мышь может использоваться для «поворота» этой оси (приблизительно).

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

Вот код, Sketch.pde:

// modification of example on http://mrfeinberg.com/peasycam/ 
// http://stackoverflow.com/questions/17683602/rotating-camera-around-object-axis-with-peasycam/26755516#26755516 
// sdaau, 2014 

import remixlab.proscene.*; 
import remixlab.dandelion.geom.*; // Vec 
Scene scene; 
int saveCount=500; 
//Choose one of P3D for a 3D scene, or P2D or JAVA2D for a 2D scene 
String renderer = P3D; 

void setup() { 
    // Setup graphics 
    size(300, 200, renderer); 
    //Scene instantiation 
    scene = new Scene(this); 
    scene.setGridVisualHint(false); 
    scene.setAxesVisualHint(false); 
    // specify starting camera position, orientation and target 
    scene.camera().setUpVector(new Vec(0, 0, -1), true); // boolean noMove 
    scene.camera().setPosition(new Vec(30, 30, 50)); 
    scene.camera().lookAt(new Vec(0, 0, 0)); 
    // when damping friction = 0 -> spin 
    scene.eye().frame().setDampingFriction(0); 
} 

void draw() { 
    // 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); 
    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); 
    } 
} 

void keyPressed() { 
    if(scene.eye().frame().dampingFriction() == 0) 
    scene.eye().frame().setDampingFriction(0.5); 
    else 
    scene.eye().frame().setDampingFriction(0); 
    println("Camera damping friction now is " + scene.eye().frame().dampingFriction()); 
} 


/* 
# http://stackoverflow.com/questions/3323619/how-to-sort-files-numerically-from-linux-command-line 
# http://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 
*/ 
Смежные вопросы