git-svn-id: svn://db.shs.com.ru/libs@638 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-12-02 20:09:18 +00:00
parent 385070f70f
commit 35668c13fc
15 changed files with 792 additions and 263 deletions

View File

@@ -0,0 +1,434 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gltransform.h"
//#include <Qt3DCore/private/sqt_p.h>
#include "gltypes.h"
#include <cmath>
inline void composeQMatrix4x4(const QVector3D & position, const QVector3D & orientation, const QVector3D & scale, QMatrix4x4 &m) {
const QMatrix3x3 rot3x3(Transform::toRotationMatrix(orientation));
// set up final matrix with scale, rotation and translation
m(0, 0) = scale.x() * rot3x3(0, 0); m(0, 1) = scale.y() * rot3x3(0, 1); m(0, 2) = scale.z() * rot3x3(0, 2); m(0, 3) = position.x();
m(1, 0) = scale.x() * rot3x3(1, 0); m(1, 1) = scale.y() * rot3x3(1, 1); m(1, 2) = scale.z() * rot3x3(1, 2); m(1, 3) = position.y();
m(2, 0) = scale.x() * rot3x3(2, 0); m(2, 1) = scale.y() * rot3x3(2, 1); m(2, 2) = scale.z() * rot3x3(2, 2); m(2, 3) = position.z();
// no projection term
m(3, 0) = 0.0f; m(3, 1) = 0.0f; m(3, 2) = 0.0f; m(3, 3) = 1.0f;
}
inline void decomposeQMatrix3x3(const QMatrix3x3 & m, QMatrix3x3 & Q, QVector3D & D, QVector3D & U) {
// Factor M = QR = QDU where Q is orthogonal, D is diagonal,
// and U is upper triangular with ones on its diagonal.
// Algorithm uses Gram-Schmidt orthogonalization (the QR algorithm).
//
// If M = [ m0 | m1 | m2 ] and Q = [ q0 | q1 | q2 ], then
// q0 = m0/|m0|
// q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0|
// q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1|
//
// where |V| indicates length of vector V and A*B indicates dot
// product of vectors A and B. The matrix R has entries
//
// r00 = q0*m0 r01 = q0*m1 r02 = q0*m2
// r10 = 0 r11 = q1*m1 r12 = q1*m2
// r20 = 0 r21 = 0 r22 = q2*m2
//
// so D = diag(r00,r11,r22) and U has entries u01 = r01/r00,
// u02 = r02/r00, and u12 = r12/r11.
// Q = rotation
// D = scaling
// U = shear
// D stores the three diagonal entries r00, r11, r22
// U stores the entries U[0] = u01, U[1] = u02, U[2] = u12
// build orthogonal matrix Q
float invLen = 1.0f / std::sqrt(m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0));
Q(0, 0) = m(0, 0) * invLen;
Q(1, 0) = m(1, 0) * invLen;
Q(2, 0) = m(2, 0) * invLen;
float dot = Q(0, 0) * m(0, 1) + Q(1, 0) * m(1, 1) + Q(2, 0) * m(2, 1);
Q(0, 1) = m(0, 1) - dot * Q(0, 0);
Q(1, 1) = m(1, 1) - dot * Q(1, 0);
Q(2, 1) = m(2, 1) - dot * Q(2, 0);
invLen = 1.0f / std::sqrt(Q(0, 1) * Q(0, 1) + Q(1, 1) * Q(1, 1) + Q(2, 1) * Q(2, 1));
Q(0, 1) *= invLen;
Q(1, 1) *= invLen;
Q(2, 1) *= invLen;
dot = Q(0, 0) * m(0, 2) + Q(1, 0) * m(1, 2) + Q(2, 0) * m(2, 2);
Q(0, 2) = m(0, 2) - dot * Q(0, 0);
Q(1, 2) = m(1, 2) - dot * Q(1, 0);
Q(2, 2) = m(2, 2) - dot * Q(2, 0);
dot = Q(0, 1) * m(0, 2) + Q(1, 1) * m(1, 2) + Q(2, 1) * m(2, 2);
Q(0, 2) -= dot * Q(0, 1);
Q(1, 2) -= dot * Q(1, 1);
Q(2, 2) -= dot * Q(2, 1);
invLen = 1.0f / std::sqrt(Q(0, 2) * Q(0, 2) + Q(1, 2) * Q(1, 2) + Q(2, 2) * Q(2, 2));
Q(0, 2) *= invLen;
Q(1, 2) *= invLen;
Q(2, 2) *= invLen;
// guarantee that orthogonal matrix has determinant 1 (no reflections)
const float det = Q(0, 0) * Q(1, 1) * Q(2, 2) + Q(0, 1) * Q(1, 2) * Q(2, 0) +
Q(0, 2) * Q(1, 0) * Q(2, 1) - Q(0, 2) * Q(1, 1) * Q(2, 0) -
Q(0, 1) * Q(1, 0) * Q(2, 2) - Q(0, 0) * Q(1, 2) * Q(2, 1);
if (det < 0.0f)
Q *= -1.0f;
// build "right" matrix R
QMatrix3x3 R(Qt::Uninitialized);
R(0, 0) = Q(0, 0) * m(0, 0) + Q(1, 0) * m(1, 0) + Q(2, 0) * m(2, 0);
R(0, 1) = Q(0, 0) * m(0, 1) + Q(1, 0) * m(1, 1) + Q(2, 0) * m(2, 1);
R(1, 1) = Q(0, 1) * m(0, 1) + Q(1, 1) * m(1, 1) + Q(2, 1) * m(2, 1);
R(0, 2) = Q(0, 0) * m(0, 2) + Q(1, 0) * m(1, 2) + Q(2, 0) * m(2, 2);
R(1, 2) = Q(0, 1) * m(0, 2) + Q(1, 1) * m(1, 2) + Q(2, 1) * m(2, 2);
R(2, 2) = Q(0, 2) * m(0, 2) + Q(1, 2) * m(1, 2) + Q(2, 2) * m(2, 2);
// the scaling component
D[0] = R(0, 0);
D[1] = R(1, 1);
D[2] = R(2, 2);
// the shear component
U[0] = R(0, 1) / D[0];
U[1] = R(0, 2) / D[0];
U[2] = R(1, 2) / D[1];
}
inline bool hasScale(const QMatrix4x4 &m) {
// If the columns are orthonormal and form a right-handed system, then there is no scale
float t(m.determinant());
if (!qFuzzyIsNull(t - 1.0f))
return true;
t = m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0);
if (!qFuzzyIsNull(t - 1.0f))
return true;
t = m(0, 1) * m(0, 1) + m(1, 1) * m(1, 1) + m(2, 1) * m(2, 1);
if (!qFuzzyIsNull(t - 1.0f))
return true;
t = m(0, 2) * m(0, 2) + m(1, 2) * m(1, 2) + m(2, 2) * m(2, 2);
if (!qFuzzyIsNull(t - 1.0f))
return true;
return false;
}
inline void decomposeQMatrix4x4(const QMatrix4x4 & m, QVector3D & position, QVector3D & orientation, QVector3D & scale) {
Q_ASSERT(m.isAffine());
const QMatrix3x3 m3x3(m.toGenericMatrix<3, 3>());
QMatrix3x3 rot3x3(Qt::Uninitialized);
if (hasScale(m)) {
decomposeQMatrix3x3(m3x3, rot3x3, scale, position);
} else {
// we know there is no scaling part; no need for QDU decomposition
scale = QVector3D(1.0f, 1.0f, 1.0f);
rot3x3 = m3x3;
}
orientation = Transform::fromRotationMatrix(rot3x3);
position = QVector3D(m(0, 3), m(1, 3), m(2, 3));
}
Transform::Transform(): m_scale(1.0f, 1.0f, 1.0f),
m_translation(), m_eulerRotationAngles(), m_matrixDirty(false) {
}
void Transform::setMatrix(const QMatrix4x4 & m) {
if (m != matrix()) {
m_matrix = m;
m_matrixDirty = false;
QVector3D s;
QVector3D t;
QVector3D r;
decomposeQMatrix4x4(m, t, r, s);
m_scale = s;
m_translation = t;
m_eulerRotationAngles = r;
}
}
void Transform::setRotationX(float r) {
if (m_eulerRotationAngles.x() == r)
return;
m_eulerRotationAngles.setX(r);
m_matrixDirty = true;
}
void Transform::setRotationY(float r) {
if (m_eulerRotationAngles.y() == r)
return;
m_eulerRotationAngles.setY(r);
m_matrixDirty = true;
}
void Transform::setRotationZ(float r) {
if (m_eulerRotationAngles.z() == r)
return;
m_eulerRotationAngles.setZ(r);
m_matrixDirty = true;
}
QMatrix4x4 Transform::matrix() const {
buildMatrix();
return m_matrix;
}
QMatrix4x4 Transform::matrixRotate() const {
buildMatrix();
return m_matrixR;
}
QMatrix4x4 Transform::matrixScale() const {
buildMatrix();
return m_matrixS;
}
QMatrix4x4 Transform::matrixRotateScale() const {
buildMatrix();
return m_matrixWT;
}
QVector3D Transform::direction() const {
return matrixRotate().mapVector(QVector3D(0,0,-1)).normalized();
}
void Transform::buildMatrix() const {
if (m_matrixDirty) {
composeQMatrix4x4(m_translation, m_eulerRotationAngles, m_scale, m_matrix);
composeQMatrix4x4(QVector3D(), m_eulerRotationAngles, m_scale, m_matrixWT);
composeQMatrix4x4(QVector3D(), m_eulerRotationAngles, QVector3D(1,1,1), m_matrixR);
composeQMatrix4x4(QVector3D(), QVector3D(), m_scale, m_matrixS);
m_matrixDirty = false;
}
}
float Transform::rotationX() const {
return m_eulerRotationAngles.x();
}
float Transform::rotationY() const {
return m_eulerRotationAngles.y();
}
float Transform::rotationZ() const {
return m_eulerRotationAngles.z();
}
void Transform::setScale(const QVector3D & s) {
if (s != m_scale) {
m_scale = s;
m_matrixDirty = true;
}
}
void Transform::setScaleX(float s) {
if (s != m_scale.x()) {
m_scale.setX(s);
m_matrixDirty = true;
}
}
void Transform::setScaleY(float s) {
if (s != m_scale.y()) {
m_scale.setY(s);
m_matrixDirty = true;
}
}
void Transform::setScaleZ(float s) {
if (s != m_scale.z()) {
m_scale.setZ(s);
m_matrixDirty = true;
}
}
QVector3D Transform::scale3D() const {
return m_scale;
}
float Transform::scale() const {
return m_scale.x();
}
void Transform::setRotation(const QVector3D & r) {
if (r != m_eulerRotationAngles) {
m_eulerRotationAngles = r;
m_matrixDirty = true;
}
}
QVector3D Transform::rotation() const {
return m_eulerRotationAngles;
}
void Transform::setTranslation(const QVector3D & t) {
if (t != m_translation) {
m_translation = t;
m_matrixDirty = true;
}
}
void Transform::setTranslationX(float t) {
if (t != m_translation.x()) {
m_translation.setX(t);
m_matrixDirty = true;
}
}
void Transform::setTranslationY(float t) {
if (t != m_translation.y()) {
m_translation.setY(t);
m_matrixDirty = true;
}
}
void Transform::setTranslationZ(float t) {
if (t != m_translation.z()) {
m_translation.setZ(t);
m_matrixDirty = true;
}
}
QVector3D Transform::translation() const {
return m_translation;
}
QQuaternion Transform::fromAxisAndAngle(const QVector3D & axis, float angle) {
return QQuaternion::fromAxisAndAngle(axis, angle);
}
QQuaternion Transform::fromAxisAndAngle(float x, float y, float z, float angle) {
return QQuaternion::fromAxisAndAngle(x, y, z, angle);
}
QQuaternion Transform::fromAxesAndAngles(const QVector3D & axis1, float angle1,
const QVector3D & axis2, float angle2) {
const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1);
const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2);
return q2 * q1;
}
QQuaternion Transform::fromAxesAndAngles(const QVector3D & axis1, float angle1,
const QVector3D & axis2, float angle2,
const QVector3D & axis3, float angle3) {
const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1);
const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2);
const QQuaternion q3 = QQuaternion::fromAxisAndAngle(axis3, angle3);
return q3 * q2 * q1;
}
QQuaternion Transform::fromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis) {
return QQuaternion::fromAxes(xAxis, yAxis, zAxis);
}
QVector3D Transform::fromDirection(QVector3D d) {
QVector3D ret;
//QMatrix3x3 m = QQuaternion::fromDirection(d, QVector3D()).toRotationMatrix();
//ret[0] = -atan2(m(0, 2), m(1, 2));
//ret[1] = acos (m(2, 2));
//ret[2] = atan2(m(2, 0), m(2, 1));
d.normalize();
ret[0] = M_PI - acos(d.z());
ret[2] = -atan2(d.x(), d.y());
return ret * rad2deg;
}
QVector3D Transform::fromRotationMatrix(const QMatrix3x3 & m) {
//return QQuaternion::fromRotationMatrix(m);
float sy = sqrt(m(0,0) * m(0,0) + m(1,0) * m(1,0));
bool singular = sy < 1.E-6; // If
float x, y, z;
if (!singular) {
x = atan2( m(2,1), m(2,2));
y = atan2(-m(2,0), sy);
z = atan2( m(1,0), m(0,0));
} else {
x = atan2(-m(1,2), m(1,1));
y = atan2(-m(2,0), sy);
z = 0.;
}
return QVector3D(x, y, z) * rad2deg;
}
QMatrix3x3 Transform::toRotationMatrix(const QVector3D & r) {
QMatrix4x4 m;
if (r.z() != 0.f) m.rotate(r.z(), 0., 0., 1.);
if (r.y() != 0.f) m.rotate(r.y(), 0., 1., 0.);
if (r.x() != 0.f) m.rotate(r.x(), 1., 0., 0.);
return m.toGenericMatrix<3,3>();
}
QMatrix4x4 Transform::rotateAround(const QVector3D & point, float angle, const QVector3D & axis) {
QMatrix4x4 m;
m.translate(point);
m.rotate(angle, axis);
m.translate(-point);
return m;
}
QMatrix4x4 Transform::rotateFromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis) {
return QMatrix4x4(xAxis.x(), yAxis.x(), zAxis.x(), 0.0f,
xAxis.y(), yAxis.y(), zAxis.y(), 0.0f,
xAxis.z(), yAxis.z(), zAxis.z(), 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
}

View File

@@ -0,0 +1,117 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLTRANSFORM_H
#define GLTRANSFORM_H
#include <QMatrix4x4>
#include <QQuaternion>
#include <QVector3D>
#include <chunkstream.h>
class Transform {
friend QDataStream & operator >>(QDataStream & s, Transform & v);
public:
Transform();
float scale() const;
QVector3D scale3D() const;
QVector3D rotation() const;
QVector3D translation() const;
QMatrix4x4 matrix() const;
QMatrix4x4 matrixRotate() const;
QMatrix4x4 matrixScale() const;
QMatrix4x4 matrixRotateScale() const;
QVector3D direction() const;
float rotationX() const;
float rotationY() const;
float rotationZ() const;
void setScale(float s) {setScale(QVector3D(s, s, s));}
void setScale(const QVector3D & s);
void setScaleX(float s);
void setScaleY(float s);
void setScaleZ(float s);
void setRotation(const QVector3D & r);
void setRotationX(float r);
void setRotationY(float r);
void setRotationZ(float r);
void setTranslation(const QVector3D & t);
void setTranslationX(float t);
void setTranslationY(float t);
void setTranslationZ(float t);
void setMatrix(const QMatrix4x4 & matrix);
static QQuaternion fromAxisAndAngle(const QVector3D & axis, float angle);
static QQuaternion fromAxisAndAngle(float x, float y, float z, float angle);
static QQuaternion fromAxesAndAngles(const QVector3D & axis1, float angle1,
const QVector3D & axis2, float angle2);
static QQuaternion fromAxesAndAngles(const QVector3D & axis1, float angle1,
const QVector3D & axis2, float angle2,
const QVector3D & axis3, float angle3);
static QQuaternion fromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis);
static QVector3D fromDirection(QVector3D d);
static QVector3D fromRotationMatrix(const QMatrix3x3 & m);
static QMatrix3x3 toRotationMatrix(const QVector3D & r);
static QMatrix4x4 rotateAround(const QVector3D & point, float angle, const QVector3D & axis);
static QMatrix4x4 rotateFromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis);
protected:
void buildMatrix() const;
QVector3D m_scale;
QVector3D m_translation;
QVector3D m_eulerRotationAngles;
mutable QMatrix4x4 m_matrix, m_matrixWT, m_matrixR, m_matrixS;
mutable bool m_matrixDirty;
};
inline QDataStream & operator <<(QDataStream & s, const Transform & v) {
//ChunkStream cs;
//cs.add(1, v.matrix());
//s << cs.data(); return s;
s << v.matrix(); return s;
}
inline QDataStream & operator >>(QDataStream & s, Transform & v) {
//ChunkStream cs(s);
//while (!cs.atEnd()) {
// switch (cs.read()) {
// case 1: v.setMatrix(cs.getData<QMatrix4x4>()); break;
// }
//}
//return s;
QMatrix4x4 m;
s >> m;
v.setMatrix(m);
v.m_matrixDirty = true;
return s;
}
#endif // QT3DCORE_QTRANSFORM_H

