how to track rotation?

edited July 2015 in Library Questions

hi there,

i have a sketch in 3d which uses the OCD library

if you use the method camera1.aim(x, y, z) - you can point to a specific location in 3d space...

i have a box at (0,0, 150) which the camera is pointed at

but, if i start rotating the scene, the camera stays locked on that spot, but the object goes off on its own orbit.

does anyone know how i might keep the camera locked on the target, while rotating?

if by rotating the world then the boxes location of (0,0,150) is now something else, then I guess I need to have the camera track a variable that store that location, but I dont know what that value is, because the whole world is rotating (as I understand it) with the translate function.

If you uncomment the rotation code, you can see what I mean

import damkjer.ocd.*;
Camera camera1;
float rot = 0.0;
float a = 0;
float x, y, z;
float cx, cy, cz;
void setup() {

  size(1000, 1000, P3D);
  smooth(8);

  camera1 = new Camera(this, 1, -300);  


  camera1.aim(0, 0, 150);
}


  void draw() {
  camera1.feed();

  background(0, a);


  colorMode(HSB, 360); // colorMode must be in the PGraphics

  rot = rot + 0.1;

  pushMatrix();
  rotateX(radians(-rot*5));
  rotateY(radians(-rot*5));
  stroke(360, 350, 360, 360);
  fill(255, 360);
  sphereDetail(20);
  sphere(100);
  popMatrix();

  pushMatrix();

//  rotateX(radians(rot*10));

  pushMatrix();
  translate(0, 0, 150);
  stroke(120, 360);
  box(5);
  popMatrix();

  popMatrix();
}

