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 } else
ret = new ObjectBase(); ret = new ObjectBase();
ret->setName(name); ret->setName(name);
ret->setTransform(fromAiMatrix4D(n->mTransformation)); ret->setMatrix(fromAiMatrix4D(n->mTransformation));
//qDebug() << "add object" << ret << ret->name(); //qDebug() << "add object" << ret << ret->name();
if (!light) { if (!light) {
for (uint i = 0; i < n->mNumMeshes; ++i) { for (uint i = 0; i < n->mNumMeshes; ++i) {

View File

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

View File

@@ -33,10 +33,6 @@ class Camera: public AimedObject
public: public:
Camera(); 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 moveForward(const float & x, bool withZ = true);
void moveBackward(const float & x, bool withZ = true) {moveForward(-x, withZ);} void moveBackward(const float & x, bool withZ = true) {moveForward(-x, withZ);}
void moveLeft(const float & x, bool withZ = true); 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 moveDown(const float & x, bool onlyZ = false) {moveUp(-x, onlyZ);}
void rotateZ(const float & a); void rotateZ(const float & a);
void rotateXY(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 orbitZ(const float & a);
void orbitXY(const float & a); void orbitXY(const float & a);
void panZ(const float & a); void panZ(const float & a);
@@ -54,7 +50,7 @@ public:
void setAngles(const QVector3D & a) {setRotation(a);} void setAngles(const QVector3D & a) {setRotation(a);}
void setAngleZ(const float & a); void setAngleZ(const float & a);
void setAngleXY(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 setAngleLowerLimitXY(const float & a) {angle_limit_lower_xy = a; buildTransform();}
void setAngleUpperLimitXY(const float & a) {angle_limit_upper_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();} 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 setDepthEnd(const float & d) {depth_end = d;}
void setMirrorX(bool yes) {mirror_x = yes;} void setMirrorX(bool yes) {mirror_x = yes;}
void setMirrorY(bool yes) {mirror_y = 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 FOV() const {return fov_;}
float distance() const {return (pos_ - aim_).length();} float angleZ() const {return rotationZ();}
float angleZ() const {return angles_.z();} float angleXY() const {return rotationY();}
float angleXY() const {return angles_.y();} float angleRoll() const {return rotationZ();}
float angleRoll() const {return angles_.x();}
float angleLowerLimitXY() const {return angle_limit_lower_xy;} float angleLowerLimitXY() const {return angle_limit_lower_xy;}
float angleUpperLimitXY() const {return angle_limit_upper_xy;} float angleUpperLimitXY() const {return angle_limit_upper_xy;}
float depthStart() const {return depth_start;} float depthStart() const {return depth_start;}
@@ -81,7 +70,6 @@ public:
bool isMirrorX() const {return mirror_x;} bool isMirrorX() const {return mirror_x;}
bool isMirrorY() const {return mirror_y;} bool isMirrorY() const {return mirror_y;}
void anglesFromPoints(); void anglesFromPoints();
void apply(const GLfloat & aspect = 1.);
void assign(const Camera & c); void assign(const Camera & c);

View File

@@ -27,7 +27,6 @@ ObjectBase::ObjectBase(Mesh * geom, Material * mat) {
type_ = glMesh; type_ = glMesh;
render_mode = View; render_mode = View;
pass_ = Solid; pass_ = Solid;
scale_ = QVector3D(1., 1., 1.);
parent_ = nullptr; parent_ = nullptr;
color_ = Qt::white; color_ = Qt::white;
is_root = is_init = is_tex_loaded = selected_ = false; 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_light = accept_light;
o->accept_fog = accept_fog; o->accept_fog = accept_fog;
o->visible_ = visible_; o->visible_ = visible_;
o->color_ = color_;
o->type_ = type_; o->type_ = type_;
o->raw_matrix = raw_matrix; o->raw_matrix = raw_matrix;
o->mat_ = mat_; o->mat_ = mat_;
o->pos_ = pos_; o->trans = trans;
o->angles_ = angles_;
o->scale_ = scale_;
o->itransform_ = itransform_; o->itransform_ = itransform_;
o->bound = bound; o->bound = bound;
o->name_ = name_;// + "_copy"; 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) { void ObjectBase::rotateZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
angles_.setZ(angles_.z() + a); trans.setRotationZ(trans.rotationZ() + a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); //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(); //while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
}
void ObjectBase::setRotationX(GLfloat a) {
raw_matrix = false;
angles_.setX(a);
buildTransform();
}
void ObjectBase::setRotationY(GLfloat a) {
raw_matrix = false;
angles_.setY(a);
buildTransform(); buildTransform();
} }
void ObjectBase::setRotationZ(GLfloat a) { void ObjectBase::setRotationZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
angles_.setZ(a); trans.setRotationZ(a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); //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);
//while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
void ObjectBase::setRotation(const QVector3D & a) { void ObjectBase::setTransform(const Transform & t) {
raw_matrix = false; trans = t;
angles_= a;
buildTransform();
}
void ObjectBase::resetRotation() {
raw_matrix = false;
angles_ = QVector3D(0., 0., 0.);
buildTransform(); buildTransform();
} }
@@ -328,15 +292,27 @@ void ObjectBase::removeProperty(const QString & pn) {
} }
void ObjectBase::setTransform(const QMatrix4x4 & t) { void ObjectBase::setMatrix(const QMatrix4x4 & t) {
raw_matrix = true; //raw_matrix = true;
mat_ = t; //mat_ = t;
pos_ = mat_.column(3).toVector3D(); //pos_ = mat_.column(3).toVector3D();
mat_.setColumn(3, QVector4D(0., 0., 0., 1.)); //mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
trans.setMatrix(t);
buildTransform(); 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 { bool ObjectBase::isSelected(bool check_parents) const {
if (!check_parents) return selected_; if (!check_parents) return selected_;
if (selected_) return true; if (selected_) return true;
@@ -397,11 +373,11 @@ void ObjectBase::buildTransform() {
ObjectBase * p = parent_; ObjectBase * p = parent_;
if (p) if (p)
itransform_ = p->itransform_; itransform_ = p->itransform_;
if (raw_matrix) { //if (raw_matrix) {
itransform_.translate(pos_); // itransform_.translate(pos_);
itransform_ *= mat_; // itransform_ *= mat_;
//qDebug() << "raw_matrix" << itransform_; // //qDebug() << "raw_matrix" << itransform_;
} else //} else
localTransform(itransform_); localTransform(itransform_);
//qDebug() << name_ << itransform_; //qDebug() << name_ << itransform_;
foreach (ObjectBase * i, children_) foreach (ObjectBase * i, children_)
@@ -417,11 +393,7 @@ void ObjectBase::initInternal() {
void ObjectBase::localTransform(QMatrix4x4 & m) { void ObjectBase::localTransform(QMatrix4x4 & m) {
m.translate(pos_); m *= trans.matrix();
m.rotate(angles_.z(), 0., 0., 1.);
m.rotate(angles_.y(), 0., 1., 0.);
m.rotate(angles_.x(), 1., 0., 0.);
m.scale(scale_);
} }
@@ -450,15 +422,16 @@ void ObjectBase::setMeshChanged() {
QMatrix4x4 ObjectBase::worldMatrix(QMatrix4x4 parent) const { QMatrix4x4 ObjectBase::worldMatrix(QMatrix4x4 parent) const {
QMatrix4x4 mat; QMatrix4x4 mat;
mat.translate(pos_); //mat.translate(pos_);
if (raw_matrix) { //if (raw_matrix) {
mat *= mat_; // mat *= mat_;
} else { //} else {
if (angles_.z() != 0.f) mat.rotate(angles_.z(), 0., 0., 1.); // 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_.y() != 0.f) mat.rotate(angles_.y(), 0., 1., 0.);
if (angles_.x() != 0.f) mat.rotate(angles_.x(), 1., 0., 0.); // if (angles_.x() != 0.f) mat.rotate(angles_.x(), 1., 0., 0.);
mat.scale(scale_); // mat.scale(scale_);
} //}
mat = trans.matrix();
return parent * mat; 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) { 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 { QVector3D AimedObject::direction() const {
return (aim_ - pos_).normalized(); return trans.direction();
} }
void AimedObject::setDirection(const QVector3D & d) { void AimedObject::setDirection(const QVector3D & d) {
double len = qMax(direction().length(), 0.001f); //double len = qMax(aim_.length(), 0.001f);
aim_ = pos_ + (d.normalized() * len); //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) { Light::Light(const QVector3D & p, const QColor & c, float i): AimedObject(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
pos_ = p;
intensity = i; intensity = i;
color_ = c; color_ = c;
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.; decay_const = decay_end = 1.;
setPos(p);
setDirection(0, 0, -1.); setDirection(0, 0, -1.);
} }
@@ -525,8 +535,8 @@ ObjectBase * Light::clone(bool withChildren) {
} }
o->color_ = color_; o->color_ = color_;
o->light_type = light_type; o->light_type = light_type;
o->pos_ = pos_; o->trans = trans;
o->aim_ = aim_; o->aim_dist = aim_dist;
o->angle_start = angle_start; o->angle_start = angle_start;
o->angle_end = angle_end; o->angle_end = angle_end;
o->intensity = intensity; o->intensity = intensity;
@@ -548,21 +558,20 @@ QDataStream & operator <<(QDataStream & s, const ObjectBase * p) {
//qDebug() << "place" << p->name() << "..."; //qDebug() << "place" << p->name() << "...";
cs.add(1, int(p->type_)).add(2, p->accept_light).add(3, p->accept_fog).add(4, p->visible_) 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(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(9, int(p->render_mode)).add(14, p->mat_).add(16, p->children_.size())
.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(20, p->trans);
.add(17, p->name_).add(18, p->meta).add(19, p->color_);
//qDebug() << "place self done"; //qDebug() << "place self done";
if (p->type_ == ObjectBase::glLight) { if (p->type_ == ObjectBase::glLight) {
//qDebug() << "place light ..."; //qDebug() << "place light ...";
const Light * l = (const Light*)p; 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(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) { if (p->type_ == ObjectBase::glCamera) {
//qDebug() << "place camera ..."; //qDebug() << "place camera ...";
const Camera * c = (const Camera*)p; 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(204, c->angle_limit_lower_xy).add(205, c->angle_limit_upper_xy)
.add(206, c->mirror_x).add(207, c->mirror_y); .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 8: if (p) p->line_width = cs.getData<float>(); break;
case 9: if (p) p->render_mode = (ObjectBase::RenderMode)cs.getData<int>(); 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 10: if (p) p->material_ = cs.getData<Material>(); break;
case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break; //case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break;
case 12: //case 12:
if (p) p->angles_ = cs.getData<QVector3D>(); // if (p) p->angles_ = cs.getData<QVector3D>();
if (c) { // if (c) {
c->setAngles(cs.getData<QVector3D>()); // c->setAngles(cs.getData<QVector3D>());
cam_angles = c->angles(); // cam_angles = c->angles();
} // }
break; //break;
case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break; //case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break;
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break; case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break;
//case 15: if (p) p->vbo = cs.getData<VBO>(); break; //case 15: if (p) p->vbo = cs.getData<VBO>(); break;
case 16: if (p) ccnt = cs.getData<int>(); break; case 16: if (p) ccnt = cs.getData<int>(); break;
case 17: if (p) p->name_ = cs.getData<QString>(); break; case 17: if (p) p->name_ = cs.getData<QString>(); break;
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break; case 18: if (p) p->meta = cs.getData<QVariantMap>(); break;
case 19: if (p) p->color_ = cs.getData<QColor>(); 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 101: if (l) l->angle_start = cs.getData<GLfloat>(); break;
case 102: if (l) l->angle_end = 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; 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 107: if (l) l->decay_start = cs.getData<GLfloat>(); break;
case 108: if (l) l->decay_end = 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 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 200: if (c) c->setAim(cs.getData<QVector3D>()); break;
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break; case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break;
case 202: if (c) c->setDepthStart(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; 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; //qDebug() << p->name() << ccnt;
for (int i = 0; i < ccnt; ++i) { for (int i = 0; i < ccnt; ++i) {
ObjectBase * c = nullptr; ObjectBase * c = nullptr;
@@ -646,5 +655,6 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
c->parent_ = p; c->parent_ = p;
p->children_ << c; p->children_ << c;
} }
p->buildTransform();
return s; return s;
} }

View File

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

View File

@@ -127,13 +127,9 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
QMatrix4x4 pmat; QMatrix4x4 pmat;
foreach (ObjectBase * o, objects) { foreach (ObjectBase * o, objects) {
pmat.setToIdentity(); pmat.setToIdentity();
if (o->parent()) { if (o->parent())
pmat = o->parent()->worldTransform(); pmat = o->parent()->worldTransform().inverted();
pmat.setColumn(3, QVector4D(0,0,0,1)); o->move((pmat * QVector4D(axe_vector, 0)).toVector3D());
double det = pmat.determinant();
if (det > 0.) pmat /= sqrt(det);
}
o->move((QVector4D(axe_vector, 0) * pmat).toVector3D());
} }
} }
if (cur_action == RendererService::haRotate) { 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(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed())); connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed()));
camera_ = new Camera(); camera_ = new Camera();
camera_->setAim(QVector3D());
camera_->setPos(QVector3D(2, 2, 2)); camera_->setPos(QVector3D(2, 2, 2));
camera_->setAim(QVector3D());
qDebug() << camera_->aim();
camera_->setName("Camera"); camera_->setName("Camera");
emit cameraPosChanged(camera_->pos()); emit cameraPosChanged(camera_->pos());
//camera().aim_ = camera().pos_; //camera().aim_ = camera().pos_;
@@ -230,7 +231,7 @@ void QGLView::focusOn(const Box3D & bb) {
QByteArray QGLView::saveCamera() { QByteArray QGLView::saveCamera() {
ChunkStream cs; ChunkStream cs;
const Camera * c = camera(); 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(); return cs.data();
} }
@@ -238,7 +239,7 @@ QByteArray QGLView::saveCamera() {
void QGLView::restoreCamera(const QByteArray & ba) { void QGLView::restoreCamera(const QByteArray & ba) {
if (ba.isEmpty()) return; if (ba.isEmpty()) return;
Camera * c = camera(); 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()); float fov(c->FOV());
ChunkStream cs(ba); ChunkStream cs(ba);
cs.readAll(); cs.readAll();

View File

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

View File

@@ -260,7 +260,7 @@ void RendererBase::reloadLightsPositions(Camera * cam) {
QMatrix4x4 m = mat * l->worldTransform(); QMatrix4x4 m = mat * l->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(l->direction(), 1);//, dir0(light->dir0), dir1(light->dir1); QVector4D pos(0, 0, 0, 1.), dir(l->direction(), 1);//, dir0(light->dir0), dir1(light->dir1);
pos = m * pos; pos = m * pos;
dir = ((m * dir) - pos).normalized(); dir = (m * QVector4D(l->direction(),0)).normalized();//((m * dir) - pos).normalized();
so.position = pos; so.position = pos;
so.direction = dir; so.direction = dir;
//so.shadowMatrix = l->shadow_matrix; //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) { fbo_mat_thumb(r->view, 6, true , GL_RGBA16F) {
mat_sphere = Primitive::ellipsoid(16, 16); mat_sphere = Primitive::ellipsoid(16, 16);
mat_camera = new Camera(); mat_camera = new Camera();
mat_camera->setAim(QVector3D());
mat_camera->setPos(QVector3D(1, 1, 1)); mat_camera->setPos(QVector3D(1, 1, 1));
mat_camera->setAim(QVector3D());
mat_camera->setFOV(45.); mat_camera->setFOV(45.);
mat_light = new Light(); mat_light = new Light();
mat_light->setPos(QVector3D(50, 100, 25)); 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 = Primitive::cone(8, 1., 1., 1.);
cone_mesh_f = Primitive::coneFrame(8, 1., 1., 1.); cone_mesh_f = Primitive::coneFrame(8, 1., 1., 1.);
QMatrix4x4 mat; QMatrix4x4 mat;
mat.translate(0,0,1); mat.translate(0,0,-1);
mat.rotate(180, 1,0,0);
cone_mesh ->transformPoints(mat); cone_mesh ->transformPoints(mat);
cone_mesh_f->transformPoints(mat); cone_mesh_f->transformPoints(mat);
cone_mesh_f->scalePoints(1.5); cone_mesh_f->scalePoints(1.5);
box_mesh ->scalePoints(1.3); box_mesh ->scalePoints(1.3);
omni_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 ->scalePoints(1.4);
cone_mesh ->translatePoints(0,0,1); cone_mesh ->translatePoints(0,0,-0.5);
cone_mesh ->scalePoints(1.5); cone_mesh ->scalePoints(1.5);
handle_move_mesh = Primitive::arrow(12, 0.06); handle_move_mesh = Primitive::arrow(12, 0.06);
@@ -153,15 +152,10 @@ QMatrix4x4 RendererService::parentRotationMatrix(ObjectBase * o, bool self_rotat
if (!o) return ret; if (!o) return ret;
QMatrix4x4 pmat; QMatrix4x4 pmat;
if (o->parent()) { if (o->parent()) {
pmat = o->parent()->worldTransform(); pmat = o->parent()->transform().matrixRotate();
pmat.setColumn(3, QVector4D(0,0,0,1));
double det = pmat.determinant();
if (det > 0.) pmat /= sqrt(det);
} }
if (self_rotation) { if (self_rotation) {
ret.rotate(o->angles_.z(), 0., 0., 1.); ret *= o->transform().matrixRotate();
ret.rotate(o->angles_.y(), 0., 1., 0.);
ret.rotate(o->angles_.x(), 1., 0., 0.);
} }
ret = pmat * ret; ret = pmat * ret;
return ret; return ret;
@@ -197,12 +191,7 @@ void RendererService::fillSpotObjects() {
cur_aims.clear(); cur_aims.clear();
foreach (Light * l, ll) { foreach (Light * l, ll) {
QMatrix4x4 m, lm; QMatrix4x4 m, lm;
//QVector3D up = QVector3D::crossProduct(l->direction, QVector3D(0,0,1)).normalized(); lm = l->transform().matrixRotate();
//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()));
m = invariantSizeMatrix(l->worldPos()) * parentRotationMatrix(l) * lm; m = invariantSizeMatrix(l->worldPos()) * parentRotationMatrix(l) * lm;
m.transposed().copyDataTo(o.modelmatrix); m.transposed().copyDataTo(o.modelmatrix);
o.object_id = l->id_; o.object_id = l->id_;
@@ -391,6 +380,7 @@ void RendererService::renderService() {
/// axis /// axis
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height()); f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
axis_camera->setPos(-r->view->camera()->direction() * 3.); axis_camera->setPos(-r->view->camera()->direction() * 3.);
axis_camera->setAim(QVector3D());
r->setUniformCamera(prog, axis_camera, true, axis_viewport); r->setUniformCamera(prog, axis_camera, true, axis_viewport);
axis_mesh->draw(f, 3); axis_mesh->draw(f, 3);
f->glViewport(0, 0, r->view->width(), r->view->height()); 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->decay_quadratic = ui->spinLightDecayQuadratic->value();
l->angle_start = ui->spinLightAngleStart->value(); l->angle_start = ui->spinLightAngleStart->value();
l->angle_end = ui->spinLightAngleEnd->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(); l->apply();
} }
if (object->type() == ObjectBase::glCamera) { if (object->type() == ObjectBase::glCamera) {