Commit 0ff2215b authored by Paul Lemire's avatar Paul Lemire
Browse files

Merge "Merge remote-tracking branch 'origin/5.13' into 5.14"

parents 0ce9f6a4 7339e9ae
......@@ -125,6 +125,11 @@ QAbstractClipAnimator::QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Q
QAbstractClipAnimator::~QAbstractClipAnimator()
{
}
/*!
\qmlproperty bool Qt3DAnimation::AbstractClipAnimator::running
This property holds a boolean indicating whether the animation is currently running.
*/
/*!
\property Qt3DAnimation::QAbstractClipAnimator::running
......@@ -141,6 +146,13 @@ bool QAbstractClipAnimator::isRunning() const
return d->m_running;
}
/*!
\qmlproperty ChannelMapper Qt3DAnimation::AbstractClipAnimator::channelMapper
This property holds the ChannelMapper that controls how the channels in
the animation clip map onto the properties of the target objects.
*/
/*!
\property Qt3DAnimation::QAbstractClipAnimator::channelMapper
......@@ -198,6 +210,12 @@ int QAbstractClipAnimator::loopCount() const
Q_D(const QAbstractClipAnimator);
return d->m_loops;
}
/*!
\qmlproperty Clock Qt3DAnimation::AbstractClipAnimator::clock
The clock controls the speed with which an animation is played.
*/
/*!
\property Qt3DAnimation::QAbstractClipAnimator::clock
......@@ -208,7 +226,11 @@ QClock *QAbstractClipAnimator::clock() const
Q_D(const QAbstractClipAnimator);
return d->m_clock;
}
/*!
\qmlproperty real Qt3DAnimation::AbstractClipAnimator::normalizedTime
This property holds the clips normalized time.
*/
/*!
\property Qt3DAnimation::QAbstractClipAnimator::normalizedTime
......
......@@ -56,6 +56,7 @@ QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate()
\qmltype BlendedClipAnimator
\instantiates Qt3DAnimation::QBlendedClipAnimator
\inqmlmodule Qt3D.Animation
\inherits AbstractClipAnimator
\since 5.9
\brief BlendedClipAnimator is a component providing animation playback capabilities of a tree
......
......@@ -66,6 +66,7 @@ bool QClipAnimatorPrivate::canPlay() const
\qmltype ClipAnimator
\instantiates Qt3DAnimation::QClipAnimator
\inqmlmodule Qt3D.Animation
\inherits AbstractClipAnimator
\since 5.9
\brief ClipAnimator is a component providing simple animation playback capabilities.
......
......@@ -2,7 +2,7 @@ TEMPLATE = subdirs
# QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp
# sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964).
QT_FOR_CONFIG += 3dcore-private
qtConfig(assimp):if(qtConfig(system-assimp)|android-clang|gcc:greaterThan(QT_GCC_MAJOR_VERSION, 4)): {
!ios:!tvos:!qcc:qtConfig(assimp):if(qtConfig(system-assimp)|android-clang|clang|win32-msvc)|if(gcc:greaterThan(QT_GCC_MAJOR_VERSION, 4)) {
SUBDIRS += assimp
}
SUBDIRS += gltf
......
......@@ -529,6 +529,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject)
m_dummySurface = new QOffscreenSurface;
m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living
m_dummySurface->setFormat(rw->format());
m_dummySurface->setScreen(rw->screen());
m_dummySurface->create();
surfaceSelector->setSurface(m_dummySurface);
} else {
......@@ -616,6 +617,9 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode
// If the render aspect wasn't created yet, do so now
if (m_renderAspect == nullptr) {
m_renderAspect = new QRenderAspect(QRenderAspect::Synchronous);
auto *rw = QQuickRenderControl::renderWindowFor(window());
static_cast<Qt3DRender::QRenderAspectPrivate *>(Qt3DRender::QRenderAspectPrivate::get(m_renderAspect))->m_screen =
(rw ? rw->screen() : window()->screen());
m_aspectEngine->registerAspect(m_renderAspect);
// Before Synchronizing is in the SG Thread, we want beforeSync to be triggered
......
......@@ -66,6 +66,7 @@
#include <Qt3DQuickExtras/private/qt3dquickwindowlogging_p.h>
#include <Qt3DRender/private/qrendersurfaceselector_p.h>
#include <Qt3DRender/private/qrenderaspect_p.h>
QT_BEGIN_NAMESPACE
......@@ -132,6 +133,8 @@ Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent)
QSurfaceFormat::setDefaultFormat(format);
d->m_renderAspect = new Qt3DRender::QRenderAspect;
if (parent && parent->screen())
static_cast<Qt3DRender::QRenderAspectPrivate*>(Qt3DRender::QRenderAspectPrivate::get(d->m_renderAspect))->m_screen = parent->screen();
d->m_inputAspect = new Qt3DInput::QInputAspect;
d->m_logicAspect = new Qt3DLogic::QLogicAspect;
d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine;
......
......@@ -68,6 +68,8 @@ namespace Quick {
with the item; if an entity has a QObjectPicker component, the pick events from that picker
are sent to the QScene2D and converted to mouse events and finally sent to the item.
\note Only mouse events are supported. The item does not support keyboard input.
\since 5.9
*/
......@@ -89,6 +91,8 @@ namespace Quick {
with the item; if an entity has an ObjectPicker component, the pick events from that picker
are sent to the Scene2D and converted to mouse events and finally sent to the item.
\note Only mouse events are supported. The item does not support keyboard input.
Usage:
\qml
Entity {
......
......@@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE
class QSurface;
class QSize;
class QScreen;
namespace Qt3DCore {
class QAbstractFrameAdvanceService;
......@@ -175,6 +176,8 @@ public:
// For QtQuick rendering
virtual void setOpenGLContext(QOpenGLContext *ctx) = 0;
virtual void setScreen(QScreen *) {}
virtual QScreen *screen() const { return nullptr; }
virtual void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) = 0;
virtual QSurfaceFormat format() = 0;
......
......@@ -72,6 +72,7 @@ void OffscreenSurfaceHelper::createOffscreenSurface()
m_offscreenSurface = new QOffscreenSurface;
m_offscreenSurface->setParent(this);
m_offscreenSurface->setFormat(m_renderer->format());
m_offscreenSurface->setScreen(m_renderer->screen());
m_offscreenSurface->create();
}
......
......@@ -107,10 +107,6 @@ bool PlatformSurfaceFilter::eventFilter(QObject *obj, QEvent *e)
// If we remove it, the call to isSurfaceValid will
// implicitely return false
PlatformSurfaceFilter::m_surfacesValidity.remove(m_surface);
if (m_obj) {
m_obj->removeEventFilter(this);
m_obj = nullptr;
}
break;
}
......
......@@ -66,7 +66,7 @@ namespace Qt3DRender {
/*!
\qmltype ComputeCommand
\since 5.7
\inmodule Qt3DRender
\inqmlmodule Qt3D.Render
\inherits Component3D
\instantiates Qt3DRender::QComputeCommand
\brief Component to issue work for the compute shader on GPU.
......
......@@ -562,6 +562,7 @@ void QRenderAspect::onRegistered()
// TO DO: Load proper Renderer class based on Qt configuration preferences
d->m_renderer = new Render::Renderer(d->m_renderType);
d->m_renderer->setScreen(d->m_screen);
d->m_renderer->setNodeManagers(d->m_nodeManagers);
// Create a helper for deferring creation of an offscreen surface used during cleanup
......
......@@ -60,6 +60,7 @@
QT_BEGIN_NAMESPACE
class QSurface;
class QScreen;
namespace Qt3DRender {
......@@ -106,6 +107,7 @@ public:
QVector<Render::QRenderPlugin *> m_renderPlugins;
QRenderAspect::RenderType m_renderType;
Render::OffscreenSurfaceHelper *m_offscreenHelper;
QScreen *m_screen = nullptr;
static QMutex m_pluginLock;
static QVector<QString> m_pluginConfig;
......
......@@ -44,6 +44,7 @@
#include <QPair>
#include <math.h>
#include <algorithm>
QT_BEGIN_NAMESPACE
......@@ -55,6 +56,9 @@ namespace {
// returns true and intersection point q; false otherwise
bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRender::Render::Sphere &s, Vector3D *q = nullptr)
{
if (s.isNull())
return false;
const Vector3D p = ray.origin();
const Vector3D d = ray.direction();
const Vector3D m = p - s.center();
......@@ -139,11 +143,31 @@ inline void sphereFromExtremePoints(Qt3DRender::Render::Sphere &s, const QVector
inline void constructRitterSphere(Qt3DRender::Render::Sphere &s, const QVector<Vector3D> &points)
{
// Calculate the sphere encompassing two axially extreme points
sphereFromExtremePoints(s, points);
// Now make sure the sphere bounds all points by growing if needed
s.expandToContain(points);
//def bounding_sphere(points):
// dist = lambda a,b: ((a[0] - b[0])**2 + (a[1] - b[1])**2 + (a[2] - b[2])**2)**0.5
// x = points[0]
// y = max(points,key= lambda p: dist(p,x) )
// z = max(points,key= lambda p: dist(p,y) )
// bounding_sphere = (((y[0]+z[0])/2,(y[1]+z[1])/2,(y[2]+z[2])/2), dist(y,z)/2)
//
// exterior_points = [p for p in points if dist(p,bounding_sphere[0]) > bounding_sphere[1] ]
// while ( len(exterior_points) > 0 ):
// pt = exterior_points.pop()
// if (dist(pt, bounding_sphere[0]) > bounding_sphere[1]):
// bounding_sphere = (bounding_sphere[0],dist(pt,bounding_sphere[0]))
//
// return bounding_sphere
const Vector3D x = points[0];
const Vector3D y = *std::max_element(points.begin(), points.end(), [&x](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - x).lengthSquared() < (rhs - x).lengthSquared(); });
const Vector3D z = *std::max_element(points.begin(), points.end(), [&y](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - y).lengthSquared() < (rhs - y).lengthSquared(); });
const Vector3D center = (y + z) * 0.5f;
const Vector3D maxDistPt = *std::max_element(points.begin(), points.end(), [&center](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - center).lengthSquared() < (rhs - center).lengthSquared(); });
const float radius = (maxDistPt - center).length();
s.setCenter(center);
s.setRadius(radius);
}
} // anonymous namespace
......@@ -169,6 +193,12 @@ void Sphere::initializeFromPoints(const QVector<Vector3D> &points)
void Sphere::expandToContain(const Vector3D &p)
{
if (isNull()) {
m_center = p;
m_radius = 0.0f;
return;
}
const Vector3D d = p - m_center;
const float dist2 = d.lengthSquared();
......@@ -184,6 +214,13 @@ void Sphere::expandToContain(const Vector3D &p)
void Sphere::expandToContain(const Sphere &sphere)
{
if (isNull()) {
*this = sphere;
return;
} else if (sphere.isNull()) {
return;
}
const Vector3D d(sphere.m_center - m_center);
const float dist2 = d.lengthSquared();
......@@ -206,6 +243,9 @@ void Sphere::expandToContain(const Sphere &sphere)
Sphere Sphere::transformed(const Matrix4x4 &mat) const
{
if (isNull())
return *this;
// Transform extremities in x, y, and z directions to find extremities
// of the resulting ellipsoid
Vector3D x = mat.map(m_center + Vector3D(m_radius, 0.0f, 0.0f));
......
......@@ -69,7 +69,7 @@ class Q_3DRENDERSHARED_PRIVATE_EXPORT Sphere : public RayCasting::BoundingSphere
public:
inline Sphere(Qt3DCore::QNodeId i = Qt3DCore::QNodeId())
: m_center()
, m_radius(0.0f)
, m_radius(-1.0f)
, m_id(i)
{}
......@@ -82,7 +82,7 @@ public:
void setCenter(const Vector3D &c);
Vector3D center() const override;
inline bool isNull() { return m_center == Vector3D() && m_radius == 0.0f; }
bool isNull() const { return m_center == Vector3D() && m_radius == -1.0f; }
void setRadius(float r);
float radius() const override;
......@@ -131,7 +131,9 @@ inline Vector3D Sphere::center() const
inline void Sphere::setRadius(float r)
{
m_radius = r;
Q_ASSERT(r >= 0.0f);
if (r >= 0.0f)
m_radius = r;
}
inline float Sphere::radius() const
......@@ -142,11 +144,14 @@ inline float Sphere::radius() const
inline void Sphere::clear()
{
m_center = Vector3D();
m_radius = 0.0f;
m_radius = -1.0f;
}
inline bool intersects(const Sphere &a, const Sphere &b)
{
if (a.isNull() || b.isNull())
return false;
// Calculate squared distance between sphere centers
const Vector3D d = a.center() - b.center();
const float distSq = Vector3D::dotProduct(d, d);
......
......@@ -90,30 +90,42 @@ public:
m_min = QVector3D(findExtremePoints.xMin, findExtremePoints.yMin, findExtremePoints.zMin);
m_max = QVector3D(findExtremePoints.xMax, findExtremePoints.yMax, findExtremePoints.zMax);
// Calculate squared distance for the pairs of points
const float xDist2 = (findExtremePoints.xMaxPt - findExtremePoints.xMinPt).lengthSquared();
const float yDist2 = (findExtremePoints.yMaxPt - findExtremePoints.yMinPt).lengthSquared();
const float zDist2 = (findExtremePoints.zMaxPt - findExtremePoints.zMinPt).lengthSquared();
// Select most distant pair
Vector3D p = findExtremePoints.xMinPt;
Vector3D q = findExtremePoints.xMaxPt;
if (yDist2 > xDist2 && yDist2 > zDist2) {
p = findExtremePoints.yMinPt;
q = findExtremePoints.yMaxPt;
FindMaxDistantPoint maxDistantPointY(m_manager);
maxDistantPointY.setReferencePoint = true;
if (!maxDistantPointY.apply(positionAttribute, indexAttribute, drawVertexCount,
primitiveRestartEnabled, primitiveRestartIndex)) {
return false;
}
if (zDist2 > xDist2 && zDist2 > yDist2) {
p = findExtremePoints.zMinPt;
q = findExtremePoints.zMaxPt;
if (maxDistantPointY.hasNoPoints)
return false;
//const Vector3D x = maxDistantPointY.referencePt;
const Vector3D y = maxDistantPointY.maxDistPt;
FindMaxDistantPoint maxDistantPointZ(m_manager);
maxDistantPointZ.setReferencePoint = false;
maxDistantPointZ.referencePt = y;
if (!maxDistantPointZ.apply(positionAttribute, indexAttribute, drawVertexCount,
primitiveRestartEnabled, primitiveRestartIndex)) {
return false;
}
const Vector3D z = maxDistantPointZ.maxDistPt;
const Vector3D center = (y + z) * 0.5f;
FindMaxDistantPoint maxDistantPointCenter(m_manager);
maxDistantPointCenter.setReferencePoint = false;
maxDistantPointCenter.referencePt = center;
if (!maxDistantPointCenter.apply(positionAttribute, indexAttribute, drawVertexCount,
primitiveRestartEnabled, primitiveRestartIndex)) {
return false;
}
const Vector3D c = 0.5f * (p + q);
m_volume.setCenter(c);
m_volume.setRadius((q - c).length());
const float radius = (center - maxDistantPointCenter.maxDistPt).length();
ExpandSphere expandSphere(m_manager, m_volume);
if (!expandSphere.apply(positionAttribute, indexAttribute, drawVertexCount,
primitiveRestartEnabled, primitiveRestartIndex))
m_volume = Qt3DRender::Render::Sphere(center, radius);
if (m_volume.isNull())
return false;
return true;
......@@ -172,18 +184,34 @@ private:
}
};
class ExpandSphere : public Buffer3fVisitor
class FindMaxDistantPoint : public Buffer3fVisitor
{
public:
ExpandSphere(NodeManagers *manager, Sphere& volume)
: Buffer3fVisitor(manager), m_volume(volume)
FindMaxDistantPoint(NodeManagers *manager)
: Buffer3fVisitor(manager)
{ }
Sphere& m_volume;
float maxLengthSquared = 0.0f;
Vector3D maxDistPt;
Vector3D referencePt;
bool setReferencePoint = false;
bool hasNoPoints = true;
void visit(uint ndx, float x, float y, float z) override
{
Q_UNUSED(ndx);
m_volume.expandToContain(Vector3D(x, y, z));
const Vector3D p = Vector3D(x, y, z);
if (hasNoPoints && setReferencePoint) {
maxLengthSquared = 0.0f;
referencePt = p;
}
const float lengthSquared = (p - referencePt).lengthSquared();
if ( lengthSquared >= maxLengthSquared ) {
maxDistPt = p;
maxLengthSquared = lengthSquared;
}
hasNoPoints = false;
}
};
};
......
......@@ -202,12 +202,12 @@ void PickBoundingVolumeJob::setRoot(Entity *root)
void PickBoundingVolumeJob::setMouseEvents(const QList<QPair<QObject*, QMouseEvent>> &pendingEvents)
{
m_pendingMouseEvents = pendingEvents;
m_pendingMouseEvents.append(pendingEvents);
}
void PickBoundingVolumeJob::setKeyEvents(const QList<QKeyEvent> &pendingEvents)
{
m_pendingKeyEvents = pendingEvents;
m_pendingKeyEvents.append(pendingEvents);
}
void PickBoundingVolumeJob::markPickersDirty()
......
......@@ -65,6 +65,8 @@ QEffectPrivate::QEffectPrivate()
An QEffect instance should be shared among several QMaterial instances when possible.
\note QEffect node can not be disabled.
\code
QEffect *effect = new QEffect();
......@@ -111,6 +113,8 @@ QEffectPrivate::QEffectPrivate()
A Parameter defined on an Effect is overridden by a QParameter (of the same
name) defined in a Material, TechniqueFilter, RenderPassFilter.
\note Effect node can not be disabled.
\code
Effect {
id: effect
......
......@@ -60,6 +60,8 @@ QFilterKeyPrivate::QFilterKeyPrivate()
Filter keys are used by QTechnique and QRenderPass to specify at which stage of rendering the
technique or the render pass is used.
\note QFilterKey node can not be disabled.
*/
/*!
......@@ -73,6 +75,8 @@ QFilterKeyPrivate::QFilterKeyPrivate()
A FilterKey is a storage type for filter key and value pair.
Filter keys are used by Technique and RenderPass to specify at which stage of rendering the
technique or the render pass is used.
\note FilterKey node can not be disabled.
*/
QFilterKey::QFilterKey(QNode *parent)
......
......@@ -76,6 +76,8 @@
\note when the targeted uniform is an array, the name should be the name
of the uniform with [0] appended to it.
\note Parameter node can not be disabled.
\code
Parameter {
name: "diffuseValues[0]"
......@@ -138,6 +140,8 @@
\note when the targeted uniform is an array, the name should be the name
of the uniform with [0] appended to it.
\note QParameter node can not be disabled.
\code
QParameter *param = new QParameter();
QVariantList values = QVariantList() << 0.0f << 1.0f << 2.0f << 3.0f << 4.0f << 883.0f << 1340.0f << 1584.0f;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment