mirror of https://github.com/vitalif/openscad
More camera fixes: Better viewall calculation, better switching between perspective and ortho
parent
788293f68f
commit
30d2440598
|
@ -3,7 +3,7 @@
|
||||||
#include "printutils.h"
|
#include "printutils.h"
|
||||||
|
|
||||||
Camera::Camera(enum CameraType camtype) :
|
Camera::Camera(enum CameraType camtype) :
|
||||||
type(camtype), projection(Camera::PERSPECTIVE), fov(22.5), viewall(false), height(60)
|
type(camtype), projection(Camera::PERSPECTIVE), fov(22.5), viewall(false)
|
||||||
{
|
{
|
||||||
PRINTD("Camera()");
|
PRINTD("Camera()");
|
||||||
if (this->type == Camera::GIMBAL) {
|
if (this->type == Camera::GIMBAL) {
|
||||||
|
@ -26,7 +26,7 @@ void Camera::setup(std::vector<double> params)
|
||||||
type = Camera::GIMBAL;
|
type = Camera::GIMBAL;
|
||||||
object_trans << params[0], params[1], params[2];
|
object_trans << params[0], params[1], params[2];
|
||||||
object_rot << params[3], params[4], params[5];
|
object_rot << params[3], params[4], params[5];
|
||||||
height = viewer_distance = params[6];
|
viewer_distance = params[6];
|
||||||
} else if (params.size() == 6) {
|
} else if (params.size() == 6) {
|
||||||
type = Camera::VECTOR;
|
type = Camera::VECTOR;
|
||||||
eye << params[0], params[1], params[2];
|
eye << params[0], params[1], params[2];
|
||||||
|
@ -69,28 +69,20 @@ void Camera::viewAll(const BoundingBox &bbox)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this->projection) {
|
double bboxRadius = bbox.diagonal().norm()/2;
|
||||||
case Camera::ORTHOGONAL:
|
double radius = (bbox.center()-this->center).norm() + bboxRadius;
|
||||||
this->height = this->viewer_distance = bbox.diagonal().norm();
|
double distance = radius / sin(this->fov/2*M_PI/180);
|
||||||
|
switch (this->type) {
|
||||||
|
case Camera::GIMBAL:
|
||||||
|
this->viewer_distance = distance;
|
||||||
|
break;
|
||||||
|
case Camera::VECTOR: {
|
||||||
|
Vector3d cameradir = (this->center - this->eye).normalized();
|
||||||
|
this->eye = this->center - distance*cameradir;
|
||||||
break;
|
break;
|
||||||
case Camera::PERSPECTIVE: {
|
|
||||||
double bboxRadius = bbox.diagonal().norm()/2;
|
|
||||||
double radius = (bbox.center()-this->center).norm() + bboxRadius;
|
|
||||||
double distance = radius / sin(this->fov*M_PI/360);
|
|
||||||
switch (this->type) {
|
|
||||||
case Camera::GIMBAL:
|
|
||||||
this->height = this->viewer_distance = distance;
|
|
||||||
break;
|
|
||||||
case Camera::VECTOR: {
|
|
||||||
Vector3d cameradir = (this->center - this->eye).normalized();
|
|
||||||
this->eye = this->center - distance*cameradir;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
assert(false && "Camera type not specified");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
default:
|
||||||
|
assert(false && "Camera type not specified");
|
||||||
}
|
}
|
||||||
PRINTDB("modified center x y z %f %f %f",center.x() % center.y() % center.z());
|
PRINTDB("modified center x y z %f %f %f",center.x() % center.y() % center.z());
|
||||||
PRINTDB("modified eye x y z %f %f %f",eye.x() % eye.y() % eye.z());
|
PRINTDB("modified eye x y z %f %f %f",eye.x() % eye.y() % eye.z());
|
||||||
|
@ -100,7 +92,7 @@ void Camera::viewAll(const BoundingBox &bbox)
|
||||||
|
|
||||||
void Camera::zoom(int delta)
|
void Camera::zoom(int delta)
|
||||||
{
|
{
|
||||||
this->height = this->viewer_distance *= pow(0.9, delta / 120.0);
|
this->viewer_distance *= pow(0.9, delta / 120.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setProjection(ProjectionType type)
|
void Camera::setProjection(ProjectionType type)
|
||||||
|
@ -113,12 +105,12 @@ void Camera::resetView()
|
||||||
type = Camera::GIMBAL;
|
type = Camera::GIMBAL;
|
||||||
object_rot << 35, 0, -25;
|
object_rot << 35, 0, -25;
|
||||||
object_trans << 0, 0, 0;
|
object_trans << 0, 0, 0;
|
||||||
height = viewer_distance = 140;
|
viewer_distance = 140;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Camera::zoomValue()
|
double Camera::zoomValue()
|
||||||
{
|
{
|
||||||
return this->projection == PERSPECTIVE ? viewer_distance : height;
|
return viewer_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Camera::statusText()
|
std::string Camera::statusText()
|
||||||
|
@ -126,6 +118,6 @@ std::string Camera::statusText()
|
||||||
boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f"));
|
boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f"));
|
||||||
fmt % object_trans.x() % object_trans.y() % object_trans.z()
|
fmt % object_trans.x() % object_trans.y() % object_trans.z()
|
||||||
% object_rot.x() % object_rot.y() % object_rot.z()
|
% object_rot.x() % object_rot.y() % object_rot.z()
|
||||||
% (this->projection == PERSPECTIVE ? viewer_distance : height);
|
% viewer_distance;
|
||||||
return fmt.str();
|
return fmt.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,22 +95,21 @@ void GLView::setupCamera()
|
||||||
|
|
||||||
switch (this->cam.type) {
|
switch (this->cam.type) {
|
||||||
case Camera::GIMBAL: {
|
case Camera::GIMBAL: {
|
||||||
double eyeY = 0.0;
|
double dist = cam.zoomValue();
|
||||||
switch (this->cam.projection) {
|
switch (this->cam.projection) {
|
||||||
case Camera::PERSPECTIVE: {
|
case Camera::PERSPECTIVE: {
|
||||||
eyeY = cam.zoomValue();
|
gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist);
|
||||||
gluPerspective(cam.fov, aspectratio, 0.1 * eyeY, 100 * eyeY);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Camera::ORTHOGONAL: {
|
case Camera::ORTHOGONAL: {
|
||||||
eyeY = cam.zoomValue();
|
double height = dist * tan(cam.fov/2*M_PI/180);
|
||||||
glOrtho(-eyeY/2*aspectratio, eyeY*aspectratio/2,
|
glOrtho(-height*aspectratio, height*aspectratio,
|
||||||
-eyeY/2, eyeY/2,
|
-height, height,
|
||||||
-far_far_away, +far_far_away);
|
-far_far_away, +far_far_away);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gluLookAt(0.0, -eyeY, 0.0,
|
gluLookAt(0.0, -dist, 0.0,
|
||||||
0.0, 0.0, 0.0,
|
0.0, 0.0, 0.0,
|
||||||
0.0, 0.0, 1.0);
|
0.0, 0.0, 1.0);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
@ -121,16 +120,16 @@ void GLView::setupCamera()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Camera::VECTOR: {
|
case Camera::VECTOR: {
|
||||||
|
double dist = (cam.center - cam.eye).norm();
|
||||||
switch (this->cam.projection) {
|
switch (this->cam.projection) {
|
||||||
case Camera::PERSPECTIVE: {
|
case Camera::PERSPECTIVE: {
|
||||||
double dist = (cam.center - cam.eye).norm();
|
|
||||||
gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist);
|
gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Camera::ORTHOGONAL: {
|
case Camera::ORTHOGONAL: {
|
||||||
double height = cam.zoomValue();
|
double height = dist * tan(cam.fov/2*M_PI/180);
|
||||||
glOrtho(-height/2*aspectratio, height*aspectratio/2,
|
glOrtho(-height*aspectratio, height*aspectratio,
|
||||||
-height/2, height/2,
|
-height, height,
|
||||||
-far_far_away, +far_far_away);
|
-far_far_away, +far_far_away);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue