mirror of https://github.com/vitalif/openscad
124 lines
3.5 KiB
C++
124 lines
3.5 KiB
C++
#include "Camera.h"
|
|
#include "rendersettings.h"
|
|
#include "printutils.h"
|
|
|
|
Camera::Camera(enum CameraType camtype) :
|
|
type(camtype), projection(Camera::PERSPECTIVE), fov(22.5), viewall(false)
|
|
{
|
|
PRINTD("Camera()");
|
|
if (this->type == Camera::GIMBAL) {
|
|
object_trans << 0,0,0;
|
|
object_rot << 35,0,25;
|
|
viewer_distance = 500;
|
|
} else if (this->type == Camera::VECTOR) {
|
|
center << 0,0,0;
|
|
Eigen::Vector3d cameradir(1, 1, -0.5);
|
|
eye = center - 500 * cameradir;
|
|
}
|
|
pixel_width = RenderSettings::inst()->img_width;
|
|
pixel_height = RenderSettings::inst()->img_height;
|
|
autocenter = false;
|
|
}
|
|
|
|
void Camera::setup(std::vector<double> params)
|
|
{
|
|
if (params.size() == 7) {
|
|
type = Camera::GIMBAL;
|
|
object_trans << params[0], params[1], params[2];
|
|
object_rot << params[3], params[4], params[5];
|
|
viewer_distance = params[6];
|
|
} else if (params.size() == 6) {
|
|
type = Camera::VECTOR;
|
|
eye << params[0], params[1], params[2];
|
|
center << params[3], params[4], params[5];
|
|
} else {
|
|
assert("Gimbal cam needs 7 numbers, Vector camera needs 6");
|
|
}
|
|
}
|
|
|
|
void Camera::gimbalDefaultTranslate()
|
|
{ // match the GUI viewport numbers (historical reasons)
|
|
object_trans.x() *= -1;
|
|
object_trans.y() *= -1;
|
|
object_trans.z() *= -1;
|
|
object_rot.x() = fmodf(360 - object_rot.x() + 90, 360);
|
|
object_rot.y() = fmodf(360 - object_rot.y(), 360);
|
|
object_rot.z() = fmodf(360 - object_rot.z(), 360);
|
|
}
|
|
|
|
/*!
|
|
Moves camera so that the given bbox is fully visible.
|
|
*/
|
|
void Camera::viewAll(const BoundingBox &bbox)
|
|
{
|
|
if (this->type == Camera::NONE) {
|
|
this->type = Camera::VECTOR;
|
|
this->center = bbox.center();
|
|
this->eye = this->center - Vector3d(1,1,-0.5);
|
|
}
|
|
|
|
if (this->autocenter) {
|
|
// autocenter = point camera at the center of the bounding box.
|
|
if (this->type == Camera::GIMBAL) {
|
|
this->object_trans = -bbox.center(); // for Gimbal cam
|
|
}
|
|
else if (this->type == Camera::VECTOR) {
|
|
Vector3d dir = this->center - this->eye;
|
|
this->center = bbox.center(); // for Vector cam
|
|
this->eye = this->center - dir;
|
|
}
|
|
}
|
|
|
|
double bboxRadius = bbox.diagonal().norm()/2;
|
|
double radius = (bbox.center()-this->center).norm() + bboxRadius;
|
|
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;
|
|
}
|
|
default:
|
|
assert(false && "Camera type not specified");
|
|
}
|
|
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 obj trans x y z %f %f %f",object_trans.x() % object_trans.y() % object_trans.z());
|
|
PRINTDB("modified obj rot x y z %f %f %f",object_rot.x() % object_rot.y() % object_rot.z());
|
|
}
|
|
|
|
void Camera::zoom(int delta)
|
|
{
|
|
this->viewer_distance *= pow(0.9, delta / 120.0);
|
|
}
|
|
|
|
void Camera::setProjection(ProjectionType type)
|
|
{
|
|
this->projection = type;
|
|
}
|
|
|
|
void Camera::resetView()
|
|
{
|
|
type = Camera::GIMBAL;
|
|
object_rot << 35, 0, -25;
|
|
object_trans << 0, 0, 0;
|
|
viewer_distance = 140;
|
|
}
|
|
|
|
double Camera::zoomValue()
|
|
{
|
|
return viewer_distance;
|
|
}
|
|
|
|
std::string Camera::statusText()
|
|
{
|
|
boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f"));
|
|
fmt % object_trans.x() % object_trans.y() % object_trans.z()
|
|
% object_rot.x() % object_rot.y() % object_rot.z()
|
|
% viewer_distance;
|
|
return fmt.str();
|
|
}
|