0

This is what I want to achieve: I want to draw the global axes (only the positive semiaxes) in a 3D processing sketch as x: red, y: green, g: blue. Then I want to place the camera at xyz coordinates (20,20,30), and have it look at xyz (0,0,0), such that the camera's Up vector is (nearly) colinear with the global z axis. Thus, in the end I want to see red axis (x) to the left, green axis (y) to the right, and blue axis (z) pointing upward - and then I want to have a mouse interaction like PeasyCam, but in respect to this orientation.

Because of Rotating camera around object axis with Peasycam, I know PeasyCam cannot really do something like this, so I tried to use OCD: Obsessive Camera Direction. Below is an MWE which uses it, and emulates some of the PeasyCam mouse interaction.

The problem is this: regardless of how I set the Up vector in the ODC Camera constructor, I get pretty much the same behavior when dragging (the white circle on the gif indicates the mouse position):

/tmp/Sketch/animate-O2.gif

Clearly, regardless of how the Up vector is set, the rendering shows the green vector for y pointing downwards.

Actually, if one looks at the updateUp() function in ocd/src/damkjer/ocd/Camera.java, one can see that the originally set Up components are overwritten based on the camera and target location, so I guess, no wonder then why the sketch doesn't react differently on them; the only thing able to change the Up vector is seemingly the roll paramerer, set via roll() method.

My question is: what can I do in the code below, to achieve what I want (camera dragging interaction, but where the 0,0,1 vector is rendered/remains upwards)?

Here is the MWE code, 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
*/
Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278

1 Answers1

0

Well, I decided to try ProScene (Javadocs: proscene API), and it turns out it does what I want:

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

... that is, it can start with the z (blue) vector up - and then the mouse can be used to "turn around" that axis (approximately).

ProScene's default interaction is otherwise nearly the same as PeasyCam (mousewheel is opposite, though), so for this purpose, I think I've found a solution (though it would be great to know if the same is achievable with OCD).

Here is the code, 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
*/
sdaau
  • 36,975
  • 46
  • 198
  • 278