Answers

  • edited July 2015

    I'm willing to bet that the problem is not your camera, but the order of your drawing calls. Try switching the commented rotateX call and the translate call below it.

    Since I have not had enough practice with OpenGL, yet, I cannot say this with confidence, but a good way to imagine how things are drawn in GL is to be the object being drawn, and go down the code line by line.

    In this case:

    rotateX: Alright. I will turn rot * 10 degrees on the X axis.
    translate: Now, I will move 150 units on the Z axis, based on how I'm currently positioned.

    That's my general idea, and I hope that I have not given a misleading analogy.

  • Oh my goodness, I completely misread the question. Ignore my above answer, as I try to come up with a new response. :\">

  • Right. By the nature that a rotate function moves objects relative to itself in a circle, we'll respectively use the sin and cos math functions to calculate the position of the cube.

    Create variables to keep the position of the cube. I'll use focus(X/Y/Z).

    To calculate the position of the cube, we use the trigonometric functions. So place the following after your OpenGL calls:

    focusX = sin(radians(rot*10)) * -150;
    focusY = cos(radians(rot*10)) * 150;
    

    Then just use camera.aim:

    camera1.aim(focusX, focusY, focusZ);
    

    If you have questions, I'll try to explain as best as I can, but I'm no tutor. For now, you can utilize the above, or try to learn why it works if you do not already.

  • Excellent thanks so much I will try this today. I really appreciate your effort to respond.

  • I worked with your suggestion and got some great results - and in fact I realised I needed another method - the camera.jump() - to move the camera independtly from what it observes.

    So I used your solution there.

    However a problem presents itself - rather than continuously rotating, the camera seems to go up and down the sine curve, and kind've glitching at the end.

    I commented out the larger spheres rotation to make things a bit simpler - and even though this example it looks like the larger sphere is rotating, it is in fact the box and camera moving together (this is what I want and a great progress) - but any idea how i can avoid the back and forth movement and just have continuous rotations? And no glitch?

    Many Thanks

    import damkjer.ocd.*;
    Camera camera1;
    float rot = 0.0;
    float a = 0;
    float x, y, z;
    float cx, cy, cz;
    
    
    float focusX;
    float focusY;
    float focusZ;
    
    float posX;
    float posY;
    float posZ;
    
    void setup() {
    
      size(1000, 1000, P3D);
      smooth(8);
    
      camera1 = new Camera(this, 1, -300);  
    
    }
    
      void draw() {
    
      background(0, a);
    
      camera1.feed();
    
      focusY = sin(radians(rot)) * -250;
      focusX = cos(radians(rot)) * 250;
    
      posY = sin(radians(rot)) * -300;
      posX = cos(radians(rot)) * 300;
    
    
      camera1.aim(0, focusY, focusX);
      camera1.jump(0, posY, posX);
    
      colorMode(HSB, 360); // colorMode must be in the PGraphics
    
      rot = rot + 1;
    
      pushMatrix();
    
    //commented out larger sphere rotation  
    //  rotateX(radians(-rot*5));
    //  rotateY(radians(-rot*5));
    
      stroke(360, 350, 360, 360);
      fill(255, 360);
      sphereDetail(20);
      sphere(100);
      popMatrix();
    
      pushMatrix();
    
      rotateX(radians(rot));
    
      pushMatrix();
      translate(0, 0, 150);
      stroke(120, 360);
      box(5);
      popMatrix();
    
      popMatrix();
    }
    
  • I worked with your suggestion and got some great results - and in fact I realised I needed another method - the camera.jump() - to move the camera independtly from what it observes.

    So I used your solution there.

    However a problem presents itself - rather than continuously rotating, the camera seems to go up and down the sine curve, and kind've glitching at the end.

    I commented out the larger spheres rotation to make things a bit simpler - and even though this example it looks like the larger sphere is rotating, it is in fact the box and camera moving together (this is what I want and a great progress) - but any idea how i can avoid the back and forth movement and just have continuous rotations? And no glitch?

    Many Thanks

    import damkjer.ocd.*;
    Camera camera1;
    float rot = 0.0;
    float a = 0;
    float x, y, z;
    float cx, cy, cz;
    
    
    float focusX;
    float focusY;
    float focusZ;
    
    float posX;
    float posY;
    float posZ;
    
    void setup() {
    
      size(1000, 1000, P3D);
      smooth(8);
    
      camera1 = new Camera(this, 1, -300);  
    
    }
    
      void draw() {
    
      background(0, a);
    
      camera1.feed();
    
      focusY = sin(radians(rot)) * -250;
      focusX = cos(radians(rot)) * 250;
    
      posY = sin(radians(rot)) * -300;
      posX = cos(radians(rot)) * 300;
    
    
      camera1.aim(0, focusY, focusX);
      camera1.jump(0, posY, posX);
    
      colorMode(HSB, 360); // colorMode must be in the PGraphics
    
      rot = rot + 1;
    
      pushMatrix();
    
    //commented out larger sphere rotation  
    //  rotateX(radians(-rot*5));
    //  rotateY(radians(-rot*5));
    
      stroke(360, 350, 360, 360);
      fill(255, 360);
      sphereDetail(20);
      sphere(100);
      popMatrix();
    
      pushMatrix();
    
      rotateX(radians(rot));
    
      pushMatrix();
      translate(0, 0, 150);
      stroke(120, 360);
      box(5);
      popMatrix();
    
      popMatrix();
    }
    
  • It was instantly apparent what was happening. I've put together an animation to demonstrate:

    image

    The camera in this sketch is effectively doing the same thing as shown by the arrow, but much faster. The camera cannot turn upside down when aiming, unless explicitly adjusted to be upside down.

    To fix this, you will likely have to use something like the roll camera function.

    To be more exact, put this somewhere in the draw function.

    if(rot % 180 == 90) {
      camera1.roll(radians(180));
    }
    

    Yeah, it's still a bit glitchy, but it's closer to what you're trying to achieve.

  • I've got to say it's very strange behaviour, and very hard to keep track of.

  • Thanks again for your help, I tried your solution and it does work in that particular example, but as soon as I start doing other things it kind've goes haywire again.

    I'm going to try and work within these imitations for now I think and there's probably enough to go on here to get further with things. So thanks :)

Sign In or Register to comment.