How to match SketchUp Camera in Processing/OpenGL?

380 views Asked by At

I'm trying to match a scene from Sketchup in Processing/OpenGL but can't seem to get the measurements right.

I'm using these simply commands in the Ruby Console in Sketchup:

model = Sketchup.active_model 
cam = model.active_view.camera 
print cam.eye, cam.direction, cam.fov 

Which prints these values for my file:

(1668.854717mm, -1723.414322mm, 131.550996mm)(-0.688802494154077, 0.649067164730165, 0.322897723306109)63.6653435710446nil

The FOV seems to work, but I don't think I've figured out the camera position(units) yet. Here's my attempt:

float eyeScale = 1.0f;
float camEyeX = 1668.854717f * eyeScale;
float camEyeY = -1723.414322f * eyeScale;
float camEyeZ = 131.550996f * eyeScale;
float camTargetX = -0.688802494154077f;
float camTargetY = 0.649067164730165f;
float camTargetZ = 0.322897723306109f;
float camFOV = 63.665f;

float div = 10;

void setup(){
    size(1280,720,P3D);
}

void draw(){
    background(255);
    perspective(radians(camFOV), width/height, camEyeZ * 0.1f, camEyeZ * 10);
    camera(camEyeX/div, camEyeY/div, camEyeZ/div, camTargetX, camTargetY, camTargetZ, 1, 0, 0);

    drawGrid(20,10,10,0);
    drawGrid(20,10,10,1);
    drawGrid(20,10,10,2);
}

void keyPressed(){
  if(keyCode == UP) div++;
  if(keyCode == DOWN) div--;
}

void drawGrid(int size,int w,int h,int plane){
    pushStyle();
    noFill();

    if(plane == 0) stroke(255,0,0);
    if(plane == 1) stroke(0,255,0);
    if(plane == 2) stroke(0,0,255);

    int total = w * h;
    int tw = w * size;
    int th = h * size;

    beginShape(LINES);
    for(int i = 0 ; i < total; i++){
        int x = (i % w) * size;
        int y = (i / w) * size;

        if(plane == 0){
             vertex(0,x,0);vertex(0,x,th);
             vertex(0,0,y);vertex(0,tw,y);
        }

        if(plane == 1){
             vertex(x,0,0);vertex(x,0,th);
             vertex(0,0,y);vertex(tw,0,y);
        }

        if(plane == 2){
             vertex(x,0,0);vertex(x,th,0);
             vertex(0,y,0);vertex(tw,y,0);
        }
    }
    endShape();
    popStyle();
}

The grids look ok above using the perspective() call, but if I comment back the camera() call the scene disappears.

Any hints or tips will help. Processing code is ok, but I don't mind raw GL calls/matrices either.

Update Based on @Majlik's notes it's good to point out the differences between the sketchup camera api and Processing's camera api, and on top of that difference in coordinate systems (Sketchup uses Z up, while Processing uses Y up).

I've tried playing with the coordinate system a bit using keys, but I'm not understanding the conversion from Sketchup to Processing/OpenGL:

float eyeScale = 1.0f;
float camEyeX = 1668.854717f * eyeScale;
float camEyeY = -1723.414322f * eyeScale;
float camEyeZ = 131.550996f * eyeScale;
float camTargetX = -0.688802494154077f;
float camTargetY = 0.649067164730165f;
float camTargetZ = 0.322897723306109f;
float camFOV = 63.665f;

float div = 10;
PImage bg;
int axis = 0;
boolean flipAxis = false;

void setup(){
    size(1280,720,P3D);
    bg = loadImage("SketchupCam.png");
}

void draw(){
    background(bg);
    perspective(radians(camFOV), width/height, camEyeZ * 0.1f, camEyeZ * 10);
    camera(camEyeX/div, camEyeY/div, camEyeZ/div, 
           camTargetX+camEyeX/div, camTargetY+camEyeY/div, camTargetZ+camEyeZ/div, 
           axis == 0 ? (flipAxis ? -1 : 1) : 0,
           axis == 1 ? (flipAxis ? -1 : 1) : 0,
           axis == 2 ? (flipAxis ? -1 : 1) : 0);

    drawGrid(20,10,10,0);
    drawGrid(20,10,10,1);
    drawGrid(20,10,10,2);
}

void keyPressed(){
  if(keyCode == UP) div++;
  if(keyCode == DOWN) div--;
  println(div);

  if(key == 'x') axis = 0;
  if(key == 'y') axis = 1;
  if(key == 'z') axis = 2;
  if(key == ' ') flipAxis = !flipAxis;
}

void drawGrid(int size,int w,int h,int plane){
    pushStyle();
    noFill();

    if(plane == 0) stroke(255,0,0);
    if(plane == 1) stroke(0,255,0);
    if(plane == 2) stroke(0,0,255);

    int total = w * h;
    int tw = w * size;
    int th = h * size;

    beginShape(LINES);

    for(int i = 0 ; i < total; i++){
        int x = (i % w) * size;
        int y = (i / w) * size;

        if(plane == 0){
             vertex(0,x,0);vertex(0,x,th);
             vertex(0,0,y);vertex(0,tw,y);
        }
        if(plane == 1){
             vertex(x,0,0);vertex(x,0,th);
             vertex(0,0,y);vertex(tw,0,y);
        }
        if(plane == 2){
             vertex(x,0,0);vertex(x,th,0);
             vertex(0,y,0);vertex(tw,y,0);
        }
    }
    endShape();
    popStyle();
}

And here is a Sketchup screenshot I'm trying to match in Processing: Sketchup Screenshot

The smaller box is 1000mm in Sketchup.

How I could match the view from Sketchup in Processing/OpenGL ?

0

There are 0 answers