Merge remote-tracking branch 'origin/5.13' into dev

Change-Id: I8c12142e4733d0d95fde3e673eb684c47363ff6f
This commit is contained in:
Qt Forward Merge Bot 2019-07-23 03:02:37 +02:00
commit b6c749a75c
17 changed files with 208 additions and 50 deletions

View File

@ -55,6 +55,10 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace {
const auto slerpThreshold = 0.01f;
}
namespace Qt3DAnimation { namespace Qt3DAnimation {
namespace Animation { namespace Animation {
@ -270,17 +274,38 @@ ClipResults evaluateClipAtLocalTime(AnimationClip *clip, float localTime)
const int lowerKeyframeBound = channel.channelComponents[0].fcurve.lowerKeyframeBound(localTime); const int lowerKeyframeBound = channel.channelComponents[0].fcurve.lowerKeyframeBound(localTime);
const auto lowerQuat = quaternionFromChannel(lowerKeyframeBound); const auto lowerQuat = quaternionFromChannel(lowerKeyframeBound);
const auto higherQuat = quaternionFromChannel(lowerKeyframeBound + 1); const auto higherQuat = quaternionFromChannel(lowerKeyframeBound + 1);
const float omega = std::acos(qBound(-1.0f, QQuaternion::dotProduct(lowerQuat, higherQuat), 1.0f)); auto cosHalfTheta = QQuaternion::dotProduct(lowerQuat, higherQuat);
if (qFuzzyIsNull(omega)) {
// If the two keyframe quaternions are equal, just return the first one as the interpolated value. // If the two keyframe quaternions are equal, just return the first one as the interpolated value.
if (std::abs(cosHalfTheta) >= 1.0f) {
channelResults[i++] = lowerQuat.scalar(); channelResults[i++] = lowerQuat.scalar();
channelResults[i++] = lowerQuat.x(); channelResults[i++] = lowerQuat.x();
channelResults[i++] = lowerQuat.y(); channelResults[i++] = lowerQuat.y();
channelResults[i++] = lowerQuat.z(); channelResults[i++] = lowerQuat.z();
} else { } else {
const auto sinHalfTheta = std::sqrt(1.0f - std::pow(cosHalfTheta,2.0f));
if (std::abs(sinHalfTheta) < ::slerpThreshold) {
auto initial_i = i;
for (const auto &channelComponent : qAsConst(channel.channelComponents)) for (const auto &channelComponent : qAsConst(channel.channelComponents))
channelResults[i++] = channelComponent.fcurve.evaluateAtTimeAsSlerp(localTime, lowerKeyframeBound, omega); channelResults[i++] = channelComponent.fcurve.evaluateAtTime(localTime, lowerKeyframeBound);
// Normalize the resulting quaternion
QQuaternion quat{channelResults[initial_i], channelResults[initial_i+1], channelResults[initial_i+2], channelResults[initial_i+3]};
quat.normalize();
channelResults[initial_i+0] = quat.scalar();
channelResults[initial_i+1] = quat.x();
channelResults[initial_i+2] = quat.y();
channelResults[initial_i+3] = quat.z();
} else {
const auto reverseQ1 = cosHalfTheta < 0 ? -1.0f : 1.0f;
cosHalfTheta *= reverseQ1;
const auto halfTheta = std::acos(cosHalfTheta);
for (const auto &channelComponent : qAsConst(channel.channelComponents))
channelResults[i++] = channelComponent.fcurve.evaluateAtTimeAsSlerp(localTime,
lowerKeyframeBound,
halfTheta,
sinHalfTheta,
reverseQ1);
}
} }
} }
} }

View File

@ -97,7 +97,7 @@ float FCurve::evaluateAtTime(float localTime, int lowerBound) const
return m_keyframes.first().value; return m_keyframes.first().value;
} }
float FCurve::evaluateAtTimeAsSlerp(float localTime, int lowerBound, float omega) const float FCurve::evaluateAtTimeAsSlerp(float localTime, int lowerBound, float halfTheta, float sinHalfTheta, float reverseQ1) const
{ {
// TODO: Implement extrapolation beyond first/last keyframes // TODO: Implement extrapolation beyond first/last keyframes
if (localTime < m_localTimes.first()) if (localTime < m_localTimes.first())
@ -119,10 +119,11 @@ float FCurve::evaluateAtTimeAsSlerp(float localTime, int lowerBound, float omega
return keyframe0.value; return keyframe0.value;
case QKeyFrame::LinearInterpolation: case QKeyFrame::LinearInterpolation:
if (localTime >= t0 && localTime <= t1 && t1 > t0) { if (localTime >= t0 && localTime <= t1 && t1 > t0) {
const float t = (localTime - t0) / (t1 - t0); const auto t = (localTime - t0) / (t1 - t0);
const float div = 1.0f / std::sin(omega);
return std::sin((1 - t) * omega) * div * keyframe0.value + const auto A = std::sin((1.0f-t) * halfTheta) / sinHalfTheta;
std::sin(t * omega) * div * keyframe1.value; const auto B = std::sin(t * halfTheta) / sinHalfTheta;
return A * keyframe0.value + reverseQ1 * B * keyframe1.value;
} }
break; break;
case QKeyFrame::BezierInterpolation: case QKeyFrame::BezierInterpolation:

View File

@ -84,7 +84,7 @@ public:
float evaluateAtTime(float localTime) const; float evaluateAtTime(float localTime) const;
float evaluateAtTime(float localTime, int lowerBound) const; float evaluateAtTime(float localTime, int lowerBound) const;
float evaluateAtTimeAsSlerp(float localTime, int lowerBound, float omega) const; float evaluateAtTimeAsSlerp(float localTime, int lowerBound, float halfTheta, float sinHalfTheta, float reverseQ1) const;
int lowerKeyframeBound(float localTime) const; int lowerKeyframeBound(float localTime) const;
void read(const QJsonObject &json); void read(const QJsonObject &json);

View File

@ -69,6 +69,10 @@
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!
\qmlproperty TextureImage DiffuseMapMaterial::diffuse \qmlproperty TextureImage DiffuseMapMaterial::diffuse
@ -152,6 +156,10 @@
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!
@ -292,6 +300,10 @@
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!
@ -366,6 +378,10 @@
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!
@ -449,6 +465,10 @@
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!

View File

@ -296,6 +296,9 @@ QAbstractTexture *QDiffuseMapMaterial::diffuse() const
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
float QDiffuseMapMaterial::textureScale() const float QDiffuseMapMaterial::textureScale() const
{ {

View File

@ -314,6 +314,10 @@ float QDiffuseSpecularMapMaterial::shininess() const
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
float QDiffuseSpecularMapMaterial::textureScale() const float QDiffuseSpecularMapMaterial::textureScale() const
{ {

View File

@ -385,12 +385,20 @@ QVariant QDiffuseSpecularMaterial::normal() const
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!
\qmlproperty real DiffuseSpecularMaterial::textureScale \qmlproperty real DiffuseSpecularMaterial::textureScale
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
float QDiffuseSpecularMaterial::textureScale() const float QDiffuseSpecularMaterial::textureScale() const
{ {

View File

@ -306,12 +306,20 @@ QVariant QMetalRoughMaterial::normal() const
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
/*! /*!
\qmlproperty real Qt3D.Extras::MetalRoughMaterial::textureScale \qmlproperty real Qt3D.Extras::MetalRoughMaterial::textureScale
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with WrapMode.Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
float QMetalRoughMaterial::textureScale() const float QMetalRoughMaterial::textureScale() const
{ {

View File

@ -338,6 +338,10 @@ float QNormalDiffuseMapMaterial::shininess() const
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
float QNormalDiffuseMapMaterial::textureScale() const float QNormalDiffuseMapMaterial::textureScale() const
{ {

View File

@ -355,6 +355,10 @@ float QNormalDiffuseSpecularMapMaterial::shininess() const
Holds the current texture scale. It is applied as a multiplier to texture Holds the current texture scale. It is applied as a multiplier to texture
coordinates at render time. Defaults to 1.0. coordinates at render time. Defaults to 1.0.
When used in conjunction with QTextureWrapMode::Repeat, textureScale provides a simple
way to tile a texture across a surface. For example, a texture scale of \c 4.0
would result in 16 (4x4) tiles.
*/ */
float QNormalDiffuseSpecularMapMaterial::textureScale() const float QNormalDiffuseSpecularMapMaterial::textureScale() const
{ {

View File

@ -110,6 +110,12 @@ void JointManager::addDirtyJoint(Qt3DCore::QNodeId jointId)
m_dirtyJoints.push_back(jointHandle); m_dirtyJoints.push_back(jointHandle);
} }
void JointManager::removeDirtyJoint(Qt3DCore::QNodeId jointId)
{
const HJoint jointHandle = lookupHandle(jointId);
m_dirtyJoints.removeAll(jointHandle);
}
QVector<HJoint> JointManager::dirtyJoints() QVector<HJoint> JointManager::dirtyJoints()
{ {
return std::move(m_dirtyJoints); return std::move(m_dirtyJoints);

View File

@ -443,6 +443,7 @@ class JointManager : public Qt3DCore::QResourceManager<
{ {
public: public:
void addDirtyJoint(Qt3DCore::QNodeId jointId); void addDirtyJoint(Qt3DCore::QNodeId jointId);
void removeDirtyJoint(Qt3DCore::QNodeId jointId);
QVector<HJoint> dirtyJoints(); QVector<HJoint> dirtyJoints();
private: private:

View File

@ -220,7 +220,7 @@ void QClearBuffers::setClearStencilValue(int clearStencilValue)
ColorBuffer flag is set, all color buffers will be cleared. ColorBuffer flag is set, all color buffers will be cleared.
*/ */
/*! /*!
\qmlproperty RenderTargetOutput Qt3D.Render::ClearBuffers::colorbuffer \qmlproperty RenderTargetOutput Qt3D.Render::ClearBuffers::colorBuffer
Specifies a specific color buffer to clear. If set to NULL (default), and Specifies a specific color buffer to clear. If set to NULL (default), and
ColorBuffer flag is set, all color buffers will be cleared. ColorBuffer flag is set, all color buffers will be cleared.
*/ */

View File

@ -254,11 +254,14 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
/*! /*!
* \qmlproperty enumeration Qt3D.Render::Camera::projectionType * \qmlproperty enumeration Qt3D.Render::Camera::projectionType
* *
* Holds the type of the camera projection. * Holds the type of the camera projection. The default value is
* CameraLens.PerspectiveProjection.
* *
* \list * \list
* \li CameraLens.OrthographicProjection * \li CameraLens.OrthographicProjection - Parallel lines appear parallel. Objects appear
* \li CameraLens.PerspectiveProjection * the same size regardless of distance.
* \li CameraLens.PerspectiveProjection - Parallel lines appear to meet in the distance.
* Objects appear to shrink the farther they are from the camera.
* \li CameraLens.FrustumProjection * \li CameraLens.FrustumProjection
* \li CameraLens.CustomProjection * \li CameraLens.CustomProjection
* \endlist * \endlist
@ -267,17 +270,28 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
/*! /*!
* \qmlproperty real Qt3D.Render::Camera::nearPlane * \qmlproperty real Qt3D.Render::Camera::nearPlane
* Holds the current camera near plane of the camera. * Holds the current camera near plane of the camera. Objects that
* are closer to the camera than the nearPlane will not be rendered.
*/ */
/*! /*!
* \qmlproperty real Qt3D.Render::Camera::farPlane * \qmlproperty real Qt3D.Render::Camera::farPlane
* Holds the current camera far plane of the camera. * Holds the current camera far plane of the camera. Objects that
* are farther from the camera than the farPlane will not be rendered.
*/ */
/*! /*!
* \qmlproperty real Qt3D.Render::Camera::fieldOfView * \qmlproperty real Qt3D.Render::Camera::fieldOfView
* Holds the current field of view of the camera in degrees. * Holds the current vertical field of view of the camera in degrees.
*
* Along with \l aspectRatio, this property determines how much of
* the scene is visible to the camera. In that respect you might
* think of it as analogous to choosing a wide angle (wide horizontal
* field of view) or telephoto (narrow horizontal field of view) lens,
* depending on how much of a scene you want to capture.
*
* fieldOfView is only relevant when \l projectionType is
* CameraLens.PerspectiveProjection.
*/ */
/*! /*!
@ -288,21 +302,33 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
/*! /*!
*\qmlproperty real Qt3D.Render::Camera::left *\qmlproperty real Qt3D.Render::Camera::left
* Holds the current left of the camera. * Holds the current left of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/ */
/*! /*!
* \qmlproperty real Qt3D.Render::Camera::right * \qmlproperty real Qt3D.Render::Camera::right
* Holds the current right of the camera. * Holds the current right of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/ */
/*! /*!
* \qmlproperty real Qt3D.Render::Camera::bottom * \qmlproperty real Qt3D.Render::Camera::bottom
* Holds the current bottom of the camera. * Holds the current bottom of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/ */
/*! /*!
* \qmlproperty real Qt3D.Render::Camera::top * \qmlproperty real Qt3D.Render::Camera::top
* Holds the current top of the camera. * Holds the current top of the camera.
*
* This property is only relevant when \l projectionType is
* CameraLens.OrthographicProjection.
*/ */
/*! /*!
@ -321,19 +347,29 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
* \qmlproperty vector3d Qt3D.Render::Camera::upVector * \qmlproperty vector3d Qt3D.Render::Camera::upVector
* Holds the current up vector of the camera in coordinates relative to * Holds the current up vector of the camera in coordinates relative to
* the parent entity. * the parent entity.
*
* The up vector indicates which direction the top of the camera is
* facing. Think of taking a picture: after positioning yourself
* and pointing the camera at your target, you might rotate the camera
* left or right, giving you a portrait or landscape (or angled!)
* shot. upVector allows you to control this type of movement.
*/ */
/*! /*!
* \qmlproperty vector3d Qt3D.Render::Camera::viewCenter * \qmlproperty vector3d Qt3D.Render::Camera::viewCenter
* Holds the current view center of the camera in coordinates relative to * Holds the current view center of the camera in coordinates relative to
* the parent entity. * the parent entity.
* \readonly *
* Intuitively, the viewCenter is the location the camera is pointing at.
*/ */
/*! /*!
* \qmlproperty vector3d Qt3D.Render::Camera::viewVector * \qmlproperty vector3d Qt3D.Render::Camera::viewVector
* Holds the camera's view vector in coordinates relative to * Holds the camera's view vector in coordinates relative to
* the parent entity. * the parent entity.
*
* This vector decribes the displacement from the camera (\l position)
* to its target (\l viewCenter).
* \readonly * \readonly
*/ */
@ -348,30 +384,44 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
/*! /*!
* \property QCamera::projectionType * \property QCamera::projectionType
* *
* Holds the type of the camera projection. * Holds the type of the camera projection. The default value is
* QCameraLens::PerspectiveProjection.
* *
* \list * \list
* \li CameraLens.OrthographicProjection * \li QCameraLens::OrthographicProjection - Parallel lines appear parallel. Objects appear
* \li CameraLens.PerspectiveProjection * the same size regardless of distance.
* \li CameraLens.FrustumProjection * \li QCameraLens::PerspectiveProjection - Parallel lines appear to meet in the distance.
* \li CameraLens.CustomProjection * Objects appear to shrink the farther they are from the camera.
* \li QCameraLens::FrustumProjection
* \li QCameraLens::CustomProjection
* \endlist * \endlist
* \sa Qt3DRender::QCameraLens::ProjectionType * \sa Qt3DRender::QCameraLens::ProjectionType
*/ */
/*! /*!
* \property QCamera::nearPlane * \property QCamera::nearPlane
* Holds the current camera near plane. * Holds the current camera near plane. Objects that are closer to the
* camera than the nearPlane will not be rendered.
*/ */
/*! /*!
* \property QCamera::farPlane * \property QCamera::farPlane
* Holds the current camera far plane. * Holds the current camera far plane. Objects that are farther from the
* camera than the farPlane will not be rendered.
*/ */
/*! /*!
* \property QCamera::fieldOfView * \property QCamera::fieldOfView
* Holds the current field of view in degrees. * Holds the current vertical field of view in degrees.
*
* Along with \l aspectRatio, this property determines how much of
* the scene is visible to the camera. In that respect you might
* think of it as analogous to choosing a wide angle (wide horizontal
* field of view) or telephoto (narrow horizontal field of view) lens
* depending on how much of a scene you want to capture.
*
* fieldOfView is only relevant when \l projectionType is
* QCameraLens::PerspectiveProjection.
*/ */
/*! /*!
@ -382,21 +432,33 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
/*! /*!
*\property QCamera::left *\property QCamera::left
* Holds the current left of the camera. * Holds the current left of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/ */
/*! /*!
* \property QCamera::right * \property QCamera::right
* Holds the current right of the camera. * Holds the current right of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/ */
/*! /*!
* \property QCamera::bottom * \property QCamera::bottom
* Holds the current bottom of the camera. * Holds the current bottom of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/ */
/*! /*!
* \property QCamera::top * \property QCamera::top
* Holds the current top of the camera. * Holds the current top of the camera.
*
* This property is only relevant when \l projectionType is
* QCameraLens::OrthographicProjection.
*/ */
/*! /*!
@ -419,18 +481,29 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
* \property QCamera::upVector * \property QCamera::upVector
* Holds the camera's up vector in coordinates relative to * Holds the camera's up vector in coordinates relative to
* the parent entity. * the parent entity.
*
* The up vector indicates which direction the top of the camera is
* facing. Think of taking a picture: after positioning yourself
* and pointing the camera at your target, you might rotate the camera
* left or right, giving you a portrait or landscape (or angled!)
* shot. upVector allows you to control this type of movement.
*/ */
/*! /*!
* \property QCamera::viewCenter * \property QCamera::viewCenter
* Holds the camera's view center in coordinates relative to * Holds the camera's view center in coordinates relative to
* the parent entity. * the parent entity.
*
* Intuitively, the viewCenter is the location the camera is pointing at.
*/ */
/*! /*!
* \property QCamera::viewVector * \property QCamera::viewVector
* Holds the camera's view vector in coordinates relative to * Holds the camera's view vector in coordinates relative to
* the parent entity. * the parent entity.
*
* This vector decribes the displacement from the camera (\l position)
* to its target (\l viewCenter).
*/ */
/*! /*!

View File

@ -153,6 +153,7 @@ Qt3DCore::QBackendNode *JointFunctor::get(Qt3DCore::QNodeId id) const
void JointFunctor::destroy(Qt3DCore::QNodeId id) const void JointFunctor::destroy(Qt3DCore::QNodeId id) const
{ {
m_jointManager->removeDirtyJoint(id);
m_jointManager->releaseResource(id); m_jointManager->releaseResource(id);
} }

View File

@ -101,7 +101,7 @@ QRay3D::QRay3D()
*/ */
QRay3D::QRay3D(const Vector3D &origin, const Vector3D &direction, float distance) QRay3D::QRay3D(const Vector3D &origin, const Vector3D &direction, float distance)
: m_origin(origin) : m_origin(origin)
, m_direction(direction) , m_direction(direction.normalized())
, m_distance(distance) , m_distance(distance)
{} {}
@ -157,7 +157,7 @@ void QRay3D::setDirection(const Vector3D &value)
if (value.isNull()) if (value.isNull())
return; return;
m_direction = value; m_direction = value.normalized();
} }
float QRay3D::distance() const float QRay3D::distance() const
@ -178,14 +178,14 @@ Vector3D QRay3D::point(float t) const
QRay3D &QRay3D::transform(const Matrix4x4 &matrix) QRay3D &QRay3D::transform(const Matrix4x4 &matrix)
{ {
m_origin = matrix * m_origin; m_origin = matrix * m_origin;
m_direction = matrix.mapVector(m_direction); m_direction = matrix.mapVector(m_direction).normalized();
return *this; return *this;
} }
QRay3D QRay3D::transformed(const Matrix4x4 &matrix) const QRay3D QRay3D::transformed(const Matrix4x4 &matrix) const
{ {
return QRay3D(matrix * m_origin, matrix.mapVector(m_direction)); return QRay3D(matrix * m_origin, matrix.mapVector(m_direction).normalized());
} }
bool QRay3D::operator==(const QRay3D &other) const bool QRay3D::operator==(const QRay3D &other) const

View File

@ -108,23 +108,23 @@ void tst_QRay3D::create_data()
// non-normalized direction vectors // non-normalized direction vectors
QTest::newRow("line on x-axis from origin - B") QTest::newRow("line on x-axis from origin - B")
<< Vector3D() << Vector3D()
<< Vector3D(2.0f, 0.0f, 0.0f); << Vector3D(2.0f, 0.0f, 0.0f).normalized();
QTest::newRow("line parallel -z-axis from 3,3,3 - B") QTest::newRow("line parallel -z-axis from 3,3,3 - B")
<< Vector3D(3.0f, 3.0f, 3.0f) << Vector3D(3.0f, 3.0f, 3.0f)
<< Vector3D(0.0f, 0.0f, -0.7f); << Vector3D(0.0f, 0.0f, -0.7f).normalized();
QTest::newRow("vertical line (parallel to y-axis) - B") QTest::newRow("vertical line (parallel to y-axis) - B")
<< Vector3D(0.5f, 0.0f, 0.5f) << Vector3D(0.5f, 0.0f, 0.5f)
<< Vector3D(0.0f, 5.3f, 0.0f); << Vector3D(0.0f, 5.3f, 0.0f).normalized();
QTest::newRow("equidistant from all 3 axes - B") QTest::newRow("equidistant from all 3 axes - B")
<< Vector3D(0.5f, 0.0f, 0.5f) << Vector3D(0.5f, 0.0f, 0.5f)
<< Vector3D(1.0f, 1.0f, 1.0f); << Vector3D(1.0f, 1.0f, 1.0f).normalized();
QTest::newRow("negative direction") QTest::newRow("negative direction")
<< Vector3D(-3.0f, -3.0f, -3.0f) << Vector3D(-3.0f, -3.0f, -3.0f)
<< Vector3D(-1.2f, -1.8f, -2.4f); << Vector3D(-1.2f, -1.8f, -2.4f).normalized();
} }
void tst_QRay3D::create() void tst_QRay3D::create()
@ -203,32 +203,32 @@ void tst_QRay3D::point_data()
QTest::newRow("line on x-axis from origin") QTest::newRow("line on x-axis from origin")
<< Vector3D() << Vector3D()
<< Vector3D(2.0f, 0.0f, 0.0f) << Vector3D(2.0f, 0.0f, 0.0f)
<< Vector3D(1.2f, 0.0f, 0.0f) << Vector3D(0.6f, 0.0f, 0.0f)
<< Vector3D(-14.4f, 0.0f, 0.0f); << Vector3D(-7.2f, 0.0f, 0.0f);
QTest::newRow("line parallel -z-axis from 3,3,3") QTest::newRow("line parallel -z-axis from 3,3,3")
<< Vector3D(3.0f, 3.0f, 3.0f) << Vector3D(3.0f, 3.0f, 3.0f)
<< Vector3D(0.0f, 0.0f, -0.7f) << Vector3D(0.0f, 0.0f, -0.7f)
<< Vector3D(3.0f, 3.0f, 2.58f) << Vector3D(3.0f, 3.0f, 2.4f)
<< Vector3D(3.0f, 3.0f, 8.04f); << Vector3D(3.0f, 3.0f, 10.2f);
QTest::newRow("vertical line (parallel to y-axis)") QTest::newRow("vertical line (parallel to y-axis)")
<< Vector3D(0.5f, 0.0f, 0.5f) << Vector3D(0.5f, 0.0f, 0.5f)
<< Vector3D(0.0f, 5.3f, 0.0f) << Vector3D(0.0f, 5.3f, 0.0f)
<< Vector3D(0.5f, 3.18f, 0.5f) << Vector3D(0.5f, 0.6f, 0.5f)
<< Vector3D(0.5f, -38.16f, 0.5f); << Vector3D(0.5f, -7.2f, 0.5f);
QTest::newRow("equidistant from all 3 axes") QTest::newRow("equidistant from all 3 axes")
<< Vector3D(0.5f, 0.0f, 0.5f) << Vector3D(0.5f, 0.0f, 0.5f)
<< Vector3D(1.0f, 1.0f, 1.0f) << Vector3D(1.0f, 1.0f, 1.0f)
<< Vector3D(1.1f, 0.6f, 1.1f) << Vector3D(0.84641f, 0.34641f, 0.84641f)
<< Vector3D(-6.7f, -7.2f, -6.7f); << Vector3D(-3.65692f, -4.15692f, -3.65692f);
QTest::newRow("negative direction") QTest::newRow("negative direction")
<< Vector3D(-3.0f, -3.0f, -3.0f) << Vector3D(-3.0f, -3.0f, -3.0f)
<< Vector3D(-1.2f, -1.8f, -2.4f) << Vector3D(-1.2f, -1.8f, -2.4f)
<< Vector3D(-3.72f, -4.08f, -4.44f) << Vector3D(-3.22283f, -3.33425f, -3.44567f)
<< Vector3D(5.64f, 9.96f, 14.28f); << Vector3D(-0.325987f, 1.01102f, 2.34803f);
} }
void tst_QRay3D::point() void tst_QRay3D::point()
@ -475,7 +475,7 @@ void tst_QRay3D::transform()
QVERIFY(fuzzyCompare(ray1.direction(), ray3.direction())); QVERIFY(fuzzyCompare(ray1.direction(), ray3.direction()));
QVERIFY(fuzzyCompare(ray1.origin(), m * point)); QVERIFY(fuzzyCompare(ray1.origin(), m * point));
QVERIFY(fuzzyCompare(ray1.direction(), m.mapVector(direction))); QVERIFY(fuzzyCompare(ray1.direction(), m.mapVector(direction).normalized()));
} }
class tst_QRay3DProperties : public QObject class tst_QRay3DProperties : public QObject
@ -503,7 +503,7 @@ void tst_QRay3D::properties()
Qt3DRender::RayCasting::QRay3D r = qvariant_cast<Qt3DRender::RayCasting::QRay3D>(obj.property("ray")); Qt3DRender::RayCasting::QRay3D r = qvariant_cast<Qt3DRender::RayCasting::QRay3D>(obj.property("ray"));
QCOMPARE(r.origin(), Vector3D(1, 2, 3)); QCOMPARE(r.origin(), Vector3D(1, 2, 3));
QCOMPARE(r.direction(), Vector3D(4, 5, 6)); QCOMPARE(r.direction(), Vector3D(4, 5, 6).normalized());
obj.setProperty("ray", obj.setProperty("ray",
QVariant::fromValue QVariant::fromValue
@ -511,7 +511,7 @@ void tst_QRay3D::properties()
r = qvariant_cast<Qt3DRender::RayCasting::QRay3D>(obj.property("ray")); r = qvariant_cast<Qt3DRender::RayCasting::QRay3D>(obj.property("ray"));
QCOMPARE(r.origin(), Vector3D(-1, -2, -3)); QCOMPARE(r.origin(), Vector3D(-1, -2, -3));
QCOMPARE(r.direction(), Vector3D(-4, -5, -6)); QCOMPARE(r.direction(), Vector3D(-4, -5, -6).normalized());
} }
void tst_QRay3D::metaTypes() void tst_QRay3D::metaTypes()