Well got it somewhat working,
minVec and maxVec describe a BBox
Press x for a new random viewing direction, the camera kind of keeps the box in the view area. Not perfect, I would like to have the objCentre value move so it would fit the box better in view and have a better fit, but itll do. Any suggestions always welcome.
- PVector minVec, maxVec, objCentre, lookDir, viewPlanePoint;
float zoom;
void setup() {
size (300, 300, P3D );
//bbox values
minVec = new PVector(10, 15, 20 );
maxVec = new PVector(50, 45, 40);
objCentre = new PVector();
zoom = 100;
//looking direction, can vary
lookDir = new PVector(.1, .1, .4);
}
void draw() {
background(255);
lookDir.normalize();
viewPlanePoint = new PVector((maxVec.x+minVec.x)/2, ( maxVec.y+minVec.y)/2, ( maxVec.z+minVec.z)/2);
//camera, eye values start at center of box and added are looking direction times zoom
camera( objCentre.x+lookDir.x*zoom, objCentre.y+lookDir.y*zoom, objCentre.z+lookDir.z*zoom, // eyeX, eyeY, eyeZ
objCentre.x, objCentre.y, objCentre.z, // centerX, centerY, centerZ
0, 1, 0); // upX, upY, upZ
//visualise box
pushMatrix();
fill(150, 150, 150, 150);
translate((maxVec.x+minVec.x)/2, ( maxVec.y+minVec.y)/2, ( maxVec.z+minVec.z)/2);
box(maxVec.x-minVec.x, maxVec.y-minVec.y, maxVec.z-minVec.z);
fill(200, 0, 0);
noStroke();
sphere(1);
stroke(0);
popMatrix();
PVector pv = new PVector();
PVector tv = new PVector();
PVector nv = new PVector();
PVector dotv = new PVector();
PVector projPoint = new PVector();
float minX = 1000;
float minY = 1000;
float minZ = 1000;
float maxX = -1000;
float maxY = -1000;
float maxZ = -1000;
for (int i =0; i<8; i++) {
if (i==0) {
tv =new PVector(minVec.x, minVec.y, minVec.z);
}
else if (i==1) {
tv =new PVector(maxVec.x, minVec.y, minVec.z);
}
else if (i==2) {
tv =new PVector(minVec.x, maxVec.y, minVec.z);
}
else if (i==3) {
tv =new PVector(minVec.x, minVec.y, maxVec.z);
}
else if (i==4) {
tv =new PVector(minVec.x, maxVec.y, maxVec.z);
}
else if (i==5) {
tv =new PVector(maxVec.x, minVec.y, maxVec.z);
}
else if (i==6) {
tv =new PVector(maxVec.x, maxVec.y, minVec.z);
}
else {
tv =new PVector(maxVec.x, maxVec.y, maxVec.z);
}
// get planar projection of boxpoint on camera viewing plane
PVector.sub(tv, viewPlanePoint, pv);
float dotp = PVector.dot(pv, lookDir);
PVector.mult(lookDir, dotp, dotv);
PVector.sub(tv, dotv, projPoint);
if (projPoint.x<minX) {
minX = projPoint.x;
}
else if (projPoint.x>maxX) {
maxX = projPoint.x;
}
if (projPoint.y<minY) {
minY = projPoint.y;
}
else if (projPoint.y>maxY) {
maxY = projPoint.y;
}
if (projPoint.z<minZ) {
minZ = projPoint.z;
}
else if (projPoint.z>maxZ) {
maxZ = projPoint.z;
}
}
objCentre.x = ((minX+maxX)/2);
objCentre.y = ((minY+maxY)/2);
objCentre.z = ((minZ+maxZ)/2);
float vPlaneCross = dist(minX, minY, minZ, maxX, maxY, maxZ);
//tan cam fov = vPlaneCross / zoom dist
float zoomDist = (vPlaneCross/2)/tan(PI/6);
zoom = zoom+ (1*zoomDist-zoom)/10;
}
void keyPressed()
{
if (key == 'x')
{
float x =random(-1, 1);
float y =random(-1, 1);
float z =random(-1, 1);
lookDir = new PVector(x, y, z);
}
}