git-svn-id: svn://db.shs.com.ru/libs@638 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
434
qglengine/core/gltransform.cpp
Normal file
434
qglengine/core/gltransform.cpp
Normal 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);
|
||||
}
|
||||
117
qglengine/core/gltransform.h
Normal file
117
qglengine/core/gltransform.h
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user