View File

@@ -113,7 +113,7 @@ ObjectBase * assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, con
} else
ret = new ObjectBase();
ret->setName(name);
ret->setTransform(fromAiMatrix4D(n->mTransformation));
ret->setMatrix(fromAiMatrix4D(n->mTransformation));
//qDebug() << "add object" << ret << ret->name();
if (!light) {
for (uint i = 0; i < n->mNumMeshes; ++i) {

View File

@@ -25,7 +25,7 @@ Camera::Camera() {
fov_ = 60.;
angle_limit_lower_xy = 0.f;
angle_limit_upper_xy = 360.f;
angles_.setY(270.f);
//setRotationX(90.f);
depth_start = 0.1f;
depth_end = 1000.f;
mirror_x = mirror_y = false;
@@ -33,45 +33,16 @@ Camera::Camera() {
void Camera::anglesFromPoints() {
QVector3D dv = aim_ - pos_, tv;
tv = QVector3D(dv.x(), dv.y(), 0.);
angles_.setZ(atan2f(tv.x(), tv.y()) * rad2deg);
angles_.setY(piClamp<GLfloat>(atan2f(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.f);
}
void Camera::apply(const GLfloat & aspect) {
glMatrixMode(GL_PROJECTION);
if (aspect <= 1.f)
glScalef(aspect, aspect, 1.f);
QMatrix4x4 pm = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
//pm.perspective(fov_, aspect, depth_start, depth_end);
//qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end);
//qDebug() << pm;
//setGLMatrix(pm);
glMatrixMode(GL_MODELVIEW);
pm.setToIdentity();
pm.translate(0., 0., -distance());
pm.rotate(angles_.y(), 1., 0., 0.);
pm.rotate(angles_.x(), 0., 1., 0.);
pm.rotate(angles_.z(), 0., 0., 1.);
//pm.translate(-aim_);
if (parent_) {
QMatrix4x4 pmat = parent_->worldTransform();
offset_ = pmat.column(3).toVector3D();
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
pmat.translate(aim_);
pm *= pmat.inverted();
//qDebug() << pmat;
}
//setGLMatrix(pm);
//qDebug() << angles_;
//QVector3D dv = aim_ - pos_, tv;
//tv = QVector3D(dv.x(), dv.y(), 0.);
//angles_.setZ(atan2f(tv.x(), tv.y()) * rad2deg);
//angles_.setY(piClamp<GLfloat>(atan2f(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.f);
}
QMatrix4x4 Camera::offsetMatrix() const {
QMatrix4x4 ret;
ret.translate(parent_ ? -offset_ : -aim_);
ret.translate(parent_ ? -offset_ : -aim());
return ret;
}
@@ -91,10 +62,9 @@ void Camera::localTransform(QMatrix4x4 & m) {
*/
void Camera::assign(const Camera & c) {
pos_ = c.pos_;
aim_ = c.aim_;
trans = c.trans;
aim_dist = c.aim_dist;
fov_ = c.fov_;
angles_ = c.angles_;
angle_limit_lower_xy = c.angle_limit_lower_xy;
angle_limit_upper_xy = c.angle_limit_upper_xy;
mirror_x = c.mirror_x;
@@ -116,10 +86,9 @@ ObjectBase * Camera::clone(bool withChildren) {
for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren));
}
o->pos_ = pos_;
o->aim_ = aim_;
o->trans = trans;
o->aim_dist = aim_dist;
o->fov_ = fov_;
o->angles_ = angles_;
o->angle_limit_lower_xy = angle_limit_lower_xy;
o->angle_limit_upper_xy = angle_limit_upper_xy;
o->mirror_x = mirror_x;
@@ -133,16 +102,18 @@ ObjectBase * Camera::clone(bool withChildren) {
QMatrix4x4 Camera::viewMatrix() const {
QMatrix4x4 ret;
//qDebug() << pos() << aim();
ret.translate(0., 0., -distance());
ret.rotate(angles_.y(), 1., 0., 0.);
ret.rotate(angles_.x(), 0., 1., 0.);
ret.rotate(angles_.z(), 0., 0., 1.);
ret *= trans.matrixRotateScale().inverted();
//ret.rotate(angles_.y(), 1., 0., 0.);
//ret.rotate(angles_.x(), 0., 1., 0.);
//ret.rotate(angles_.z(), 0., 0., 1.);
//pm.translate(-aim_);
if (parent_) {
QMatrix4x4 pmat = parent_->worldTransform();
offset_ = pmat.column(3).toVector3D();
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
pmat.translate(aim_);
pmat.translate(aim());
ret *= pmat.inverted();
}
return ret;
@@ -155,96 +126,106 @@ QMatrix4x4 Camera::projectionMatrix(double aspect) const {
void Camera::panZ(const float & a) {
QVector3D dv = aim_ - pos_;
/*QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(angles_.z() + a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
aim_ = pos_ + dv;
buildTransform();
buildTransform();*/
}
void Camera::panXY(const float & a) {
QVector3D dv = aim_ - pos_;
/*QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc;
angles_.setY(angles_.y() + a);
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
aim_ = pos_ + dv * tl;
buildTransform();
buildTransform();*/
}
void Camera::rotateZ(const float & a) {
QVector3D dv = aim_ - pos_;
/*QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(angles_.z() + a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
aim_ = pos_ + dv;
buildTransform();
buildTransform();*/
}
void Camera::rotateXY(const float & a) {
QVector3D dv = aim_ - pos_;
/*QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc;
angles_.setY(angles_.y() + a);
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
aim_ = pos_ + dv * tl;
buildTransform();
buildTransform();*/
}
void Camera::orbitZ(const float & a) {
QVector3D dv = aim_ - pos_;
//qDebug() << rotation() << Transform::fromDirection(direction());
QVector3D pa = aim();
//trans.rotationRef() *= QQuaternion::fromEulerAngles(0, a, 0);
ObjectBase::rotateZ(-a);
move(pa - aim());
/*QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(angles_.z() + a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
pos_ = aim_ - dv;
buildTransform();
buildTransform();*/
}
void Camera::orbitXY(const float & a) {
QVector3D dv = aim_ - pos_;
QVector3D pa = aim();
//trans.rotationRef() *= QQuaternion::fromEulerAngles(a, 0, 0);
ObjectBase::rotateX(-a);
move(pa - aim());
//qDebug() << pos() << aim();
/*QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc;
angles_.setY(angles_.y() + a);
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
pos_ = aim_ - dv * tl;
buildTransform();
buildTransform();*/
}
void Camera::setAngleZ(const float & a) {
QVector3D dv = aim_ - pos_;
/*QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
aim_ = pos_ + dv;
buildTransform();
buildTransform();*/
}
void Camera::setAngleXY(const float & a) {
QVector3D dv = aim_ - pos_;
/*QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc;
angles_.setY(a);
tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
//pos_ = aim_ - dv;
aim_ = pos_ + dv * tl;
buildTransform();
buildTransform();*/
//anglesFromPoints();
}
void Camera::moveForward(const float & x, bool withZ) {
QVector3D dv;// = aim_ - pos_;
/*Vector3D dv;// = aim_ - pos_;
float tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, 0.);
if (withZ) dv.setZ(-cosf(angles_.y() * deg2rad));
@@ -252,12 +233,12 @@ void Camera::moveForward(const float & x, bool withZ) {
dv *= x;
pos_ += dv;
aim_ += dv;
buildTransform();
buildTransform();*/
}
void Camera::moveLeft(const float & x, bool withZ) {
QVector3D dv;// = aim_ - pos_;
/*QVector3D dv;// = aim_ - pos_;
float tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad - float(M_PI_2)) * tc, cosf(angles_.z() * deg2rad - float(M_PI_2)) * tc, 0.f);
if (withZ) dv.setZ(-sinf(angles_.x() * deg2rad));
@@ -265,12 +246,12 @@ void Camera::moveLeft(const float & x, bool withZ) {
dv *= x;
pos_ += dv;
aim_ += dv;
buildTransform();
buildTransform();*/
}
void Camera::moveUp(const float & x, bool onlyZ) {
QVector3D dv;
/*QVector3D dv;
if (onlyZ)
dv = QVector3D(0., 0., x);
else {
@@ -281,10 +262,10 @@ void Camera::moveUp(const float & x, bool onlyZ) {
}
pos_ += dv;
aim_ += dv;
buildTransform();
buildTransform();*/
}
/*
void Camera::flyCloser(const float & s) {
QVector3D dv = aim_ - pos_;
float tl = dv.length() / (1.f + s), tc = -sinf(angles_.y() * deg2rad);
@@ -310,4 +291,4 @@ void Camera::flyToDistance(const float & d) {
pos_ = aim_ - dv * d;
buildTransform();
}
*/

View File

@@ -33,10 +33,6 @@ class Camera: public AimedObject
public:
Camera();
void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();}
void setAim(const QVector3D & p) {AimedObject::setAim(p); anglesFromPoints(); buildTransform();}
void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();}
void move(const float & x, const float & y = 0., const float & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();}
void moveForward(const float & x, bool withZ = true);
void moveBackward(const float & x, bool withZ = true) {moveForward(-x, withZ);}
void moveLeft(const float & x, bool withZ = true);
@@ -45,7 +41,7 @@ public:
void moveDown(const float & x, bool onlyZ = false) {moveUp(-x, onlyZ);}
void rotateZ(const float & a);
void rotateXY(const float & a);
void rotateRoll(const float & a) {angles_.setX(angles_.x() + a); buildTransform();}
void rotateRoll(const float & a) {rotateX(a);}
void orbitZ(const float & a);
void orbitXY(const float & a);
void panZ(const float & a);
@@ -54,7 +50,7 @@ public:
void setAngles(const QVector3D & a) {setRotation(a);}
void setAngleZ(const float & a);
void setAngleXY(const float & a);
void setAngleRoll(const float & a) {angles_.setX(a); buildTransform();}
void setAngleRoll(const float & a) {setRotationX(a);}
void setAngleLowerLimitXY(const float & a) {angle_limit_lower_xy = a; buildTransform();}
void setAngleUpperLimitXY(const float & a) {angle_limit_upper_xy = a; buildTransform();}
void setAngleLimitsXY(const float & lower, const float & upper) {angle_limit_lower_xy = lower; angle_limit_upper_xy = upper; buildTransform();}
@@ -62,18 +58,11 @@ public:
void setDepthEnd(const float & d) {depth_end = d;}
void setMirrorX(bool yes) {mirror_x = yes;}
void setMirrorY(bool yes) {mirror_y = yes;}
void flyCloser(const float & s);
void flyFarer(const float & s);
void flyToDistance(const float & d);
QVector3D angles() const {return rotation();}
QVector3D direction() const {return (aim_ - pos_).normalized();}
QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();}
float FOV() const {return fov_;}
float distance() const {return (pos_ - aim_).length();}
float angleZ() const {return angles_.z();}
float angleXY() const {return angles_.y();}
float angleRoll() const {return angles_.x();}
float angleZ() const {return rotationZ();}
float angleXY() const {return rotationY();}
float angleRoll() const {return rotationZ();}
float angleLowerLimitXY() const {return angle_limit_lower_xy;}
float angleUpperLimitXY() const {return angle_limit_upper_xy;}
float depthStart() const {return depth_start;}
@@ -81,7 +70,6 @@ public:
bool isMirrorX() const {return mirror_x;}
bool isMirrorY() const {return mirror_y;}
void anglesFromPoints();
void apply(const GLfloat & aspect = 1.);
void assign(const Camera & c);

View File

@@ -27,7 +27,6 @@ ObjectBase::ObjectBase(Mesh * geom, Material * mat) {
type_ = glMesh;
render_mode = View;
pass_ = Solid;
scale_ = QVector3D(1., 1., 1.);
parent_ = nullptr;
color_ = Qt::white;
is_root = is_init = is_tex_loaded = selected_ = false;
@@ -67,12 +66,11 @@ ObjectBase * ObjectBase::clone(bool withChildren) {
o->accept_light = accept_light;
o->accept_fog = accept_fog;
o->visible_ = visible_;
o->color_ = color_;
o->type_ = type_;
o->raw_matrix = raw_matrix;
o->mat_ = mat_;
o->pos_ = pos_;
o->angles_ = angles_;
o->scale_ = scale_;
o->trans = trans;
o->itransform_ = itransform_;
o->bound = bound;
o->name_ = name_;// + "_copy";
@@ -215,62 +213,28 @@ void ObjectBase::setVisible(bool v) {
}
void ObjectBase::rotateX(GLfloat a) {
raw_matrix = false;
angles_.setX(angles_.x() + a);
buildTransform();
}
void ObjectBase::rotateY(GLfloat a) {
raw_matrix = false;
angles_.setY(angles_.y() + a);
buildTransform();
}
void ObjectBase::rotateZ(GLfloat a) {
raw_matrix = false;
angles_.setZ(angles_.z() + a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
buildTransform();
}
void ObjectBase::setRotationX(GLfloat a) {
raw_matrix = false;
angles_.setX(a);
buildTransform();
}
void ObjectBase::setRotationY(GLfloat a) {
raw_matrix = false;
angles_.setY(a);
trans.setRotationZ(trans.rotationZ() + a);
//angles_.setZ(angles_.z() + a);
//while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
//while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
buildTransform();
}
void ObjectBase::setRotationZ(GLfloat a) {
raw_matrix = false;
angles_.setZ(a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
trans.setRotationZ(a);
//angles_.setZ(a);
//while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
//while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
buildTransform();
}
void ObjectBase::setRotation(const QVector3D & a) {
raw_matrix = false;
angles_= a;
buildTransform();
}
void ObjectBase::resetRotation() {
raw_matrix = false;
angles_ = QVector3D(0., 0., 0.);
void ObjectBase::setTransform(const Transform & t) {
trans = t;
buildTransform();
}
@@ -328,15 +292,27 @@ void ObjectBase::removeProperty(const QString & pn) {
}
void ObjectBase::setTransform(const QMatrix4x4 & t) {
raw_matrix = true;
mat_ = t;
pos_ = mat_.column(3).toVector3D();
mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
void ObjectBase::setMatrix(const QMatrix4x4 & t) {
//raw_matrix = true;
//mat_ = t;
//pos_ = mat_.column(3).toVector3D();
//mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
trans.setMatrix(t);
buildTransform();
}
QMatrix4x4 ObjectBase::matrix() const {
return trans.matrix();
}
QVector3D ObjectBase::inParentSpace(const QVector3D & v) const {
if (!parent_) return v;
return (parent_->matrix() * QVector4D(v, 1)).toVector3D();
}
bool ObjectBase::isSelected(bool check_parents) const {
if (!check_parents) return selected_;
if (selected_) return true;
@@ -397,11 +373,11 @@ void ObjectBase::buildTransform() {
ObjectBase * p = parent_;
if (p)
itransform_ = p->itransform_;
if (raw_matrix) {
itransform_.translate(pos_);
itransform_ *= mat_;
//qDebug() << "raw_matrix" << itransform_;
} else
//if (raw_matrix) {
// itransform_.translate(pos_);
// itransform_ *= mat_;
// //qDebug() << "raw_matrix" << itransform_;
//} else
localTransform(itransform_);
//qDebug() << name_ << itransform_;
foreach (ObjectBase * i, children_)
@@ -417,11 +393,7 @@ void ObjectBase::initInternal() {
void ObjectBase::localTransform(QMatrix4x4 & m) {
m.translate(pos_);
m.rotate(angles_.z(), 0., 0., 1.);
m.rotate(angles_.y(), 0., 1., 0.);
m.rotate(angles_.x(), 1., 0., 0.);
m.scale(scale_);
m *= trans.matrix();
}
@@ -450,15 +422,16 @@ void ObjectBase::setMeshChanged() {
QMatrix4x4 ObjectBase::worldMatrix(QMatrix4x4 parent) const {
QMatrix4x4 mat;
mat.translate(pos_);
if (raw_matrix) {
mat *= mat_;
} else {
if (angles_.z() != 0.f) mat.rotate(angles_.z(), 0., 0., 1.);
if (angles_.y() != 0.f) mat.rotate(angles_.y(), 0., 1., 0.);
if (angles_.x() != 0.f) mat.rotate(angles_.x(), 1., 0., 0.);
mat.scale(scale_);
}
//mat.translate(pos_);
//if (raw_matrix) {
// mat *= mat_;
//} else {
// if (angles_.z() != 0.f) mat.rotate(angles_.z(), 0., 0., 1.);
// if (angles_.y() != 0.f) mat.rotate(angles_.y(), 0., 1., 0.);
// if (angles_.x() != 0.f) mat.rotate(angles_.x(), 1., 0., 0.);
// mat.scale(scale_);
//}
mat = trans.matrix();
return parent * mat;
}
@@ -470,19 +443,56 @@ AimedObject::AimedObject() {
}
QVector3D AimedObject::worldAim() const {
QVector3D ret = worldPos() + worldDirection() * aim_dist;
return ret;
}
void AimedObject::setAim(const QVector3D & p) {
aim_ = p;
QVector3D dir = inParentSpace(p) - pos(), up;
if (!QVector3D::crossProduct(QVector3D(0,0,1), dir).isNull())
up = QVector3D(0,0,1);
trans.setRotation(Transform::fromDirection(dir));
aim_dist = dir.length();
//qDebug() << "setAim" << p << aim();
}
QVector3D AimedObject::direction() const {
return (aim_ - pos_).normalized();
return trans.direction();
}
void AimedObject::setDirection(const QVector3D & d) {
double len = qMax(direction().length(), 0.001f);
aim_ = pos_ + (d.normalized() * len);
//double len = qMax(aim_.length(), 0.001f);
//aim_ = d.normalized() * len;
}
void AimedObject::flyCloser(double s) {
double tl = 1. / (1. + s);
move(direction() * aim_dist * (1. - tl));
aim_dist *= tl;
}
void AimedObject::flyFarer(double s) {
double tl = 1. * (1. + s);
move(direction() * aim_dist * (1. - tl));
aim_dist *= tl;
}
void AimedObject::flyToDistance(double d) {
move(direction() * (aim_dist - d));
aim_dist = d;
//qDebug() << d << (aim() - pos()).length() << aim();
}
void AimedObject::transformChanged() {
}
@@ -502,12 +512,12 @@ Light::Light(): AimedObject(), shadow_map(0, true, GL_R16F) {
Light::Light(const QVector3D & p, const QColor & c, float i): AimedObject(), shadow_map(0, true, GL_R16F) {
type_ = glLight;
light_type = Omni;
pos_ = p;
intensity = i;
color_ = c;
angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.;
setPos(p);
setDirection(0, 0, -1.);
}
@@ -525,8 +535,8 @@ ObjectBase * Light::clone(bool withChildren) {
}
o->color_ = color_;
o->light_type = light_type;
o->pos_ = pos_;
o->aim_ = aim_;
o->trans = trans;
o->aim_dist = aim_dist;
o->angle_start = angle_start;
o->angle_end = angle_end;
o->intensity = intensity;
@@ -548,21 +558,20 @@ QDataStream & operator <<(QDataStream & s, const ObjectBase * p) {
//qDebug() << "place" << p->name() << "...";
cs.add(1, int(p->type_)).add(2, p->accept_light).add(3, p->accept_fog).add(4, p->visible_)
.add(5, p->cast_shadow).add(6, p->rec_shadow).add(7, p->raw_matrix).add(8, p->line_width)
.add(9, int(p->render_mode)).add(11, p->pos_).add(12, p->angles_)
.add(13, p->scale_).add(14, p->mat_).add(16, p->children_.size())
.add(17, p->name_).add(18, p->meta).add(19, p->color_);
.add(9, int(p->render_mode)).add(14, p->mat_).add(16, p->children_.size())
.add(17, p->name_).add(18, p->meta).add(19, p->color_).add(20, p->trans);
//qDebug() << "place self done";
if (p->type_ == ObjectBase::glLight) {
//qDebug() << "place light ...";
const Light * l = (const Light*)p;
cs.add(100, l->direction()).add(101, l->angle_start).add(102, l->angle_end).add(103, l->intensity)
cs.add(100, l->aim()).add(101, l->angle_start).add(102, l->angle_end).add(103, l->intensity)
.add(104, l->decay_const).add(105, l->decay_linear).add(106, l->decay_quadratic)
.add(107, l->decay_start).add(108, l->decay_end).add(109, int(l->light_type)).add(110, l->aim());
.add(107, l->decay_start).add(108, l->decay_end).add(109, int(l->light_type));
}
if (p->type_ == ObjectBase::glCamera) {
//qDebug() << "place camera ...";
const Camera * c = (const Camera*)p;
cs.add(200, c->aim_).add(201, c->fov_).add(202, c->depth_start).add(203, c->depth_end)
cs.add(200, c->aim()).add(201, c->fov_).add(202, c->depth_start).add(203, c->depth_end)
.add(204, c->angle_limit_lower_xy).add(205, c->angle_limit_upper_xy)
.add(206, c->mirror_x).add(207, c->mirror_y);
}
@@ -601,22 +610,23 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
case 8: if (p) p->line_width = cs.getData<float>(); break;
case 9: if (p) p->render_mode = (ObjectBase::RenderMode)cs.getData<int>(); break;
//case 10: if (p) p->material_ = cs.getData<Material>(); break;
case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break;
case 12:
if (p) p->angles_ = cs.getData<QVector3D>();
if (c) {
c->setAngles(cs.getData<QVector3D>());
cam_angles = c->angles();
}
break;
case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break;
//case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break;
//case 12:
// if (p) p->angles_ = cs.getData<QVector3D>();
// if (c) {
// c->setAngles(cs.getData<QVector3D>());
// cam_angles = c->angles();
// }
//break;
//case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break;
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break;
//case 15: if (p) p->vbo = cs.getData<VBO>(); break;
case 16: if (p) ccnt = cs.getData<int>(); break;
case 17: if (p) p->name_ = cs.getData<QString>(); break;
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break;
case 19: if (p) p->color_ = cs.getData<QColor>(); break;
case 100: if (l) l->setDirection(cs.getData<QVector3D>());break;
case 20: if (p) p->trans = cs.getData<Transform>(); break;
case 100: if (l) l->setAim(cs.getData<QVector3D>()); break;
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break;
case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break;
case 103: if (l) l->intensity = cs.getData<GLfloat>(); break;
@@ -626,7 +636,6 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break;
case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break;
case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break;
case 110: if (l) l->setAim(cs.getData<QVector3D>()); if (l->aim().isNull()) l->setAim(l->direction()); break;
case 200: if (c) c->setAim(cs.getData<QVector3D>()); break;
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break;
case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break;
@@ -637,7 +646,7 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
case 207: if (c) c->mirror_y = cs.getData<bool>(); break;
}
}
if (c) c->setAngles(cam_angles);
//if (c) c->setAngles(cam_angles);
//qDebug() << p->name() << ccnt;
for (int i = 0; i < ccnt; ++i) {
ObjectBase * c = nullptr;
@@ -646,5 +655,6 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
c->parent_ = p;
p->children_ << c;
}
p->buildTransform();
return s;
}

View File

@@ -22,6 +22,7 @@
#include "glframebuffer.h"
#include "glmaterial.h"
#include "gltypes.h"
#include "gltransform.h"
class ObjectBase
@@ -89,61 +90,64 @@ public:
void setReceiveShadows(bool on) {rec_shadow = on;}
void setCastShadows(bool on) {cast_shadow = on;}
void move(const QVector3D & dv) {pos_ += dv; buildTransform();}
void moveTo(const QVector3D & dv) {pos_ = dv; buildTransform();}
void move(const QVector3D & dv) {trans.setTranslation(pos() + dv); buildTransform();}
void moveTo(const QVector3D & dv) {trans.setTranslation(dv); buildTransform();}
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); buildTransform();}
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {moveTo(QVector3D(dx, dy, dz)); buildTransform();}
void moveX(GLfloat o) {pos_.setX(pos_.x() + o); buildTransform();}
void moveY(GLfloat o) {pos_.setY(pos_.y() + o); buildTransform();}
void moveZ(GLfloat o) {pos_.setZ(pos_.z() + o); buildTransform();}
void setPosX(GLfloat o) {pos_.setX(o); buildTransform();}
void setPosY(GLfloat o) {pos_.setY(o); buildTransform();}
void setPosZ(GLfloat o) {pos_.setZ(o); buildTransform();}
void setPos(GLfloat x, GLfloat y, GLfloat z) {pos_ = QVector3D(x, y, z); buildTransform();}
void setPos(const QVector3D & p) {pos_ = p; buildTransform();}
void resetPos() {pos_ = QVector3D(0., 0., 0.); buildTransform();}
void moveX(GLfloat o) {trans.setTranslationX(posX() + o); buildTransform();}
void moveY(GLfloat o) {trans.setTranslationY(posY() + o); buildTransform();}
void moveZ(GLfloat o) {trans.setTranslationZ(posZ() + o); buildTransform();}
void setPosX(GLfloat o) {trans.setTranslationX(o); buildTransform();}
void setPosY(GLfloat o) {trans.setTranslationY(o); buildTransform();}
void setPosZ(GLfloat o) {trans.setTranslationZ(o); buildTransform();}
void setPos(GLfloat x, GLfloat y, GLfloat z) {trans.setTranslation(QVector3D(x, y, z)); buildTransform();}
void setPos(const QVector3D & p) {trans.setTranslation(p); buildTransform();}
void resetPos() {trans.setTranslation(QVector3D()); buildTransform();}
QVector3D pos() const {return pos_;}
float posX() const {return pos_.x();}
float posY() const {return pos_.y();}
float posZ() const {return pos_.z();}
QVector3D pos() const {return trans.translation();}
float posX() const {return trans.translation().x();}
float posY() const {return trans.translation().y();}
float posZ() const {return trans.translation().z();}
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();}
QMatrix4x4 worldTransform() const {return itransform_;}
QVector3D rotation() const {return angles_;}
float rotationX() const {return angles_.x();}
float rotationY() const {return angles_.y();}
float rotationZ() const {return angles_.z();}
void rotateX(GLfloat a);
void rotateY(GLfloat a);
QVector3D rotation() const {return trans.rotation();}
float rotationX() const {return rotation().x();}
float rotationY() const {return rotation().y();}
float rotationZ() const {return rotation().z();}
void rotateX(GLfloat a) {raw_matrix = false; trans.setRotationX(trans.rotationX() + a); buildTransform();}
void rotateY(GLfloat a) {raw_matrix = false; trans.setRotationY(trans.rotationY() + a); buildTransform();}
void rotateZ(GLfloat a);
void setRotationX(GLfloat a);
void setRotationY(GLfloat a);
void setRotationX(GLfloat a) {raw_matrix = false; trans.setRotationX(a); buildTransform();}
void setRotationY(GLfloat a) {raw_matrix = false; trans.setRotationY(a); buildTransform();}
void setRotationZ(GLfloat a);
void setRotation(const QVector3D & a);
void resetRotation();
void setRotation(const QVector3D & a) {raw_matrix = false; trans.setRotation(a); buildTransform();}
void resetRotation() {raw_matrix = false; trans.setRotation(QVector3D()); buildTransform();}
QVector3D scale() {return scale_;}
float scaleX() {return scale_.x();}
float scaleY() {return scale_.y();}
float scaleZ() {return scale_.z();}
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();}
QVector3D scale() {return trans.scale3D();}
float scaleX() {return trans.scale3D().x();}
float scaleY() {return trans.scale3D().y();}
float scaleZ() {return trans.scale3D().z();}
void scale(const QVector3D & sv) {raw_matrix = false; trans.setScale(trans.scale3D() * sv); buildTransform();}
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();}
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();}
void scale(GLfloat sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();}
void scaleX(GLfloat a) {raw_matrix = false; scale_.setX(scale_.x() + a); buildTransform();}
void scaleY(GLfloat a) {raw_matrix = false; scale_.setY(scale_.y() + a); buildTransform();}
void scaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(scale_.z() + a); buildTransform();}
void setScale(const QVector3D & a) {raw_matrix = false; scale_ = a; buildTransform();}
void setScale(GLfloat a) {raw_matrix = false; scale_ = QVector3D(a, a, a); buildTransform();}
void setScaleX(GLfloat a) {raw_matrix = false; scale_.setX(a); buildTransform();}
void setScaleY(GLfloat a) {raw_matrix = false; scale_.setY(a); buildTransform();}
void setScaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(a); buildTransform();}
void resetScale() {raw_matrix = false; scale_ = QVector3D(1., 1., 1.); buildTransform();}
void scaleX(GLfloat a) {raw_matrix = false; trans.setScaleX(trans.scale3D().x() + a); buildTransform();}
void scaleY(GLfloat a) {raw_matrix = false; trans.setScaleY(trans.scale3D().y() + a); buildTransform();}
void scaleZ(GLfloat a) {raw_matrix = false; trans.setScaleZ(trans.scale3D().z() + a); buildTransform();}
void setScale(const QVector3D & a) {raw_matrix = false; trans.setScale(a); buildTransform();}
void setScale(GLfloat a) {raw_matrix = false; trans.setScale(a); buildTransform();}
void setScaleX(GLfloat a) {raw_matrix = false; trans.setScaleX(a); buildTransform();}
void setScaleY(GLfloat a) {raw_matrix = false; trans.setScaleY(a); buildTransform();}
void setScaleZ(GLfloat a) {raw_matrix = false; trans.setScaleZ(a); buildTransform();}
void resetScale() {raw_matrix = false; trans.setScale(1.f); buildTransform();}
QMatrix4x4 transform() {return mat_;}
void setTransform(const QMatrix4x4 & t);
Transform transform() {return trans;}
void setTransform(const Transform & t);
void setMatrix(const QMatrix4x4 & t);
QMatrix4x4 matrix() const;
bool isRawMatrix() {return raw_matrix;}
QVector3D inParentSpace(const QVector3D & v) const;
bool isAcceptLight() const {return accept_light;}
void setAcceptLight(bool yes) {accept_light = yes;}
@@ -190,6 +194,7 @@ public:
//QVector<GLfloat> d_vertices, d_normals, d_uvs;
protected:
virtual void transformChanged() {}
void addChildren(QList<ObjectBase * > & list, ObjectBase * where);
void loadTextures(bool with_children = false);
//void deleteTextures() {foreach (GLuint i, textures) currentQGLView->deleteTexture(i); textures.clear();}
@@ -210,7 +215,7 @@ protected:
Type type_;
RenderMode render_mode;
Box3D bound;
QVector3D pos_, angles_, scale_;
Transform trans;
QList<ObjectBase * > children_;
QMatrix4x4 itransform_, mat_;
QString name_;
@@ -234,14 +239,20 @@ class AimedObject: public ObjectBase {
public:
AimedObject();
~AimedObject() {}
QVector3D aim() const {return aim_;}
QVector3D worldAim() const {return (itransform_ * QVector4D(aim_, 1.)).toVector3D();}
QVector3D aim() const {return pos() + (direction() * aim_dist);}
QVector3D worldAim() const;
void setAim(const QVector3D & p);
QVector3D direction() const;
QVector3D worldDirection() const {return (itransform_ * QVector4D(direction(), 0.)).toVector3D().normalized();}
void setDirection(const QVector3D & d);
void setDirection(double x, double y, double z) {setDirection(QVector3D(x, y, z));}
double distance() const {return aim_dist;}
void flyCloser(double s);
void flyFarer(double s);
void flyToDistance(double d);
protected:
QVector3D aim_;
void transformChanged() override;
double aim_dist;
};

View File

@@ -213,7 +213,7 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri
cam.setDepthStart(view->camera()->depthStart());
cam.setDepthEnd(view->camera()->depthEnd());
cam.setFOV(l->angle_end);
cam.apply(1.);
//cam.apply(1.);
/*cam.rotateXY(l->angle_end);
QVector3D rdir = l->direction * cos(l->angle_end / 2. * deg2rad);
l->dir0 = cam.direction() - rdir;

View File

@@ -127,13 +127,9 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
QMatrix4x4 pmat;
foreach (ObjectBase * o, objects) {
pmat.setToIdentity();
if (o->parent()) {
pmat = o->parent()->worldTransform();
pmat.setColumn(3, QVector4D(0,0,0,1));
double det = pmat.determinant();
if (det > 0.) pmat /= sqrt(det);
}
o->move((QVector4D(axe_vector, 0) * pmat).toVector3D());
if (o->parent())
pmat = o->parent()->worldTransform().inverted();
o->move((pmat * QVector4D(axe_vector, 0)).toVector3D());
}
}
if (cur_action == RendererService::haRotate) {

View File

@@ -81,8 +81,9 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed()));
camera_ = new Camera();
camera_->setAim(QVector3D());
camera_->setPos(QVector3D(2, 2, 2));
camera_->setAim(QVector3D());
qDebug() << camera_->aim();
camera_->setName("Camera");
emit cameraPosChanged(camera_->pos());
//camera().aim_ = camera().pos_;
@@ -230,7 +231,7 @@ void QGLView::focusOn(const Box3D & bb) {
QByteArray QGLView::saveCamera() {
ChunkStream cs;
const Camera * c = camera();
cs.add(1, c->pos()).add(2, c->aim()).add(3, c->angles()).add(4, c->FOV());
cs.add(1, c->pos()).add(2, c->aim()).add(3, c->rotation()).add(4, c->FOV());
return cs.data();
}
@@ -238,7 +239,7 @@ QByteArray QGLView::saveCamera() {
void QGLView::restoreCamera(const QByteArray & ba) {
if (ba.isEmpty()) return;
Camera * c = camera();
QVector3D pos(c->pos()), aim(c->aim()), ang(c->angles());
QVector3D pos(c->pos()), aim(c->aim()), ang(c->rotation());
float fov(c->FOV());
ChunkStream cs(ba);
cs.readAll();

View File

@@ -31,9 +31,9 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
session.addEntry(this);
spinViewLineWidth->setValue(lineThickness()*2);
view->view()->camera()->setAim(QVector3D());
view->view()->camera()->setPos(QVector3D(2, 2, 2));
view->view()->camera()->flyToDistance(2.);
//view->view()->camera()->setPos(QVector3D(2, 2, 2));
//view->view()->camera()->setAim(QVector3D());
//view->view()->camera()->flyToDistance(2.);
// view->setFrameShape(QFrame::NoFrame);
view->view()->setMouseRotateEnabled(true);
view->view()->setMouseSelectionEnabled(true);
@@ -91,6 +91,7 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
session.load();
loadFile("axis.DAE.qgl");
//matEditor->setMaterial(const_cast<ObjectBase*>(view->view()->scene()->rootObject()->child(0))->material());
/*Scene * sc = loadScene("truck.obj");
//view->view()->scene()->addScene(sc);

View File

@@ -260,7 +260,7 @@ void RendererBase::reloadLightsPositions(Camera * cam) {
QMatrix4x4 m = mat * l->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(l->direction(), 1);//, dir0(light->dir0), dir1(light->dir1);
pos = m * pos;
dir = ((m * dir) - pos).normalized();
dir = (m * QVector4D(l->direction(),0)).normalized();//((m * dir) - pos).normalized();
so.position = pos;
so.direction = dir;
//so.shadowMatrix = l->shadow_matrix;

View File

@@ -32,8 +32,8 @@ RendererMaterial::RendererMaterial(Renderer * r_): r(r_),
fbo_mat_thumb(r->view, 6, true , GL_RGBA16F) {
mat_sphere = Primitive::ellipsoid(16, 16);
mat_camera = new Camera();
mat_camera->setAim(QVector3D());
mat_camera->setPos(QVector3D(1, 1, 1));
mat_camera->setAim(QVector3D());
mat_camera->setFOV(45.);
mat_light = new Light();
mat_light->setPos(QVector3D(50, 100, 25));

View File

@@ -63,17 +63,16 @@ RendererService::RendererService(Renderer * r_): r(r_) {
cone_mesh = Primitive::cone(8, 1., 1., 1.);
cone_mesh_f = Primitive::coneFrame(8, 1., 1., 1.);
QMatrix4x4 mat;
mat.translate(0,0,1);
mat.rotate(180, 1,0,0);
mat.translate(0,0,-1);
cone_mesh ->transformPoints(mat);
cone_mesh_f->transformPoints(mat);
cone_mesh_f->scalePoints(1.5);
box_mesh ->scalePoints(1.3);
omni_mesh ->scalePoints(1.3);
cone_mesh ->translatePoints(0,0,-1);
cone_mesh ->translatePoints(0,0,0.5);
cone_mesh ->scalePoints(1.4);
cone_mesh ->translatePoints(0,0,1);
cone_mesh ->translatePoints(0,0,-0.5);
cone_mesh ->scalePoints(1.5);
handle_move_mesh = Primitive::arrow(12, 0.06);
@@ -153,15 +152,10 @@ QMatrix4x4 RendererService::parentRotationMatrix(ObjectBase * o, bool self_rotat
if (!o) return ret;
QMatrix4x4 pmat;
if (o->parent()) {
pmat = o->parent()->worldTransform();
pmat.setColumn(3, QVector4D(0,0,0,1));
double det = pmat.determinant();
if (det > 0.) pmat /= sqrt(det);
pmat = o->parent()->transform().matrixRotate();
}
if (self_rotation) {
ret.rotate(o->angles_.z(), 0., 0., 1.);
ret.rotate(o->angles_.y(), 0., 1., 0.);
ret.rotate(o->angles_.x(), 1., 0., 0.);
ret *= o->transform().matrixRotate();
}
ret = pmat * ret;
return ret;
@@ -197,12 +191,7 @@ void RendererService::fillSpotObjects() {
cur_aims.clear();
foreach (Light * l, ll) {
QMatrix4x4 m, lm;
//QVector3D up = QVector3D::crossProduct(l->direction, QVector3D(0,0,1)).normalized();
//if (up.isNull())
// up = QVector3D::crossProduct(l->direction, QVector3D(0,0,1)).normalized();
//lm.lookAt(QVector3D(), l->direction, up);
//lm.lookAt(QVector3D(), l->direction, (QVector3D(0,0,1)));
lm.rotate(QQuaternion::fromDirection(l->direction(), QVector3D()));
lm = l->transform().matrixRotate();
m = invariantSizeMatrix(l->worldPos()) * parentRotationMatrix(l) * lm;
m.transposed().copyDataTo(o.modelmatrix);
o.object_id = l->id_;
@@ -391,6 +380,7 @@ void RendererService::renderService() {
/// axis
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
axis_camera->setPos(-r->view->camera()->direction() * 3.);
axis_camera->setAim(QVector3D());
r->setUniformCamera(prog, axis_camera, true, axis_viewport);
axis_mesh->draw(f, 3);
f->glViewport(0, 0, r->view->width(), r->view->height());

View File

@@ -135,7 +135,7 @@ void ObjectEditor::objectChanged() {
l->decay_quadratic = ui->spinLightDecayQuadratic->value();
l->angle_start = ui->spinLightAngleStart->value();
l->angle_end = ui->spinLightAngleEnd->value();
l->setDirection(QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized());
//l->setDirection(QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized());
l->apply();
}
if (object->type() == ObjectBase::glCamera) {