mirror of https://github.com/KLayout/klayout.git
WIP.
This commit is contained in:
parent
7077bac647
commit
d37608dac1
|
|
@ -37,6 +37,9 @@ D25View::D25View (QWidget *parent)
|
||||||
mp_ui = new Ui::D25View ();
|
mp_ui = new Ui::D25View ();
|
||||||
mp_ui->setupUi (this);
|
mp_ui->setupUi (this);
|
||||||
|
|
||||||
|
// @@@ should be an event filter?
|
||||||
|
mp_ui->d25_view->setFocusPolicy (Qt::StrongFocus);
|
||||||
|
mp_ui->d25_view->setFocus ();
|
||||||
// @@@
|
// @@@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,4 +161,65 @@ camera_normal (const QMatrix4x4 &camera_trans, double x, double y)
|
||||||
return (std::make_pair (p, u.normalized ()));
|
return (std::make_pair (p, u.normalized ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
normalize_scene_trans (const QMatrix4x4 &cam_trans, QVector3D &displacement, double &scale, double ztarget)
|
||||||
|
{
|
||||||
|
QMatrix4x4 m;
|
||||||
|
|
||||||
|
// Here is the theory:
|
||||||
|
// Let:
|
||||||
|
// cam = ( M t ) M = 3x3 matrix, t = 3x1 translation vector, z = scalar, p = 1x3 perspective
|
||||||
|
// ( p z )
|
||||||
|
// and:
|
||||||
|
// scene = ( S d ) S = s*U1 (s = scale factor, U1 = 3x3 unit matrix), d = 3x1 displacement vector
|
||||||
|
// ( 0 1 )
|
||||||
|
// then:
|
||||||
|
// cam * scene = ( M*s M*d+t )
|
||||||
|
// ( p*s p*d+z ) (p*d = dot product)
|
||||||
|
//
|
||||||
|
// this is image invariant (only x,y results are considered) against changes of s (s->s') if
|
||||||
|
//
|
||||||
|
// 1.) (p*d+z)/s = (p*d'+z)/s'
|
||||||
|
// 2.) (M*d+t)/s = (M*d'+t)/s' for [x] and [y]
|
||||||
|
//
|
||||||
|
// Ff we seek a solution with d'[z] == b (b = ztarget), we get these equations (f:=s'/s)
|
||||||
|
//
|
||||||
|
// 2.) M[xx] * d'[x] + M[xy] * d'[y] - ((M*d)[x] + t[x]) * f = -t[x] - M[xz] * b
|
||||||
|
// M[yx] * d'[x] + M[yy] * d'[y] - ((M*d)[y] + t[y]) * f = -t[y] - M[yz] * b
|
||||||
|
// 1.) p[x] * d'[x] + p[y] * d'[y] - (p*d+z) * f = -z - p[z] * b
|
||||||
|
//
|
||||||
|
// we can solve these equations for d'[x], d'[y] and f.
|
||||||
|
// With p[x]=M[wx], p[y]=M[wy] and z=t[w], the above equation system can be written as
|
||||||
|
//
|
||||||
|
// M[ix] * d'[x] + M[iy] * d'[y] - ((M*d)[i] + t[i]) * f = -t[i] - M[iz]*b i = x,y,w
|
||||||
|
//
|
||||||
|
// and with M,t->M (4x4 matrix) and d->(d,1) (4d vector)
|
||||||
|
//
|
||||||
|
// M[ix] * d'[x] + M[iy] * d'[y] - (M*d)[i] * f = -t[i] - M[iz]*b i = x,y,w
|
||||||
|
//
|
||||||
|
|
||||||
|
QVector4D d4 (displacement);
|
||||||
|
d4.setW (1.0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (i != 2) {
|
||||||
|
m (i, 0) = cam_trans (i, 0);
|
||||||
|
m (i, 1) = cam_trans (i, 1);
|
||||||
|
m (i, 3) = -QVector4D::dotProduct (cam_trans.row (i), d4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool invertable = false;
|
||||||
|
m = m.inverted (&invertable);
|
||||||
|
if (! invertable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector4D sol = m.map (-cam_trans.column (3) - cam_trans.column (2) * ztarget);
|
||||||
|
if (sol.w () > 0.01 /*skip weird solutions*/) {
|
||||||
|
scale *= sol.w ();
|
||||||
|
displacement = QVector3D (sol.x (), sol.y (), ztarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,18 @@ hit_point_with_cuboid (const QVector3D &line, const QVector3D &line_dir, const Q
|
||||||
LAY_PLUGIN_PUBLIC std::pair<QVector3D, QVector3D>
|
LAY_PLUGIN_PUBLIC std::pair<QVector3D, QVector3D>
|
||||||
camera_normal (const QMatrix4x4 &camera_trans, double x, double y);
|
camera_normal (const QMatrix4x4 &camera_trans, double x, double y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Normalizes a scene transformation
|
||||||
|
*
|
||||||
|
* Scene transformations consist of a scaling and displacement. Both are
|
||||||
|
* interchangeable to some extent under the presence of a perspective
|
||||||
|
* transformation (further away makes the scene smaller). This normalization
|
||||||
|
* tries to find a displacement which has "ztarget" target value for z. Without normalization
|
||||||
|
* the scene tends to "move away" with respect to z.
|
||||||
|
*/
|
||||||
|
LAY_PLUGIN_PUBLIC void
|
||||||
|
normalize_scene_trans (const QMatrix4x4 &cam_trans, QVector3D &displacement, double &scale, double ztarget = 0.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
|
|
@ -44,14 +45,13 @@ namespace lay
|
||||||
|
|
||||||
D25ViewWidget::D25ViewWidget (QWidget *parent)
|
D25ViewWidget::D25ViewWidget (QWidget *parent)
|
||||||
: QOpenGLWidget (parent),
|
: QOpenGLWidget (parent),
|
||||||
m_shapes_program (0), m_dragging (false), m_rotating (false), m_cam_azimuth (0.0), m_cam_elevation (0.0)
|
m_shapes_program (0), m_dragging (false), m_rotating (false), m_cam_azimuth (0.0), m_cam_elevation (0.0), m_top_view (false)
|
||||||
{
|
{
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
format.setDepthBufferSize (24);
|
format.setDepthBufferSize (24);
|
||||||
format.setSamples (4); // more -> widget extends beyond boundary!
|
format.setSamples (4); // more -> widget extends beyond boundary!
|
||||||
setFormat (format);
|
setFormat (format);
|
||||||
|
|
||||||
m_cam_position = QVector3D (0.0, 0.0, 4.0); // @@@
|
|
||||||
m_scale_factor = 1.0;
|
m_scale_factor = 1.0;
|
||||||
m_focus_dist = 0.0;
|
m_focus_dist = 0.0;
|
||||||
}
|
}
|
||||||
|
|
@ -183,48 +183,87 @@ D25ViewWidget::initializeGL ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QVector3D cam_direction (double azimuth, double elevation)
|
|
||||||
{
|
|
||||||
// positive azimuth: camera looks left
|
|
||||||
// positive elevation: camera looks up
|
|
||||||
double y = sin (elevation * M_PI / 180.0);
|
|
||||||
double r = cos (elevation * M_PI / 180.0);
|
|
||||||
double x = r * sin (azimuth * M_PI / 180.0);
|
|
||||||
double z = r * cos (azimuth * M_PI / 180.0);
|
|
||||||
return QVector3D (x, y, -z);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
D25ViewWidget::wheelEvent (QWheelEvent *event)
|
D25ViewWidget::wheelEvent (QWheelEvent *event)
|
||||||
{
|
{
|
||||||
double px = (event->pos ().x () - width () / 2) * 2.0 / width ();
|
double px = (event->pos ().x () - width () / 2) * 2.0 / width ();
|
||||||
double py = -(event->pos ().y () - height () / 2) * 2.0 / height ();
|
double py = -(event->pos ().y () - height () / 2) * 2.0 / height ();
|
||||||
|
|
||||||
double f = exp (event->angleDelta ().y () * (1.0 / (90 * 8)));
|
|
||||||
|
|
||||||
// compute vector of line of sight
|
// compute vector of line of sight
|
||||||
std::pair<QVector3D, QVector3D> ray = camera_normal (m_cam_trans, px, py);
|
std::pair<QVector3D, QVector3D> ray = camera_normal (m_cam_trans, px, py);
|
||||||
|
|
||||||
// by definition the ray goes through the camera position
|
// by definition the ray goes through the camera position
|
||||||
std::pair<bool, QVector3D> hp = hit_point_with_scene (m_cam_position, ray.second);
|
float focal_length = 2.0;
|
||||||
|
QVector3D hp = hit_point_with_scene (cam_position () + focal_length * ray.second, ray.second);
|
||||||
|
|
||||||
QVector3D pm = m_cam_trans.map(hp.second);
|
if (false /*@@@*/ && (event->modifiers () & Qt::ShiftModifier)) {
|
||||||
printf("@@@ mouse=%g,%g back=%g,%g\n", px, py, pm.x(), pm.y());
|
|
||||||
printf("@@@ before: hp=%g,%g,%g d=%g,%g,%g s=%g\n", hp.second.x(), hp.second.y(), hp.second.z(), m_displacement.x(), m_displacement.y(), m_displacement.z(), m_scale_factor); fflush(stdout);
|
|
||||||
|
|
||||||
m_displacement = hp.second * (1.0 - f) + m_displacement * f;
|
// "Shift" is closeup
|
||||||
m_scale_factor *= f;
|
|
||||||
|
double f = event->angleDelta ().y () * (1.0 / (90 * 8));
|
||||||
|
m_displacement += -f * cam_position ().length () * ray.second;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// No shift is zoom
|
||||||
|
|
||||||
|
double f = exp (event->angleDelta ().y () * (1.0 / (90 * 8)));
|
||||||
|
|
||||||
|
QVector3D initial_displacement = m_displacement;
|
||||||
|
QVector3D displacement = m_displacement;
|
||||||
|
|
||||||
|
displacement = hp * (1.0 - f) + displacement * f;
|
||||||
|
m_scale_factor *= f;
|
||||||
|
|
||||||
|
// normalize the scene translation so the scene does not "flee"
|
||||||
|
|
||||||
|
QMatrix4x4 ct;
|
||||||
|
ct.rotate (-cam_elevation (), 1.0, 0.0, 0.0);
|
||||||
|
ct.rotate (cam_azimuth (), 0.0, 1.0, 0.0);
|
||||||
|
ct.translate (-cam_position ());
|
||||||
|
|
||||||
|
initial_displacement = ct.map (initial_displacement);
|
||||||
|
displacement = ct.map (displacement);
|
||||||
|
|
||||||
|
lay::normalize_scene_trans (m_cam_trans, displacement, m_scale_factor, initial_displacement.z ());
|
||||||
|
|
||||||
|
m_displacement = ct.inverted ().map (displacement);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
update_cam_trans ();
|
update_cam_trans ();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, QVector3D>
|
void
|
||||||
|
D25ViewWidget::keyPressEvent (QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key () == Qt::Key_Shift) {
|
||||||
|
m_top_view = true;
|
||||||
|
update_cam_trans ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
D25ViewWidget::keyReleaseEvent (QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key () == Qt::Key_Shift) {
|
||||||
|
m_top_view = false;
|
||||||
|
update_cam_trans ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D
|
||||||
D25ViewWidget::hit_point_with_scene (const QVector3D &line, const QVector3D &line_dir)
|
D25ViewWidget::hit_point_with_scene (const QVector3D &line, const QVector3D &line_dir)
|
||||||
{
|
{
|
||||||
QVector3D corner = QVector3D (m_bbox.left (), m_zmin, -(m_bbox.bottom () + m_bbox.height ())) * m_scale_factor + m_displacement;
|
QVector3D corner = QVector3D (m_bbox.left (), m_zmin, -(m_bbox.bottom () + m_bbox.height ())) * m_scale_factor + m_displacement;
|
||||||
QVector3D dim = QVector3D (m_bbox.width (), m_zmax - m_zmin, m_bbox.height ()) * m_scale_factor;
|
QVector3D dim = QVector3D (m_bbox.width (), m_zmax - m_zmin, m_bbox.height ()) * m_scale_factor;
|
||||||
|
|
||||||
return lay::hit_point_with_cuboid (line, line_dir, corner, dim);
|
std::pair<bool, QVector3D> hp = lay::hit_point_with_cuboid (line, line_dir, corner, dim);
|
||||||
|
if (! hp.first) {
|
||||||
|
return line;
|
||||||
|
} else {
|
||||||
|
return hp.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -238,20 +277,19 @@ D25ViewWidget::mousePressEvent (QMouseEvent *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_start_pos = event->pos ();
|
m_start_pos = event->pos ();
|
||||||
m_start_cam_position = m_cam_position;
|
m_start_cam_position = cam_position ();
|
||||||
m_start_cam_azimuth = m_cam_azimuth;
|
m_start_cam_azimuth = cam_azimuth ();
|
||||||
m_start_cam_elevation = m_cam_elevation;
|
m_start_cam_elevation = cam_elevation ();
|
||||||
m_start_displacement = m_displacement;
|
m_start_displacement = m_displacement;
|
||||||
|
|
||||||
m_focus_dist = 2.0;
|
m_focus_dist = 2.0;
|
||||||
|
|
||||||
if (m_dragging || m_rotating) {
|
if (m_dragging || m_rotating) {
|
||||||
|
|
||||||
QVector3D cd = cam_direction (m_start_cam_azimuth, m_start_cam_elevation);
|
QVector3D cd = cam_direction ();
|
||||||
std::pair<bool, QVector3D> hp = hit_point_with_scene (m_cam_position, cd);
|
QVector3D cp = cam_position ();
|
||||||
if (hp.first) {
|
QVector3D hp = hit_point_with_scene (cp + m_focus_dist * cd, cd);
|
||||||
m_focus_dist = std::max (m_focus_dist, double ((m_cam_position - hp.second).length ()));
|
m_focus_dist = std::max (m_focus_dist, double ((cp - hp).length ()));
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,9 +313,9 @@ D25ViewWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
double dx = d.x () * f;
|
double dx = d.x () * f;
|
||||||
double dy = -d.y () * f;
|
double dy = -d.y () * f;
|
||||||
|
|
||||||
QVector3D xv (cos (m_start_cam_azimuth * M_PI / 180.0), 0.0, -sin (m_start_cam_azimuth * M_PI / 180.0));
|
QVector3D xv (cos (cam_azimuth () * M_PI / 180.0), 0.0, -sin (cam_azimuth () * M_PI / 180.0));
|
||||||
double re = sin (m_start_cam_elevation * M_PI / 180.0);
|
double re = sin (cam_elevation () * M_PI / 180.0);
|
||||||
QVector3D yv (-re * xv.z (), cos (m_start_cam_elevation * M_PI / 180.0), re * xv.x ());
|
QVector3D yv (-re * xv.z (), cos (cam_elevation () * M_PI / 180.0), re * xv.x ());
|
||||||
QVector3D drag = xv * dx + yv * dy;
|
QVector3D drag = xv * dx + yv * dy;
|
||||||
|
|
||||||
m_displacement = m_start_displacement + drag;
|
m_displacement = m_start_displacement + drag;
|
||||||
|
|
@ -286,6 +324,8 @@ D25ViewWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
|
|
||||||
} else if (m_rotating) {
|
} else if (m_rotating) {
|
||||||
|
|
||||||
|
// @@@ needs redo ...
|
||||||
|
// @@@ consider m_top_view
|
||||||
double focus_dist = 4.0; // @@@
|
double focus_dist = 4.0; // @@@
|
||||||
|
|
||||||
QPoint d = event->pos () - m_start_pos;
|
QPoint d = event->pos () - m_start_pos;
|
||||||
|
|
@ -296,30 +336,64 @@ D25ViewWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
m_cam_elevation = m_start_cam_elevation + ay;
|
m_cam_elevation = m_start_cam_elevation + ay;
|
||||||
m_cam_azimuth = m_start_cam_azimuth + ax;
|
m_cam_azimuth = m_start_cam_azimuth + ax;
|
||||||
|
|
||||||
m_cam_position = (cam_direction (m_cam_azimuth, m_cam_elevation) * -focus_dist) + cam_direction (m_start_cam_azimuth, m_start_cam_elevation) * focus_dist + m_start_cam_position;
|
|
||||||
|
|
||||||
update_cam_trans ();
|
update_cam_trans ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector3D
|
||||||
|
D25ViewWidget::cam_direction () const
|
||||||
|
{
|
||||||
|
double azimuth = cam_azimuth ();
|
||||||
|
double elevation = cam_elevation ();
|
||||||
|
|
||||||
|
// positive azimuth: camera looks left
|
||||||
|
// positive elevation: camera looks up
|
||||||
|
double y = sin (elevation * M_PI / 180.0);
|
||||||
|
double r = cos (elevation * M_PI / 180.0);
|
||||||
|
double x = r * sin (azimuth * M_PI / 180.0);
|
||||||
|
double z = r * cos (azimuth * M_PI / 180.0);
|
||||||
|
return QVector3D (x, y, -z);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D
|
||||||
|
D25ViewWidget::cam_position () const
|
||||||
|
{
|
||||||
|
double focus_dist = 4.0;
|
||||||
|
return cam_direction () * -focus_dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
D25ViewWidget::cam_azimuth () const
|
||||||
|
{
|
||||||
|
return m_cam_azimuth;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
D25ViewWidget::cam_elevation () const
|
||||||
|
{
|
||||||
|
return m_top_view ? -90.0 : m_cam_elevation;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
D25ViewWidget::update_cam_trans ()
|
D25ViewWidget::update_cam_trans ()
|
||||||
{
|
{
|
||||||
printf("@@@ e=%g a=%g x,y,z=%g,%g,%g d=%g,%g,%g s=%g f=%g\n", m_cam_elevation, m_cam_azimuth, m_cam_position.x(), m_cam_position.y(), m_cam_position.z(), m_displacement.x(), m_displacement.y(), m_displacement.z(), m_scale_factor, m_focus_dist); fflush(stdout);
|
QVector3D cp = cam_position ();
|
||||||
|
|
||||||
|
printf("@@@ e=%g a=%g x,y,z=%g,%g,%g d=%g,%g,%g s=%g f=%g\n", cam_elevation (), cam_azimuth (), cp.x(), cp.y(), cp.z(), m_displacement.x(), m_displacement.y(), m_displacement.z(), m_scale_factor, m_focus_dist); fflush(stdout);
|
||||||
QMatrix4x4 t;
|
QMatrix4x4 t;
|
||||||
|
|
||||||
// finally add perspective
|
// finally add perspective
|
||||||
t.perspective (60.0f, float (width ()) / float (height ()), 0.1f, 100.0f);
|
t.perspective (60.0f, float (width ()) / float (height ()), 0.1f, 100.0f);
|
||||||
|
|
||||||
// third: elevation
|
// third: elevation
|
||||||
t.rotate (-m_cam_elevation, 1.0, 0.0, 0.0);
|
t.rotate (-cam_elevation (), 1.0, 0.0, 0.0);
|
||||||
|
|
||||||
// second: azimuth
|
// second: azimuth
|
||||||
t.rotate (m_cam_azimuth, 0.0, 1.0, 0.0);
|
t.rotate (cam_azimuth (), 0.0, 1.0, 0.0);
|
||||||
|
|
||||||
// first: translate the origin into the cam's position
|
// first: translate the origin into the cam's position
|
||||||
t.translate (-m_cam_position);
|
t.translate (-cam_position ());
|
||||||
|
|
||||||
m_cam_trans = t;
|
m_cam_trans = t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ public:
|
||||||
D25ViewWidget (QWidget *parent);
|
D25ViewWidget (QWidget *parent);
|
||||||
~D25ViewWidget ();
|
~D25ViewWidget ();
|
||||||
|
|
||||||
|
void keyPressEvent (QKeyEvent *event);
|
||||||
|
void keyReleaseEvent (QKeyEvent *event);
|
||||||
void wheelEvent (QWheelEvent *event);
|
void wheelEvent (QWheelEvent *event);
|
||||||
void mousePressEvent (QMouseEvent *event);
|
void mousePressEvent (QMouseEvent *event);
|
||||||
void mouseReleaseEvent (QMouseEvent *event);
|
void mouseReleaseEvent (QMouseEvent *event);
|
||||||
|
|
@ -70,9 +72,9 @@ private:
|
||||||
QOpenGLShaderProgram *m_shapes_program, *m_gridplane_program;
|
QOpenGLShaderProgram *m_shapes_program, *m_gridplane_program;
|
||||||
QMatrix4x4 m_cam_trans;
|
QMatrix4x4 m_cam_trans;
|
||||||
bool m_dragging, m_rotating;
|
bool m_dragging, m_rotating;
|
||||||
QVector3D m_cam_position;
|
|
||||||
double m_scale_factor;
|
double m_scale_factor;
|
||||||
double m_cam_azimuth, m_cam_elevation;
|
double m_cam_azimuth, m_cam_elevation;
|
||||||
|
bool m_top_view;
|
||||||
QVector3D m_displacement;
|
QVector3D m_displacement;
|
||||||
double m_focus_dist;
|
double m_focus_dist;
|
||||||
QPoint m_start_pos;
|
QPoint m_start_pos;
|
||||||
|
|
@ -101,7 +103,11 @@ private:
|
||||||
void render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, unsigned int layer, double zstart, double zstop);
|
void render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, unsigned int layer, double zstart, double zstop);
|
||||||
void render_polygon (D25ViewWidget::chunks_type &chunks, const db::Polygon &poly, double dbu, double zstart, double zstop);
|
void render_polygon (D25ViewWidget::chunks_type &chunks, const db::Polygon &poly, double dbu, double zstart, double zstop);
|
||||||
void render_wall (D25ViewWidget::chunks_type &chunks, const db::Edge &poly, double dbu, double zstart, double zstop);
|
void render_wall (D25ViewWidget::chunks_type &chunks, const db::Edge &poly, double dbu, double zstart, double zstop);
|
||||||
std::pair<bool, QVector3D> hit_point_with_scene (const QVector3D &line, const QVector3D &line_dir);
|
QVector3D hit_point_with_scene(const QVector3D &line, const QVector3D &line_dir);
|
||||||
|
double cam_elevation () const;
|
||||||
|
double cam_azimuth () const;
|
||||||
|
QVector3D cam_position () const;
|
||||||
|
QVector3D cam_direction () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,3 +166,65 @@ TEST(5_CameraNormal)
|
||||||
p = matrix.map (ray.first + ray.second * 1000.0);
|
p = matrix.map (ray.first + ray.second * 1000.0);
|
||||||
EXPECT_EQ (v2s_2d (p), "0,1");
|
EXPECT_EQ (v2s_2d (p), "0,1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(6_NormalizeSceneTrans)
|
||||||
|
{
|
||||||
|
QMatrix4x4 cam;
|
||||||
|
cam.perspective (60.0f, 1.5, 0.1f, 100.0f);
|
||||||
|
cam.rotate (22.0, 1.0, 0.0, 0.0);
|
||||||
|
cam.rotate (-15.0, 0.0, 1.0, 0.0);
|
||||||
|
cam.translate (QVector3D (0.0, 0.0, 4.0));
|
||||||
|
|
||||||
|
double scale = 0.1;
|
||||||
|
QVector3D displacement (-0.5, 0.2, 2.0);
|
||||||
|
|
||||||
|
QMatrix4x4 scene1;
|
||||||
|
scene1.translate (displacement);
|
||||||
|
scene1.scale (scale);
|
||||||
|
|
||||||
|
QVector3D v1 = (cam * scene1).map (QVector3D (1.0, -1.0, 2.0));
|
||||||
|
v1.setZ (0);
|
||||||
|
QVector3D v2 = (cam * scene1).map (QVector3D (0.0, 0.0, 5.0));
|
||||||
|
v2.setZ (0);
|
||||||
|
QVector3D v3 = (cam * scene1).map (QVector3D (-1.0, 0.0, 1.0));
|
||||||
|
v3.setZ (0);
|
||||||
|
|
||||||
|
lay::normalize_scene_trans (cam, displacement, scale);
|
||||||
|
|
||||||
|
QMatrix4x4 scene2;
|
||||||
|
scene2.translate (displacement);
|
||||||
|
scene2.scale (scale);
|
||||||
|
|
||||||
|
EXPECT_EQ (tl::sprintf ("%.4f", scale), "0.0667");
|
||||||
|
|
||||||
|
QVector3D u1 = (cam * scene2).map (QVector3D (1.0, -1.0, 2.0));
|
||||||
|
u1.setZ (0);
|
||||||
|
QVector3D u2 = (cam * scene2).map (QVector3D (0.0, 0.0, 5.0));
|
||||||
|
u2.setZ (0);
|
||||||
|
QVector3D u3 = (cam * scene2).map (QVector3D (-1.0, 0.0, 1.0));
|
||||||
|
u3.setZ (0);
|
||||||
|
|
||||||
|
EXPECT_EQ ((u1 - v1).length () < 1e-4, true);
|
||||||
|
EXPECT_EQ ((u2 - v2).length () < 1e-4, true);
|
||||||
|
EXPECT_EQ ((u3 - v3).length () < 1e-4, true);
|
||||||
|
|
||||||
|
lay::normalize_scene_trans (cam, displacement, scale, 1.0);
|
||||||
|
|
||||||
|
QMatrix4x4 scene3;
|
||||||
|
scene3.translate (displacement);
|
||||||
|
scene3.scale (scale);
|
||||||
|
|
||||||
|
EXPECT_EQ (tl::sprintf ("%.4f", scale), "0.0833");
|
||||||
|
EXPECT_EQ (tl::to_string (displacement.z ()), "1");
|
||||||
|
|
||||||
|
QVector3D uu1 = (cam * scene2).map (QVector3D (1.0, -1.0, 2.0));
|
||||||
|
uu1.setZ (0);
|
||||||
|
QVector3D uu2 = (cam * scene2).map (QVector3D (0.0, 0.0, 5.0));
|
||||||
|
uu2.setZ (0);
|
||||||
|
QVector3D uu3 = (cam * scene2).map (QVector3D (-1.0, 0.0, 1.0));
|
||||||
|
uu3.setZ (0);
|
||||||
|
|
||||||
|
EXPECT_EQ ((uu1 - v1).length () < 1e-4, true);
|
||||||
|
EXPECT_EQ ((uu2 - v2).length () < 1e-4, true);
|
||||||
|
EXPECT_EQ ((uu3 - v3).length () < 1e-4, true);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue