mirror of https://github.com/qt/qt3d.git
Merge "Merge remote-tracking branch 'origin/5.13' into 5.14"
This commit is contained in:
commit
0ff2215bb0
|
|
@ -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);
|
||||
//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
|
||||
|
||||
// Now make sure the sphere bounds all points by growing if needed
|
||||
s.expandToContain(points);
|
||||
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(), [¢er](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;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ QTechniquePrivate::~QTechniquePrivate()
|
|||
QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view
|
||||
will likely have no effect on Qt3D related rendering.
|
||||
|
||||
\note Technique node can not be disabled.
|
||||
|
||||
\qml
|
||||
Technique {
|
||||
id: gl3Technique
|
||||
|
|
@ -152,6 +154,8 @@ QTechniquePrivate::~QTechniquePrivate()
|
|||
QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view
|
||||
will likely have no effect on Qt3D related rendering.
|
||||
|
||||
\note QTechnique node can not be disabled.
|
||||
|
||||
\code
|
||||
QTechnique *gl3Technique = new QTechnique();
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ namespace Qt3DRender {
|
|||
\note Instances of this component shouldn't be shared, not respecting that
|
||||
condition will most likely result in undefined behavior.
|
||||
|
||||
\note The camera far plane value affects picking and produces incorrect results due to
|
||||
floating-point precision if it is greater than ~100 000.
|
||||
|
||||
\since 5.6
|
||||
*/
|
||||
|
||||
|
|
@ -115,6 +118,9 @@ namespace Qt3DRender {
|
|||
|
||||
\note Instances of this component shouldn't be shared, not respecting that
|
||||
condition will most likely result in undefined behavior.
|
||||
|
||||
\note The camera far plane value affects picking and produces incorrect results due to
|
||||
floating-point precision if it is greater than ~100 000.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -347,6 +347,16 @@ void Renderer::setOpenGLContext(QOpenGLContext *context)
|
|||
m_glContext = context;
|
||||
}
|
||||
|
||||
void Renderer::setScreen(QScreen *scr)
|
||||
{
|
||||
m_screen = scr;
|
||||
}
|
||||
|
||||
QScreen *Renderer::screen() const
|
||||
{
|
||||
return m_screen;
|
||||
}
|
||||
|
||||
// Called in RenderThread context by the run method of RenderThread
|
||||
// RenderThread has locked the mutex already and unlocks it when this
|
||||
// method termintates
|
||||
|
|
@ -364,6 +374,8 @@ void Renderer::initialize()
|
|||
// we need to create it
|
||||
if (!m_glContext) {
|
||||
ctx = new QOpenGLContext;
|
||||
if (m_screen)
|
||||
ctx->setScreen(m_screen);
|
||||
ctx->setShareContext(qt_gl_global_share_context());
|
||||
|
||||
// TO DO: Shouldn't we use the highest context available and trust
|
||||
|
|
@ -393,6 +405,8 @@ void Renderer::initialize()
|
|||
|
||||
if (!ctx->shareContext()) {
|
||||
m_shareContext = new QOpenGLContext;
|
||||
if (ctx->screen())
|
||||
m_shareContext->setScreen(ctx->screen());
|
||||
m_shareContext->setFormat(ctx->format());
|
||||
m_shareContext->setShareContext(ctx);
|
||||
m_shareContext->create();
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
class QSurface;
|
||||
class QMouseEvent;
|
||||
class QScreen;
|
||||
|
||||
namespace Qt3DCore {
|
||||
class QEntity;
|
||||
|
|
@ -293,6 +294,8 @@ public:
|
|||
ViewSubmissionResultData submitRenderViews(const QVector<Render::RenderView *> &renderViews);
|
||||
|
||||
RendererCache *cache() { return &m_cache; }
|
||||
void setScreen(QScreen *scr) override;
|
||||
QScreen *screen() const override;
|
||||
|
||||
#ifdef QT3D_RENDER_UNIT_TESTS
|
||||
public:
|
||||
|
|
@ -426,6 +429,7 @@ private:
|
|||
bool m_shouldSwapBuffers;
|
||||
|
||||
QVector<FrameGraphNode *> m_frameGraphLeaves;
|
||||
QScreen *m_screen = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace Qt3DRender {
|
|||
|
||||
/*!
|
||||
\qmltype RenderState
|
||||
\inqmlmodule Qt3D.Render
|
||||
\brief An abstract base type for all render states.
|
||||
\since 5.7
|
||||
\inherits Node
|
||||
|
|
|
|||
|
|
@ -204,13 +204,150 @@ class tst_BoundingSphere : public Qt3DCore::QBackendNodeTester
|
|||
private:
|
||||
|
||||
private Q_SLOTS:
|
||||
void checkIsNull() {
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
QVERIFY(defaultSphere.isNull());
|
||||
}
|
||||
|
||||
void remainsNotNullAfterTransform() {
|
||||
QMatrix4x4 mat;
|
||||
mat.translate(-5,-5,-5);
|
||||
auto mMat = Matrix4x4(mat);
|
||||
auto pointSphere = Qt3DRender::Render::Sphere(Vector3D(5.f,5.f,5.f),0.f);
|
||||
pointSphere.transform(mMat);
|
||||
QVERIFY(!pointSphere.isNull());
|
||||
QVERIFY(pointSphere.center() == Vector3D(0.,0.,0));
|
||||
QVERIFY(pointSphere.radius() == 0.f);
|
||||
}
|
||||
|
||||
void remainsNullAfterTransform() {
|
||||
QMatrix4x4 mat;
|
||||
mat.translate(-5,-5,-5);
|
||||
auto mMat = Matrix4x4(mat);
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
defaultSphere.transform(mMat);
|
||||
QVERIFY(defaultSphere.isNull());
|
||||
}
|
||||
|
||||
void expandToContainSphere() {
|
||||
auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
|
||||
auto secondValidSphere = Qt3DRender::Render::Sphere(Vector3D(10.f,10.f,10.f),1.f);
|
||||
firstValidSphere.expandToContain(secondValidSphere);
|
||||
QVERIFY(firstValidSphere.center()==Vector3D(0.f,0.f,0.f));
|
||||
float dist = static_cast<float>((2 + sqrt(3.*(20)*(20)))/2.);
|
||||
QVERIFY(qFuzzyCompare(firstValidSphere.radius(), dist));
|
||||
}
|
||||
|
||||
void expandToContainSphereOneInvalid() {
|
||||
auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
auto copiedSphere = firstValidSphere;
|
||||
firstValidSphere.expandToContain(defaultSphere);
|
||||
QVERIFY(firstValidSphere.center() == copiedSphere.center());
|
||||
QVERIFY(firstValidSphere.radius() == copiedSphere.radius());
|
||||
QVERIFY(!firstValidSphere.isNull());
|
||||
}
|
||||
|
||||
void expandToContainOtherSphereInvalid() {
|
||||
auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
defaultSphere.expandToContain(firstValidSphere);
|
||||
QVERIFY(defaultSphere.center() == firstValidSphere.center());
|
||||
QVERIFY(defaultSphere.radius() == firstValidSphere.radius());
|
||||
QVERIFY(!defaultSphere.isNull());
|
||||
}
|
||||
|
||||
void expandNullSphereWithNullSphere() {
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
auto otherDefaultSphere = Qt3DRender::Render::Sphere();
|
||||
defaultSphere.expandToContain(otherDefaultSphere);
|
||||
QVERIFY(defaultSphere.isNull());
|
||||
}
|
||||
|
||||
void expandToContainPoint() {
|
||||
auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
|
||||
firstValidSphere.expandToContain(Vector3D(0,0,0));
|
||||
QVERIFY(!firstValidSphere.isNull());
|
||||
float expectedRadius = static_cast<float>((1 + qSqrt(3.*(10)*(10)))/2.);
|
||||
QVERIFY(qFuzzyCompare(firstValidSphere.radius(), expectedRadius));
|
||||
}
|
||||
|
||||
void nullSphereExpandToContainPoint() {
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
defaultSphere.expandToContain(Vector3D(5,5,5));
|
||||
QVERIFY(!defaultSphere.isNull());
|
||||
QVERIFY(defaultSphere.center() == Vector3D(5,5,5));
|
||||
QVERIFY(qFuzzyIsNull(defaultSphere.radius()));
|
||||
}
|
||||
|
||||
void nullSphereExpandToOrigin() {
|
||||
auto defaultSphere = Qt3DRender::Render::Sphere();
|
||||
defaultSphere.expandToContain(Vector3D(0,0,0));
|
||||
QVERIFY(!defaultSphere.isNull());
|
||||
QVERIFY(defaultSphere.center() == Vector3D(0,0,0));
|
||||
QVERIFY(qFuzzyIsNull(defaultSphere.radius()));
|
||||
}
|
||||
|
||||
void ritterSphereCubePoints() {
|
||||
QVector<Vector3D> cubePts={
|
||||
Vector3D(-0.5, -0.5, 0.5),
|
||||
Vector3D( 0.5, -0.5, -0.5),
|
||||
Vector3D(-0.5, 0.5, -0.5),
|
||||
Vector3D( 0.5, 0.5, -0.5),
|
||||
Vector3D(-0.5, -0.5, -0.5),
|
||||
Vector3D( 0.5, -0.5, 0.5),
|
||||
Vector3D(-0.5, 0.5, 0.5),
|
||||
Vector3D( 0.5, 0.5, 0.5)
|
||||
};
|
||||
auto ritterSphere=Qt3DRender::Render::Sphere::fromPoints(cubePts);
|
||||
QVERIFY(!ritterSphere.isNull());
|
||||
QVERIFY(qFuzzyIsNull(ritterSphere.center().x()));
|
||||
QVERIFY(qFuzzyIsNull(ritterSphere.center().y()));
|
||||
QVERIFY(qFuzzyIsNull(ritterSphere.center().z()));
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.radius(), static_cast<float>(qSqrt(3)/2)));
|
||||
}
|
||||
|
||||
void ritterSphereRandomPoints() {
|
||||
QVector<Vector3D> randomPts={
|
||||
Vector3D(-81, 55, 46),
|
||||
Vector3D(-91, -73, -42),
|
||||
Vector3D(-50, -76, -77),
|
||||
Vector3D(-40, 63, 58),
|
||||
Vector3D(-28, -2, -57),
|
||||
Vector3D(84, 17, 33),
|
||||
Vector3D(53, 11, -49),
|
||||
Vector3D(-7, -24, -86),
|
||||
Vector3D(-89, 6, 76),
|
||||
Vector3D(46, -18, -27)
|
||||
};
|
||||
|
||||
auto ritterSphere = Qt3DRender::Render::Sphere::fromPoints(randomPts);
|
||||
QVERIFY(!ritterSphere.isNull());
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.center().x(), 17.f));
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.center().y(), -29.5f));
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.center().z(), -22.0f));
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.radius(), 148.66152831179963f));
|
||||
}
|
||||
|
||||
void ritterSphereOnePoint() {
|
||||
QVector<Vector3D> singlePt={
|
||||
Vector3D(-0.5, -0.5, -0.5),
|
||||
};
|
||||
auto ritterSphere = Qt3DRender::Render::Sphere::fromPoints(singlePt);
|
||||
QVERIFY(!ritterSphere.isNull());
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.center().x(), -0.5f));
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.center().y(), -0.5f));
|
||||
QVERIFY(qFuzzyCompare(ritterSphere.center().z(), -0.5f));
|
||||
QVERIFY(qFuzzyIsNull(ritterSphere.radius()));
|
||||
}
|
||||
|
||||
void checkExtraGeometries_data()
|
||||
{
|
||||
QTest::addColumn<QString>("qmlFile");
|
||||
QTest::addColumn<QVector3D>("sphereCenter");
|
||||
QTest::addColumn<float>("sphereRadius");
|
||||
QTest::newRow("SphereMesh") << "qrc:/sphere.qml" << QVector3D(0.f, 0.f, 0.f) << 1.f;
|
||||
QTest::newRow("CubeMesh") << "qrc:/cube.qml" << QVector3D(0.0928356f, -0.212021f, -0.0467958f) << 1.07583f; // weird!
|
||||
QTest::newRow("CubeMesh") << "qrc:/cube.qml" << QVector3D(0.f, 0.f, 0.f) << static_cast<float>(qSqrt(3.)/2.); // not weird at all
|
||||
}
|
||||
|
||||
void checkExtraGeometries()
|
||||
|
|
@ -235,9 +372,10 @@ private Q_SLOTS:
|
|||
const auto boundingSphere = test->sceneRoot()->worldBoundingVolumeWithChildren();
|
||||
qDebug() << qmlFile << boundingSphere->radius() << boundingSphere->center();
|
||||
QCOMPARE(boundingSphere->radius(), sphereRadius);
|
||||
QVERIFY(qAbs(boundingSphere->center().x() - sphereCenter.x()) < 0.000001f); // qFuzzyCompare hates 0s
|
||||
QVERIFY(qAbs(boundingSphere->center().y() - sphereCenter.y()) < 0.000001f);
|
||||
QVERIFY(qAbs(boundingSphere->center().z() - sphereCenter.z()) < 0.000001f);
|
||||
|
||||
QVERIFY(qFuzzyIsNull(boundingSphere->center().x() - sphereCenter.x()));
|
||||
QVERIFY(qFuzzyIsNull(boundingSphere->center().y() - sphereCenter.y()));
|
||||
QVERIFY(qFuzzyIsNull(boundingSphere->center().z() - sphereCenter.z()));
|
||||
}
|
||||
|
||||
void checkCustomGeometry_data()
|
||||
|
|
@ -247,10 +385,10 @@ private Q_SLOTS:
|
|||
QTest::addColumn<QVector3D>("expectedCenter");
|
||||
QTest::addColumn<float>("expectedRadius");
|
||||
QTest::addColumn<bool>("withPrimitiveRestart");
|
||||
QTest::newRow("all") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f << false;
|
||||
QTest::newRow("all") << 0 << 0 << QVector3D(0.0f, 0.0f, -75.0f) << 25.03997f << false;
|
||||
QTest::newRow("first only") << 3 << 0 << QVector3D(0, 1, -100) << 1.0f << false;
|
||||
QTest::newRow("second only") << 3 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f << false;
|
||||
QTest::newRow("all with primitive restart") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f << true;
|
||||
QTest::newRow("all with primitive restart") << 0 << 0 << QVector3D(0.0f, 0.0f, -75.0f) << 25.03997f << true;
|
||||
QTest::newRow("first only with primitive restart") << 4 << 0 << QVector3D(0, 1, -100) << 1.0f << true;
|
||||
QTest::newRow("second only with primitive restart") << 4 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f << true;
|
||||
}
|
||||
|
|
@ -376,18 +514,17 @@ private Q_SLOTS:
|
|||
float radius = entityBackend->localBoundingVolume()->radius();
|
||||
qDebug() << radius << center;
|
||||
|
||||
// truncate and compare integers only
|
||||
QCOMPARE(int(radius), int(expectedRadius));
|
||||
QCOMPARE(int(center.x()), int(expectedCenter.x()));
|
||||
QCOMPARE(int(center.y()), int(expectedCenter.y()));
|
||||
QCOMPARE(int(center.z()), int(expectedCenter.z()));
|
||||
QCOMPARE(radius, expectedRadius);
|
||||
QCOMPARE(center.x(), expectedCenter.x());
|
||||
QCOMPARE(center.y(), expectedCenter.y());
|
||||
QCOMPARE(center.z(), expectedCenter.z());
|
||||
}
|
||||
|
||||
void checkCustomPackedGeometry()
|
||||
{
|
||||
int drawVertexCount = 6;
|
||||
QVector3D expectedCenter(-0.488892f, 0.0192147f, -75.4804f);
|
||||
float expectedRadius = 25.5442f;
|
||||
QVector3D expectedCenter(0.0f, 0.0f, -75.0f);
|
||||
float expectedRadius = 25.03997f;
|
||||
|
||||
// two triangles with different Z
|
||||
QByteArray vdata;
|
||||
|
|
@ -467,11 +604,10 @@ private Q_SLOTS:
|
|||
float radius = entityBackend->localBoundingVolume()->radius();
|
||||
qDebug() << radius << center;
|
||||
|
||||
// truncate and compare integers only
|
||||
QVERIFY(int(radius) == int(expectedRadius));
|
||||
QVERIFY(int(center.x()) == int(expectedCenter.x()));
|
||||
QVERIFY(int(center.y()) == int(expectedCenter.y()));
|
||||
QVERIFY(int(center.z()) == int(expectedCenter.z()));
|
||||
QCOMPARE(radius, expectedRadius);
|
||||
QCOMPARE(center.x(), expectedCenter.x());
|
||||
QCOMPARE(center.y(), expectedCenter.y());
|
||||
QCOMPARE(center.z(), expectedCenter.z());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@
|
|||
#include <QtTest/QTest>
|
||||
#include <Qt3DCore/qentity.h>
|
||||
#include <Qt3DCore/qtransform.h>
|
||||
#include <Qt3DRender/qgeometry.h>
|
||||
#include <Qt3DRender/qgeometryrenderer.h>
|
||||
#include <Qt3DRender/qattribute.h>
|
||||
#include <Qt3DRender/qbuffer.h>
|
||||
#include <Qt3DRender/private/nodemanagers_p.h>
|
||||
#include <Qt3DRender/private/managers_p.h>
|
||||
#include <Qt3DRender/private/entity_p.h>
|
||||
|
|
@ -43,6 +47,40 @@ namespace {
|
|||
Qt3DCore::QEntity *buildEntityAtDistance(float distance, Qt3DCore::QEntity *parent)
|
||||
{
|
||||
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(parent);
|
||||
|
||||
// create geometry with a valid bounding volume - a single point is sufficient
|
||||
auto geometry = new Qt3DRender::QGeometry;
|
||||
auto vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry);
|
||||
|
||||
auto positionAttribute = new Qt3DRender::QAttribute;
|
||||
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
|
||||
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
|
||||
positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
|
||||
positionAttribute->setVertexSize(3);
|
||||
positionAttribute->setByteStride(3 * sizeof(float));
|
||||
positionAttribute->setBuffer(vertexBuffer);
|
||||
|
||||
QByteArray vertexBufferData;
|
||||
vertexBufferData.resize(static_cast<int>(3 * sizeof(float)));
|
||||
|
||||
auto vertexArray = reinterpret_cast<float*>(vertexBufferData.data());
|
||||
|
||||
int i = 0;
|
||||
vertexArray[i++] = 0.0f;
|
||||
vertexArray[i++] = 0.0f;
|
||||
vertexArray[i++] = 0.0f;
|
||||
|
||||
vertexBuffer->setData(vertexBufferData);
|
||||
positionAttribute->setCount(1);
|
||||
|
||||
geometry->addAttribute(positionAttribute);
|
||||
|
||||
auto geometryRenderer = new Qt3DRender::QGeometryRenderer;
|
||||
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points);
|
||||
geometryRenderer->setGeometry(geometry);
|
||||
|
||||
entity->addComponent(geometryRenderer);
|
||||
|
||||
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(parent);
|
||||
const QVector3D t = QVector3D(1.0f, 0.0f, 0.0f) * distance;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue