From 05563678aae259909b89fe203e5095756d65bc91 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 6 Jun 2011 07:43:51 +0200 Subject: Fixed up command line options a bit --- src/declarative/scenegraph/qsgcontext.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp index e36d432e40..55942bebe4 100644 --- a/src/declarative/scenegraph/qsgcontext.cpp +++ b/src/declarative/scenegraph/qsgcontext.cpp @@ -281,10 +281,17 @@ QSGImageNode *QSGContext::createImageNode() */ QSGGlyphNode *QSGContext::createGlyphNode() { + // ### Do something with these before final release... + static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing")); + static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing")); + if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) { QSGGlyphNode *node = new QSGDistanceFieldGlyphNode; - if (qApp->arguments().contains(QLatin1String("--subpixel-antialiasing"))) + + if (doSubpixel) node->setPreferredAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing); + else if (doGray) + node->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing); return node; } else { return new QSGDefaultGlyphNode; @@ -299,8 +306,10 @@ QSGGlyphNode *QSGContext::createGlyphNode() */ QSGRenderer *QSGContext::createRenderer() { + // ### Do something with this before release... + static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back")); QMLRenderer *renderer = new QMLRenderer(this); - if (qApp->arguments().contains(QLatin1String("--opaque-front-to-back"))) { + if (doFrontToBack) { printf("QSGContext: Sorting opaque nodes front to back...\n"); renderer->setSortFrontToBackEnabled(true); } -- cgit v1.2.3 From 1a7f847db851d2dda706a7eb01333e13e3605528 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 6 Jun 2011 07:44:41 +0200 Subject: Don't fetch a context that is never to be used --- src/declarative/scenegraph/coreapi/qsgrenderer.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp index e267e3d8b8..dbf704b64a 100644 --- a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp @@ -206,10 +206,7 @@ void QSGRenderer::renderScene() class B : public Bindable { public: - B() : m_ctx(const_cast(QGLContext::currentContext())) { } void bind() const { QGLFramebufferObject::bindDefault(); } - private: - QGLContext *m_ctx; } b; renderScene(b); } -- cgit v1.2.3 From 33e349ac6bdab5c55b428c999ced253890c82305 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 6 Jun 2011 07:45:22 +0200 Subject: Removed warning --- src/declarative/items/qsgcanvasitem.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/declarative/items/qsgcanvasitem.cpp b/src/declarative/items/qsgcanvasitem.cpp index ba3c4baa11..fa99c9be6f 100644 --- a/src/declarative/items/qsgcanvasitem.cpp +++ b/src/declarative/items/qsgcanvasitem.cpp @@ -111,7 +111,7 @@ QSGContext2D* QSGCanvasItem::getContext(const QString &contextId) void QSGCanvasItem::requestPaint() { - Q_D(QSGCanvasItem); + // Q_D(QSGCanvasItem); //TODO:update(d->context->dirtyRect()); update(); } @@ -140,19 +140,19 @@ QString QSGCanvasItem::toDataURL(const QString& mimeType) const QString mime = mimeType; QString type; if (mimeType == QLatin1String("image/bmp")) - type = "BMP"; + type = QLatin1String("BMP"); else if (mimeType == QLatin1String("image/jpeg")) - type = "JPEG"; + type = QLatin1String("JPEG"); else if (mimeType == QLatin1String("image/x-portable-pixmap")) - type = "PPM"; + type = QLatin1String("PPM"); else if (mimeType == QLatin1String("image/tiff")) - type = "TIFF"; + type = QLatin1String("TIFF"); else if (mimeType == QLatin1String("image/xbm")) - type = "XBM"; + type = QLatin1String("XBM"); else if (mimeType == QLatin1String("image/xpm")) - type = "XPM"; + type = QLatin1String("XPM"); else { - type = "PNG"; + type = QLatin1String("PNG"); mime = QLatin1String("image/png"); } image.save(&buffer, type.toAscii()); -- cgit v1.2.3 From 6b0af9fe9fd9114bd579510010c09519928f91ce Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 6 Jun 2011 08:05:56 +0200 Subject: A better threaded renderer --- src/declarative/items/qsgcanvas.cpp | 681 +++++++++++++++++++++++++----------- src/declarative/items/qsgcanvas.h | 4 +- src/declarative/items/qsgcanvas_p.h | 91 +++-- 3 files changed, 548 insertions(+), 228 deletions(-) (limited to 'src') diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 16bd8ce44c..963c19f25d 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_NO_THREADED_RENDERER) DEFINE_BOOL_CONFIG_OPTION(qmlFixedAnimationStep, QML_FIXED_ANIMATION_STEP) +extern Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); + /* Focus behavior ============== @@ -79,10 +81,65 @@ a scope focused item that takes precedence over the item being added. Otherwise the focus of the added tree is used. In the case of of a tree of items being added to a canvas for the first time, which may have a conflicted focus state (two or more items in one scope having focus set), the same rule is applied item by item - -thus the first item that has focus will get it (assuming the scope doesn't already +thus the first item that has focus will get it (assuming the scope doesn't already have a scope focused item), and the other items will have their focus cleared. */ +/* + Threaded Rendering + ================== + + The threaded rendering uses a number of different variables to track potential + states used to handle resizing, initial paint, grabbing and driving animations + while ALWAYS keeping the GL context in the rendering thread and keeping the + overhead of normal one-shot paints and vblank driven animations at a minimum. + + Resize, initial show and grab suffer slightly in this model as they are locked + to the rendering in the rendering thread, but this is a necessary evil for + the system to work. + + Variables that are used: + + Private::animationRunning: This is true while the animations are running, and only + written to inside locks. + + RenderThread::isGuiBlocked: This is used to indicate that the GUI thread owns the + lock. This variable is an integer to allow for recursive calls to lockInGui() + without using a recursive mutex. See isGuiBlockPending. + + RenderThread::isPaintComplete: This variable is cleared when rendering starts and + set once rendering is complete. It is monitored in the paintEvent(), + resizeEvent() and grab() functions to force them to wait for rendering to + complete. + + RenderThread::isGuiBlockPending: This variable is set in the render thread just + before the sync event is sent to the GUI thread. It is used to avoid deadlocks + in the case where render thread waits while waiting for GUI to pick up the sync + event and GUI thread gets a resizeEvent, the initial paintEvent or a grab. + When this happens, we use the + exhaustSyncEvent() function to do the sync right there and mark the coming + sync event to be discarded. There can only ever be one sync incoming. + + RenderThread::isRenderBlock: This variable is true when animations are not + running and the render thread has gone to sleep, waiting for more to do. + + RenderThread::isExternalUpdatePending: This variable is set to false during + the sync phase in the GUI thread and to true in maybeUpdate(). It is an + indication to the render thread that another render pass needs to take + place, rather than the render thread going to sleep after completing its swap. + + RenderThread::doGrab: This variable is set by the grab() function and + tells the renderer to do a grab after rendering is complete and before + swapping happens. + + RenderThread::shouldExit: This variable is used to determine if the render + thread should do a nother pass. It is typically set as a result of show() + and unset as a result of hide() or during shutdown() + + RenderThread::hasExited: Used by the GUI thread to synchronize the shutdown + after shouldExit has been set to true. + */ + // #define FOCUS_DEBUG // #define MOUSE_DEBUG // #define TOUCH_DEBUG @@ -106,41 +163,6 @@ QSGRootItem::QSGRootItem() { } -void QSGCanvasPrivate::stopRenderingThread() -{ - if (thread->isRunning()) { - mutex.lock(); - exitThread = true; - wait.wakeOne(); - wait.wait(&mutex); - exitThread = false; - mutex.unlock(); - thread->wait(); - } -} - -void QSGCanvasPrivate::_q_animationStarted() -{ -#ifdef THREAD_DEBUG - qWarning("AnimationDriver: Main Thread: started"); -#endif - mutex.lock(); - animationRunning = true; - if (idle) - wait.wakeOne(); - mutex.unlock(); -} - -void QSGCanvasPrivate::_q_animationStopped() -{ -#ifdef THREAD_DEBUG - qWarning("AnimationDriver: Main Thread: stopped"); -#endif - mutex.lock(); - animationRunning = false; - mutex.unlock(); -} - void QSGCanvas::paintEvent(QPaintEvent *) { Q_D(QSGCanvas); @@ -180,7 +202,9 @@ void QSGCanvas::paintEvent(QPaintEvent *) int syncTime = frameTimer.elapsed(); #endif - d->renderSceneGraph(); + d->renderSceneGraph(d->widgetSize); + + swapBuffers(); #ifdef FRAME_TIMING printf("FrameTimes, last=%d, animations=%d, polish=%d, makeCurrent=%d, sync=%d, sgrender=%d, readback=%d, total=%d\n", @@ -198,6 +222,11 @@ void QSGCanvas::paintEvent(QPaintEvent *) if (d->animationDriver->isRunning()) update(); + } else { + if (isUpdatesEnabled()) { + d->thread->paint(); + setUpdatesEnabled(false); + } } } @@ -205,10 +234,7 @@ void QSGCanvas::resizeEvent(QResizeEvent *e) { Q_D(QSGCanvas); if (d->threadedRendering) { - d->mutex.lock(); - QGLWidget::resizeEvent(e); - d->widgetSize = e->size(); - d->mutex.unlock(); + d->thread->resize(e->size()); } else { d->widgetSize = e->size(); d->viewportSize = d->widgetSize; @@ -223,18 +249,14 @@ void QSGCanvas::showEvent(QShowEvent *e) QGLWidget::showEvent(e); if (d->threadedRendering) { - d->contextInThread = true; - doneCurrent(); if (!d->animationDriver) { d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(_q_animationStarted()), Qt::DirectConnection); - connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(_q_animationStopped()), Qt::DirectConnection); + connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection); + connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection); } d->animationDriver->install(); - d->mutex.lock(); - d->thread->start(); - d->wait.wait(&d->mutex); - d->mutex.unlock(); + d->thread->startRenderThread(); + setUpdatesEnabled(true); } else { makeCurrent(); @@ -252,8 +274,9 @@ void QSGCanvas::hideEvent(QHideEvent *e) { Q_D(QSGCanvas); - if (d->threadedRendering) - d->stopRenderingThread(); + if (d->threadedRendering) { + d->thread->stopRenderThread(); + } d->animationDriver->uninstall(); @@ -312,18 +335,14 @@ void QSGCanvasPrivate::polishItems() void QSGCanvasPrivate::syncSceneGraph() { - inSync = true; updateDirtyNodes(); - inSync = false; } -void QSGCanvasPrivate::renderSceneGraph() +void QSGCanvasPrivate::renderSceneGraph(const QSize &size) { - QGLContext *glctx = const_cast(QGLContext::currentContext()); - - context->renderer()->setDeviceRect(QRect(QPoint(0, 0), viewportSize)); - context->renderer()->setViewportRect(QRect(QPoint(0, 0), viewportSize)); + context->renderer()->setDeviceRect(QRect(QPoint(0, 0), size)); + context->renderer()->setViewportRect(QRect(QPoint(0, 0), size)); context->renderer()->setProjectMatrixToDeviceRect(); context->renderNextFrame(); @@ -332,127 +351,22 @@ void QSGCanvasPrivate::renderSceneGraph() sceneGraphRenderTime = frameTimer.elapsed(); #endif - #ifdef FRAME_TIMING // int pixel; // glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); readbackTime = frameTimer.elapsed(); #endif - - glctx->swapBuffers(); } +// ### Do we need this? void QSGCanvas::sceneGraphChanged() { - Q_D(QSGCanvas); - d->needsRepaint = true; +// Q_D(QSGCanvas); +// d->needsRepaint = true; } -void QSGCanvasPrivate::runThread() -{ -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render thread running"); -#endif - Q_Q(QSGCanvas); - - printf("QSGCanvas::runThread(), rendering in a thread...\n"); - - q->makeCurrent(); - initializeSceneGraph(); - - QObject::connect(context->renderer(), SIGNAL(sceneGraphChanged()), - q, SLOT(sceneGraphChanged()), - Qt::DirectConnection); - - mutex.lock(); - wait.wakeOne(); // Wake the main thread waiting for us to start - - while (true) { - QSize s; - s = widgetSize; - - if (exitThread) - break; - - if (s != viewportSize) { - glViewport(0, 0, s.width(), s.height()); - viewportSize = s; - } - -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: Waiting for main thread to stop"); -#endif - QCoreApplication::postEvent(q, new QEvent(QEvent::User)); - wait.wait(&mutex); - - if (exitThread) { -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: Shutting down..."); -#endif - break; - } - -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: Main thread has stopped, syncing scene"); -#endif - - // Do processing while main thread is frozen - syncSceneGraph(); - -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: Resuming main thread"); -#endif - - // Read animationRunning while inside the locked section - bool continous = animationRunning; - - wait.wakeOne(); - mutex.unlock(); - - bool enterIdle = false; - if (needsRepaint) { -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: rendering scene"); -#endif - renderSceneGraph(); - needsRepaint = false; - } else if (continous) { -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: waiting a while..."); -#endif - MyThread::doWait(); - } else { - enterIdle = true; - } - - mutex.lock(); - - if (enterIdle) { -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: Nothing has changed, going idle..."); -#endif - idle = true; - wait.wait(&mutex); - idle = false; -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: waking up from idle"); -#endif - } - - } - - -#ifdef THREAD_DEBUG - qWarning("QSGRenderer: Render Thread: shutting down, waking up main thread"); -#endif - wait.wakeOne(); - mutex.unlock(); - - q->doneCurrent(); -} - QSGCanvasPrivate::QSGCanvasPrivate() : rootItem(0) , activeFocusItem(0) @@ -460,15 +374,10 @@ QSGCanvasPrivate::QSGCanvasPrivate() , hoverItem(0) , dirtyItemList(0) , context(0) - , contextInThread(false) , threadedRendering(false) - , exitThread(false) , animationRunning(false) - , idle(false) - , needsRepaint(true) , renderThreadAwakened(false) - , inSync(false) - , thread(new MyThread(this)) + , thread(0) , animationDriver(0) { threadedRendering = !qmlNoThreadedRenderer(); @@ -495,6 +404,13 @@ void QSGCanvasPrivate::init(QSGCanvas *c) rootItemPrivate->flags |= QSGItem::ItemIsFocusScope; context = QSGContext::createDefaultContext(); + + if (threadedRendering) { + thread = new QSGCanvasRenderThread; + thread->renderer = q; + thread->d = this; + } + } void QSGCanvasPrivate::sceneMouseEventForTransform(QGraphicsSceneMouseEvent &sceneEvent, @@ -945,9 +861,10 @@ QSGCanvas::~QSGCanvas() { Q_D(QSGCanvas); - if (d->threadedRendering) { - d->stopRenderingThread(); + if (d->threadedRendering && d->thread->isRunning()) { + d->thread->stopRenderThread(); delete d->thread; + d->thread = 0; } // ### should we change ~QSGItem to handle this better? @@ -1022,31 +939,24 @@ bool QSGCanvas::event(QEvent *e) Q_D(QSGCanvas); if (e->type() == QEvent::User) { - Q_ASSERT(d->threadedRendering); + if (!d->thread->syncAlreadyHappened) + d->thread->sync(false); + + d->thread->syncAlreadyHappened = false; - d->mutex.lock(); + if (d->animationRunning) { #ifdef THREAD_DEBUG - qWarning("QSGRenderer: Main Thread: Stopped"); + qDebug("GUI: Advancing animations...\n"); #endif - d->polishItems(); - - d->renderThreadAwakened = false; - - d->wait.wakeOne(); + d->animationDriver->advance(); - // The thread is exited when the widget has been hidden. We then need to - // skip the waiting, otherwise we would be waiting for a wakeup that never - // comes. - if (d->thread->isRunning()) - d->wait.wait(&d->mutex); #ifdef THREAD_DEBUG - qWarning("QSGRenderer: Main Thread: Resumed"); + qDebug("GUI: Animations advanced...\n"); #endif - d->mutex.unlock(); + } - if (d->animationRunning) - d->animationDriver->advance(); + return true; } switch (e->type()) { @@ -1881,24 +1791,17 @@ void QSGCanvas::maybeUpdate() { Q_D(QSGCanvas); - if (d->threadedRendering) { + if (d->threadedRendering && d->thread && d->thread->isRunning()) { if (!d->renderThreadAwakened) { - d->renderThreadAwakened = true; - bool locked = d->mutex.tryLock(); - if (d->idle && locked) { #ifdef THREAD_DEBUG - qWarning("QSGRenderer: now maybe I should update..."); + printf("GUI: doing update...\n"); #endif - d->wait.wakeOne(); - } else if (d->inSync) { - // If we are in sync (on scene graph thread) someone has explicitely asked us - // to redraw, hence we tell the render loop to not go idle. - // The primary usecase for this is updatePaintNode() calling update() without - // changing the scene graph. - d->needsRepaint = true; - } - if (locked) - d->mutex.unlock(); + d->renderThreadAwakened = true; + d->thread->lockInGui(); + d->thread->isExternalUpdatePending = true; + if (d->thread->isRenderBlocked) + d->thread->wake(); + d->thread->unlockInGui(); } } else if (!d->animationDriver || !d->animationDriver->isRunning()) { update(); @@ -1929,6 +1832,372 @@ QSGEngine *QSGCanvas::sceneGraphEngine() const return 0; } + +/*! + Grabs the contents of the framebuffer and returns it as an image. + + This function might not work if the view is not visible. + + \warning Calling this function will cause performance problems. + */ +QImage QSGCanvas::grabFrameBuffer() +{ + Q_D(QSGCanvas); + if (d->threadedRendering) + return d->thread ? d->thread->grab() : QImage(); + else { + // render a fresh copy of the scene graph in the current thread. + d->renderSceneGraph(size()); + return QGLWidget::grabFrameBuffer(false); + } +} + + +void QSGCanvasRenderThread::run() +{ + qDebug("QML Rendering Thread Started"); + + renderer->makeCurrent(); + + if (!d->context->isReady()) + d->initializeSceneGraph(); + + + while (!shouldExit) { + lock(); + + bool sizeChanged = false; + isExternalUpdatePending = false; + + if (renderedSize != windowSize) { +#ifdef THREAD_DEBUG + printf(" RenderThread: window has changed size...\n"); +#endif + glViewport(0, 0, windowSize.width(), windowSize.height()); + sizeChanged = true; + } + +#ifdef THREAD_DEBUG + printf(" RenderThread: preparing to sync...\n"); +#endif + + if (!isGuiBlocked) { + isGuiBlockPending = true; + +#ifdef THREAD_DEBUG + printf(" RenderThread: aquired sync lock...\n"); +#endif + QApplication::postEvent(renderer, new QEvent(QEvent::User)); +#ifdef THREAD_DEBUG + printf(" RenderThread: going to sleep...\n"); +#endif + wait(); + + isGuiBlockPending = false; + } + +#ifdef THREAD_DEBUG + printf(" RenderThread: Doing locked sync\n"); +#endif + d->syncSceneGraph(); + + // Wake GUI after sync to let it continue animating and event processing. + wake(); + unlock(); +#ifdef THREAD_DEBUG + printf(" RenderThread: sync done\n"); +#endif + + + +#ifdef THREAD_DEBUG + printf(" RenderThread: rendering... %d x %d\n", windowSize.width(), windowSize.height()); +#endif + + d->renderSceneGraph(windowSize); + + // The content of the target buffer is undefined after swap() so grab needs + // to happen before swap(); + if (doGrab) { +#ifdef THREAD_DEBUG + printf(" RenderThread: doing a grab...\n"); +#endif + grabContent = qt_gl_read_framebuffer(windowSize, false, false); + doGrab = false; + } + +#ifdef THREAD_DEBUG + printf(" RenderThread: wait for swap...\n"); +#endif + + renderer->swapBuffers(); +#ifdef THREAD_DEBUG + printf(" RenderThread: swap complete...\n"); +#endif + + lock(); + isPaintCompleted = true; + if (sizeChanged) + renderedSize = windowSize; + + // Wake the GUI thread now that rendering is complete, to signal that painting + // is done, resizing is done or grabbing is completed. For grabbing, we're + // signalling this much later than needed (we could have done it before swap) + // but we don't want to lock an extra time. + wake(); + + if (!d->animationRunning && !isExternalUpdatePending) { +#ifdef THREAD_DEBUG + printf(" RenderThread: nothing to do, going to sleep...\n"); +#endif + isRenderBlocked = true; + wait(); + isRenderBlocked = false; + } + + unlock(); + } + +#ifdef THREAD_DEBUG + printf(" RenderThread: exited... Good Night!\n"); +#endif + + renderer->doneCurrent(); + + lock(); + hasExited = true; +#ifdef THREAD_DEBUG + printf(" RenderThread: waking GUI for final sleep..\n"); +#endif + wake(); + unlock(); +} + + + +void QSGCanvasRenderThread::exhaustSyncEvent() +{ + if (isGuiBlockPending) { + sync(true); + syncAlreadyHappened = true; + } +} + + + +void QSGCanvasRenderThread::sync(bool guiAlreadyLocked) +{ +#ifdef THREAD_DEBUG + printf("GUI: sync - %s\n", guiAlreadyLocked ? "outside event" : "inside event"); +#endif + Q_ASSERT(d->threadedRendering); + + if (!guiAlreadyLocked) + d->thread->lockInGui(); + + d->renderThreadAwakened = false; + + d->polishItems(); + + d->thread->wake(); + d->thread->wait(); + + if (!guiAlreadyLocked) + d->thread->unlockInGui(); +} + + + + +/*! + Acquires the mutex for the GUI thread. The function uses the isGuiBlocked + variable to keep track of how many recursion levels the gui is locket with. + We only actually acquire the mutex for the first level to avoid deadlocking + ourselves. + */ + +void QSGCanvasRenderThread::lockInGui() +{ + // We must avoid recursive locking in the GUI thread, hence we + // only lock when we are the first one to try to block. + if (!isGuiBlocked) + lock(); + + isGuiBlocked++; + +#ifdef THREAD_DEBUG + printf("GUI: aquired lock... %d\n", isGuiBlocked); +#endif +} + + + +void QSGCanvasRenderThread::unlockInGui() +{ +#ifdef THREAD_DEBUG + printf("GUI: releasing lock... %d\n", isGuiBlocked); +#endif + --isGuiBlocked; + if (!isGuiBlocked) + unlock(); +} + + + + +void QSGCanvasRenderThread::animationStarted() +{ +#ifdef THREAD_DEBUG + printf("GUI: animationStarted()\n"); +#endif + + lockInGui(); + + d->animationRunning = true; + + if (isRenderBlocked) + wake(); + + unlockInGui(); +} + + + +void QSGCanvasRenderThread::animationStopped() +{ +#ifdef THREAD_DEBUG + printf("GUI: animationStopped()...\n"); +#endif + + lockInGui(); + d->animationRunning = false; + unlockInGui(); +} + + +void QSGCanvasRenderThread::paint() +{ +#ifdef THREAD_DEBUG + printf("GUI: paint called..\n"); +#endif + + lockInGui(); + exhaustSyncEvent(); + + isPaintCompleted = false; + while (isRunning() && !isPaintCompleted) + wait(); + unlockInGui(); + + // paint is only called for the inital show. After that we will do all + // drawing ourselves, so block future updates.. + renderer->setUpdatesEnabled(false); +} + + + +void QSGCanvasRenderThread::resize(const QSize &size) +{ +#ifdef THREAD_DEBUG + printf("GUI: Resize Event: %dx%d\n", size.width(), size.height()); +#endif + + if (!isRunning()) { + windowSize = size; + return; + } + + lockInGui(); + exhaustSyncEvent(); + + windowSize = size; + + while (isRunning() && renderedSize != windowSize) { + if (isRenderBlocked) + wake(); + wait(); + } + unlockInGui(); +} + + + +void QSGCanvasRenderThread::startRenderThread() +{ +#ifdef THREAD_DEBUG + printf("GUI: Starting Render Thread\n"); +#endif + hasExited = false; + shouldExit = false; + isGuiBlocked = 0; + isGuiBlockPending = false; + + renderer->doneCurrent(); + start(); +} + + + +void QSGCanvasRenderThread::stopRenderThread() +{ +#ifdef THREAD_DEBUG + printf("GUI: stopping render thread\n"); +#endif + + lockInGui(); + exhaustSyncEvent(); + shouldExit = true; + + if (isRenderBlocked) { +#ifdef THREAD_DEBUG + printf("GUI: waking up render thread\n"); +#endif + wake(); + } + + while (!hasExited) { +#ifdef THREAD_DEBUG + printf("GUI: waiting for render thread to have exited..\n"); +#endif + wait(); + } + + unlockInGui(); +} + + + +QImage QSGCanvasRenderThread::grab() +{ + if (!isRunning()) + return QImage(); + +#ifdef THREAD_DEBUG + printf("GUI: doing a pixelwise grab..\n"); +#endif + + lockInGui(); + exhaustSyncEvent(); + + doGrab = true; + isPaintCompleted = false; + while (isRunning() && !isPaintCompleted) { + // If we're in an animation we don't need to wake as we know another frame + // will be pending anyway. + if (!d->animationRunning) + wake(); + wait(); + } + + QImage grabbed = grabContent; + grabContent = QImage(); + + unlockInGui(); + + return grabbed; +} + + #include "moc_qsgcanvas.cpp" QT_END_NAMESPACE diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h index 6707d24b30..d0d0c79d5e 100644 --- a/src/declarative/items/qsgcanvas.h +++ b/src/declarative/items/qsgcanvas.h @@ -75,6 +75,8 @@ public: QSGEngine *sceneGraphEngine() const; + QImage grabFrameBuffer(); + Q_SIGNALS: void sceneGraphInitialized(); @@ -109,8 +111,6 @@ private Q_SLOTS: private: Q_DISABLE_COPY(QSGCanvas) - Q_PRIVATE_SLOT(d_func(), void _q_animationStarted()) - Q_PRIVATE_SLOT(d_func(), void _q_animationStopped()) }; QT_END_NAMESPACE diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h index 6b8034f922..9ea11f5892 100644 --- a/src/declarative/items/qsgcanvas_p.h +++ b/src/declarative/items/qsgcanvas_p.h @@ -78,6 +78,8 @@ public: class QSGCanvasPrivate; class QTouchEvent; +class QSGCanvasRenderThread; + class QSGCanvasPrivate : public QGLWidgetPrivate { public: @@ -115,8 +117,6 @@ public: void sendHoverEvent(QEvent::Type, QSGItem *, QGraphicsSceneHoverEvent *); void clearHover(); - void stopRenderingThread(); - QDeclarativeGuard hoverItem; enum FocusOption { DontChangeFocusProperty = 0x01, @@ -135,11 +135,7 @@ public: void initializeSceneGraph(); void polishItems(); void syncSceneGraph(); - void renderSceneGraph(); - void runThread(); - - void _q_animationStarted(); - void _q_animationStopped(); + void renderSceneGraph(const QSize &size); QSGItem::UpdatePaintNodeData updatePaintNodeData; @@ -158,22 +154,10 @@ public: uint contextInThread : 1; uint threadedRendering : 1; - uint exitThread : 1; uint animationRunning: 1; - uint idle : 1; // Set to true when render thread sees no change and enters a wait() - uint needsRepaint : 1; // Set by callback from render if scene needs repainting. uint renderThreadAwakened : 1; - uint inSync: 1; - struct MyThread : public QThread { - MyThread(QSGCanvasPrivate *r) : renderer(r) {} - virtual void run() { renderer->runThread(); } - static void doWait() { QThread::msleep(16); } - QSGCanvasPrivate *renderer; - }; - MyThread *thread; - QMutex mutex; - QWaitCondition wait; + QSGCanvasRenderThread *thread; QSize widgetSize; QSize viewportSize; @@ -182,6 +166,73 @@ public: QHash itemForTouchPointId; }; + + +class QSGCanvasRenderThread : public QThread +{ + Q_OBJECT +public: + QSGCanvasRenderThread() + : mutex(QMutex::NonRecursive) + , isGuiBlocked(0) + , isPaintCompleted(false) + , isGuiBlockPending(false) + , isRenderBlocked(false) + , isExternalUpdatePending(false) + , syncAlreadyHappened(false) + , doGrab(false) + , shouldExit(false) + , hasExited(false) + {} + + inline void lock() { mutex.lock(); } + inline void unlock() { mutex.unlock(); } + inline void wait() { condition.wait(&mutex); } + inline void wake() { condition.wakeOne(); } + + void lockInGui(); + void unlockInGui(); + + void paint(); + void resize(const QSize &size); + void startRenderThread(); + void stopRenderThread(); + void exhaustSyncEvent(); + void sync(bool guiAlreadyLocked); + + QImage grab(); + +public slots: + void animationStarted(); + void animationStopped(); + +public: + QMutex mutex; + QWaitCondition condition; + + QSize windowSize; + QSize renderedSize; + + QSGCanvas *renderer; + QSGCanvasPrivate *d; + + int isGuiBlocked; + uint isPaintCompleted : 1; + uint isGuiBlockPending : 1; + uint isRenderBlocked : 1; + uint isExternalUpdatePending : 1; + uint syncAlreadyHappened : 1; + + uint doGrab : 1; + uint shouldExit : 1; + uint hasExited : 1; + + QImage grabContent; + + void run(); +}; + + Q_DECLARE_OPERATORS_FOR_FLAGS(QSGCanvasPrivate::FocusOptions) QT_END_NAMESPACE -- cgit v1.2.3 From 70910dfb354a0a12ae0e446982071e54051ca83d Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 7 Jun 2011 11:34:57 +1000 Subject: Fix docs on caching for images loaded by image providers Also add docs for 'source' and 'asynchronous' properties for AnimatedImage. Task-number: QTBUG-19504 Change-Id: Iec72dc7630308a94c37d00c6b008b5949c6fccd4 Reviewed-by: Martin Jones (cherry picked from commit 7602be09663d37f01cfd640a7f1be959ce4317b7) --- .../graphicsitems/qdeclarativeanimatedimage.cpp | 26 ++++++++++++++++++++++ src/declarative/qml/qdeclarativeengine.cpp | 3 --- src/declarative/qml/qdeclarativeimageprovider.cpp | 14 +++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp index b7fcbb546e..8787a5ed68 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp @@ -86,6 +86,32 @@ QT_BEGIN_NAMESPACE \sa BorderImage, Image */ +/*! + \qmlproperty url AnimatedImage::source + + This property holds the URL that refers to the source image. + + AnimatedImage can handle any image format supported by Qt, loaded from any + URL scheme supported by Qt. + + \sa QDeclarativeImageProvider +*/ + +/*! + \qmlproperty bool AnimatedImage::asynchronous + + Specifies that images on the local filesystem should be loaded + asynchronously in a separate thread. The default value is + false, causing the user interface thread to block while the + image is loaded. Setting \a asynchronous to true is useful where + maintaining a responsive user interface is more desirable + than having images immediately visible. + + Note that this property is only valid for images read from the + local filesystem. Images loaded via a network resource (e.g. HTTP) + are always loaded asynchonously. +*/ + /*! \qmlproperty bool AnimatedImage::cache \since Quick 1.1 diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index ecd6a2bd7a..4f9e6e3af8 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -796,9 +796,6 @@ QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const All required image providers should be added to the engine before any QML sources files are loaded. - Note that images loaded from a QDeclarativeImageProvider are cached - by QPixmapCache, similar to any image loaded by QML. - \sa removeImageProvider() */ void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider) diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index 50a3aad733..56e04c963f 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -136,7 +136,8 @@ public: Image providers that support QImage loading automatically include support for asychronous loading of images. To enable asynchronous loading for an - \l Image source, set \l Image::asynchronous to \c true. When this is enabled, + image source, set the \c asynchronous property to \c true for the relevant + \l Image, \l BorderImage or \l AnimatedImage object. When this is enabled, the image request to the provider is run in a low priority thread, allowing image loading to be executed in the background, and reducing the performance impact on the user interface. @@ -147,6 +148,17 @@ public: \c true, the value is ignored and the image is loaded synchronously. + + \section2 Image caching + + Images returned by a QDeclarativeImageProvider are automatically cached, + similar to any image loaded by the QML engine. When an image with a + "image://" prefix is loaded from cache, requestImage() and requestPixmap() + will not be called for the relevant image provider. If an image should always + be fetched from the image provider, and should not be cached at all, set the + \c cache property to \c false for the relevant \l Image, \l BorderImage or + \l AnimatedImage object. + \sa QDeclarativeEngine::addImageProvider() */ -- cgit v1.2.3 From 21d0c6ef9a7df3e5fa69ff344e9dee2d2159c43c Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 7 Jun 2011 15:12:53 +1000 Subject: Immense Particles Refactor Part A Qt.labs.particles 2.0 moved to QtQuick.Particles 2.0. All C++ classes changed names, some renaming of QML types. Also adds CustomParticle. --- src/declarative/declarative.pro | 1 + src/declarative/items/items.pri | 6 + src/declarative/items/qsgitemsmodule.cpp | 4 + src/declarative/items/qsgsprite.cpp | 57 ++ src/declarative/items/qsgsprite_p.h | 231 +++++ src/declarative/items/qsgspriteengine.cpp | 437 +++++++++ src/declarative/items/qsgspriteengine_p.h | 161 ++++ src/declarative/items/qsgspriteimage.cpp | 353 ++++++++ src/declarative/items/qsgspriteimage_p.h | 114 +++ .../particles/defaultshaders/ctfragment.shader | 11 + .../particles/defaultshaders/ctvertex.shader | 38 + .../particles/defaultshaders/defaultFadeInOut.png | Bin 0 -> 286 bytes .../defaultshaders/deformablefragment.shader | 8 + .../defaultshaders/deformablevertex.shader | 57 ++ .../particles/defaultshaders/identitytable.png | Bin 0 -> 90 bytes .../particles/defaultshaders/simplefragment.shader | 8 + .../particles/defaultshaders/simplevertex.shader | 36 + .../particles/defaultshaders/spritefragment.shader | 10 + .../defaultshaders/spriteimagefragment.shader | 9 + .../defaultshaders/spriteimagevertex.shader | 52 ++ .../particles/defaultshaders/spritevertex.shader | 77 ++ .../particles/defaultshaders/superfragment.shader | 11 + .../particles/defaultshaders/supervertex.shader | 57 ++ .../particles/defaultshaders/trailsfragment.shader | 8 + .../particles/defaultshaders/trailsvertex.shader | 37 + .../particles/defaultshaders/ultrafragment.shader | 16 + .../particles/defaultshaders/ultravertex.shader | 94 ++ src/declarative/particles/particles.pri | 60 ++ src/declarative/particles/particles.qrc | 22 + src/declarative/particles/qsgangleddirection.cpp | 66 ++ src/declarative/particles/qsgangleddirection_p.h | 133 +++ src/declarative/particles/qsgcustomparticle.cpp | 581 ++++++++++++ src/declarative/particles/qsgcustomparticle_p.h | 114 +++ src/declarative/particles/qsgellipseextruder.cpp | 64 ++ src/declarative/particles/qsgellipseextruder_p.h | 86 ++ src/declarative/particles/qsgemitter.cpp | 200 +++++ src/declarative/particles/qsgemitter_p.h | 104 +++ src/declarative/particles/qsgfollowemitter.cpp | 195 ++++ src/declarative/particles/qsgfollowemitter_p.h | 168 ++++ src/declarative/particles/qsgfriction.cpp | 59 ++ src/declarative/particles/qsgfriction_p.h | 86 ++ src/declarative/particles/qsggravity.cpp | 77 ++ src/declarative/particles/qsggravity_p.h | 106 +++ src/declarative/particles/qsgimageparticle.cpp | 993 +++++++++++++++++++++ src/declarative/particles/qsgimageparticle_p.h | 352 ++++++++ src/declarative/particles/qsgitemparticle.cpp | 205 +++++ src/declarative/particles/qsgitemparticle_p.h | 125 +++ src/declarative/particles/qsgkill.cpp | 59 ++ src/declarative/particles/qsgkill_p.h | 68 ++ src/declarative/particles/qsglineextruder.cpp | 66 ++ src/declarative/particles/qsglineextruder_p.h | 77 ++ src/declarative/particles/qsgmaskextruder.cpp | 91 ++ src/declarative/particles/qsgmaskextruder_p.h | 97 ++ src/declarative/particles/qsgmodelparticle.cpp | 274 ++++++ src/declarative/particles/qsgmodelparticle_p.h | 143 +++ src/declarative/particles/qsgparticleaffector.cpp | 121 +++ src/declarative/particles/qsgparticleaffector_p.h | 193 ++++ src/declarative/particles/qsgparticleemitter.cpp | 148 +++ src/declarative/particles/qsgparticleemitter_p.h | 304 +++++++ src/declarative/particles/qsgparticleextruder.cpp | 78 ++ src/declarative/particles/qsgparticleextruder_p.h | 90 ++ src/declarative/particles/qsgparticlepainter.cpp | 135 +++ src/declarative/particles/qsgparticlepainter_p.h | 136 +++ src/declarative/particles/qsgparticlesmodule.cpp | 111 +++ src/declarative/particles/qsgparticlesmodule_p.h | 63 ++ src/declarative/particles/qsgparticlesystem.cpp | 396 ++++++++ src/declarative/particles/qsgparticlesystem_p.h | 228 +++++ src/declarative/particles/qsgpointattractor.cpp | 66 ++ src/declarative/particles/qsgpointattractor_p.h | 120 +++ src/declarative/particles/qsgpointdirection.cpp | 62 ++ src/declarative/particles/qsgpointdirection_p.h | 135 +++ src/declarative/particles/qsgspritegoal.cpp | 100 +++ src/declarative/particles/qsgspritegoal_p.h | 104 +++ .../particles/qsgstochasticdirection.cpp | 56 ++ .../particles/qsgstochasticdirection_p.h | 72 ++ src/declarative/particles/qsgtargeteddirection.cpp | 93 ++ src/declarative/particles/qsgtargeteddirection_p.h | 190 ++++ src/declarative/particles/qsgturbulence.cpp | 159 ++++ src/declarative/particles/qsgturbulence_p.h | 125 +++ src/declarative/particles/qsgwander.cpp | 110 +++ src/declarative/particles/qsgwander_p.h | 134 +++ src/declarative/qml/qdeclarativeengine.cpp | 2 + src/imports/particles/angledvector.cpp | 66 -- src/imports/particles/angledvector.h | 133 --- src/imports/particles/attractoraffector.cpp | 66 -- src/imports/particles/attractoraffector.h | 120 --- src/imports/particles/burstemitter.cpp | 55 -- src/imports/particles/burstemitter.h | 67 -- src/imports/particles/coloredparticle.cpp | 540 ----------- src/imports/particles/coloredparticle.h | 254 ------ src/imports/particles/dataparticle.cpp | 274 ------ src/imports/particles/dataparticle.h | 143 --- src/imports/particles/deformableparticle.cpp | 438 --------- src/imports/particles/deformableparticle.h | 235 ----- src/imports/particles/directedvector.cpp | 93 -- src/imports/particles/directedvector.h | 190 ---- src/imports/particles/driftaffector.cpp | 67 -- src/imports/particles/driftaffector.h | 104 --- src/imports/particles/ellipseextruder.cpp | 64 -- src/imports/particles/ellipseextruder.h | 86 -- src/imports/particles/eternalaffector.cpp | 60 -- src/imports/particles/eternalaffector.h | 88 -- src/imports/particles/followemitter.cpp | 195 ---- src/imports/particles/followemitter.h | 168 ---- src/imports/particles/frictionaffector.cpp | 59 -- src/imports/particles/frictionaffector.h | 86 -- .../particles/gravitationalsingularityaffector.cpp | 179 ---- .../particles/gravitationalsingularityaffector.h | 121 --- src/imports/particles/gravityaffector.cpp | 77 -- src/imports/particles/gravityaffector.h | 106 --- src/imports/particles/itemparticle.cpp | 205 ----- src/imports/particles/itemparticle.h | 125 --- src/imports/particles/killaffector.cpp | 59 -- src/imports/particles/killaffector.h | 68 -- src/imports/particles/lineextruder.cpp | 66 -- src/imports/particles/lineextruder.h | 77 -- src/imports/particles/main.cpp | 160 ---- src/imports/particles/maskextruder.cpp | 91 -- src/imports/particles/maskextruder.h | 97 -- src/imports/particles/meanderaffector.cpp | 65 -- src/imports/particles/meanderaffector.h | 103 --- src/imports/particles/particle.cpp | 135 --- src/imports/particles/particle.h | 136 --- src/imports/particles/particleaffector.cpp | 121 --- src/imports/particles/particleaffector.h | 193 ---- src/imports/particles/particleemitter.cpp | 148 --- src/imports/particles/particleemitter.h | 304 ------- src/imports/particles/particleextruder.cpp | 78 -- src/imports/particles/particleextruder.h | 90 -- src/imports/particles/particles.cpp | 69 ++ src/imports/particles/particles.pro | 109 +-- src/imports/particles/particlesystem.cpp | 396 -------- src/imports/particles/particlesystem.h | 228 ----- src/imports/particles/pictureaffector.cpp | 118 --- src/imports/particles/pictureaffector.h | 99 -- src/imports/particles/pluginmain.h | 65 -- src/imports/particles/pointvector.cpp | 62 -- src/imports/particles/pointvector.h | 135 --- src/imports/particles/resetaffector.cpp | 78 -- src/imports/particles/resetaffector.h | 75 -- src/imports/particles/resources/ctfragment.shader | 11 - src/imports/particles/resources/ctvertex.shader | 38 - .../particles/resources/defaultFadeInOut.png | Bin 286 -> 0 bytes .../particles/resources/deformablefragment.shader | 8 - .../particles/resources/deformablevertex.shader | 57 -- src/imports/particles/resources/identitytable.png | Bin 90 -> 0 bytes .../particles/resources/simplefragment.shader | 8 - .../particles/resources/simplevertex.shader | 36 - .../particles/resources/spritefragment.shader | 10 - .../particles/resources/spriteimagefragment.shader | 9 - .../particles/resources/spriteimagevertex.shader | 52 -- .../particles/resources/spritevertex.shader | 77 -- .../particles/resources/superfragment.shader | 11 - src/imports/particles/resources/supervertex.shader | 57 -- .../particles/resources/trailsfragment.shader | 8 - .../particles/resources/trailsvertex.shader | 37 - .../particles/resources/ultrafragment.shader | 16 - src/imports/particles/resources/ultravertex.shader | 94 -- src/imports/particles/speedlimitaffector.cpp | 77 -- src/imports/particles/speedlimitaffector.h | 89 -- src/imports/particles/spriteengine.cpp | 437 --------- src/imports/particles/spriteengine.h | 161 ---- src/imports/particles/spritegoalaffector.cpp | 100 --- src/imports/particles/spritegoalaffector.h | 104 --- src/imports/particles/spriteimage.cpp | 353 -------- src/imports/particles/spriteimage.h | 114 --- src/imports/particles/spriteparticle.cpp | 449 ---------- src/imports/particles/spriteparticle.h | 99 -- src/imports/particles/spriteparticles.qrc | 22 - src/imports/particles/spritestate.cpp | 57 -- src/imports/particles/spritestate.h | 231 ----- src/imports/particles/superparticle.cpp | 511 ----------- src/imports/particles/superparticle.h | 389 -------- src/imports/particles/swarmaffector.cpp | 114 --- src/imports/particles/swarmaffector.h | 116 --- src/imports/particles/toggleaffector.cpp | 59 -- src/imports/particles/toggleaffector.h | 102 --- src/imports/particles/trailsemitter.cpp | 200 ----- src/imports/particles/trailsemitter.h | 105 --- src/imports/particles/turbulenceaffector.cpp | 159 ---- src/imports/particles/turbulenceaffector.h | 125 --- src/imports/particles/ultraparticle.cpp | 993 --------------------- src/imports/particles/ultraparticle.h | 354 -------- src/imports/particles/varyingvector.cpp | 56 -- src/imports/particles/varyingvector.h | 72 -- src/imports/particles/wanderaffector.cpp | 110 --- src/imports/particles/wanderaffector.h | 136 --- src/imports/particles/zoneaffector.cpp | 68 -- src/imports/particles/zoneaffector.h | 159 ---- 189 files changed, 10168 insertions(+), 14466 deletions(-) create mode 100644 src/declarative/items/qsgsprite.cpp create mode 100644 src/declarative/items/qsgsprite_p.h create mode 100644 src/declarative/items/qsgspriteengine.cpp create mode 100644 src/declarative/items/qsgspriteengine_p.h create mode 100644 src/declarative/items/qsgspriteimage.cpp create mode 100644 src/declarative/items/qsgspriteimage_p.h create mode 100644 src/declarative/particles/defaultshaders/ctfragment.shader create mode 100644 src/declarative/particles/defaultshaders/ctvertex.shader create mode 100644 src/declarative/particles/defaultshaders/defaultFadeInOut.png create mode 100644 src/declarative/particles/defaultshaders/deformablefragment.shader create mode 100644 src/declarative/particles/defaultshaders/deformablevertex.shader create mode 100644 src/declarative/particles/defaultshaders/identitytable.png create mode 100644 src/declarative/particles/defaultshaders/simplefragment.shader create mode 100644 src/declarative/particles/defaultshaders/simplevertex.shader create mode 100644 src/declarative/particles/defaultshaders/spritefragment.shader create mode 100644 src/declarative/particles/defaultshaders/spriteimagefragment.shader create mode 100644 src/declarative/particles/defaultshaders/spriteimagevertex.shader create mode 100644 src/declarative/particles/defaultshaders/spritevertex.shader create mode 100644 src/declarative/particles/defaultshaders/superfragment.shader create mode 100644 src/declarative/particles/defaultshaders/supervertex.shader create mode 100644 src/declarative/particles/defaultshaders/trailsfragment.shader create mode 100644 src/declarative/particles/defaultshaders/trailsvertex.shader create mode 100644 src/declarative/particles/defaultshaders/ultrafragment.shader create mode 100644 src/declarative/particles/defaultshaders/ultravertex.shader create mode 100644 src/declarative/particles/particles.pri create mode 100644 src/declarative/particles/particles.qrc create mode 100644 src/declarative/particles/qsgangleddirection.cpp create mode 100644 src/declarative/particles/qsgangleddirection_p.h create mode 100644 src/declarative/particles/qsgcustomparticle.cpp create mode 100644 src/declarative/particles/qsgcustomparticle_p.h create mode 100644 src/declarative/particles/qsgellipseextruder.cpp create mode 100644 src/declarative/particles/qsgellipseextruder_p.h create mode 100644 src/declarative/particles/qsgemitter.cpp create mode 100644 src/declarative/particles/qsgemitter_p.h create mode 100644 src/declarative/particles/qsgfollowemitter.cpp create mode 100644 src/declarative/particles/qsgfollowemitter_p.h create mode 100644 src/declarative/particles/qsgfriction.cpp create mode 100644 src/declarative/particles/qsgfriction_p.h create mode 100644 src/declarative/particles/qsggravity.cpp create mode 100644 src/declarative/particles/qsggravity_p.h create mode 100644 src/declarative/particles/qsgimageparticle.cpp create mode 100644 src/declarative/particles/qsgimageparticle_p.h create mode 100644 src/declarative/particles/qsgitemparticle.cpp create mode 100644 src/declarative/particles/qsgitemparticle_p.h create mode 100644 src/declarative/particles/qsgkill.cpp create mode 100644 src/declarative/particles/qsgkill_p.h create mode 100644 src/declarative/particles/qsglineextruder.cpp create mode 100644 src/declarative/particles/qsglineextruder_p.h create mode 100644 src/declarative/particles/qsgmaskextruder.cpp create mode 100644 src/declarative/particles/qsgmaskextruder_p.h create mode 100644 src/declarative/particles/qsgmodelparticle.cpp create mode 100644 src/declarative/particles/qsgmodelparticle_p.h create mode 100644 src/declarative/particles/qsgparticleaffector.cpp create mode 100644 src/declarative/particles/qsgparticleaffector_p.h create mode 100644 src/declarative/particles/qsgparticleemitter.cpp create mode 100644 src/declarative/particles/qsgparticleemitter_p.h create mode 100644 src/declarative/particles/qsgparticleextruder.cpp create mode 100644 src/declarative/particles/qsgparticleextruder_p.h create mode 100644 src/declarative/particles/qsgparticlepainter.cpp create mode 100644 src/declarative/particles/qsgparticlepainter_p.h create mode 100644 src/declarative/particles/qsgparticlesmodule.cpp create mode 100644 src/declarative/particles/qsgparticlesmodule_p.h create mode 100644 src/declarative/particles/qsgparticlesystem.cpp create mode 100644 src/declarative/particles/qsgparticlesystem_p.h create mode 100644 src/declarative/particles/qsgpointattractor.cpp create mode 100644 src/declarative/particles/qsgpointattractor_p.h create mode 100644 src/declarative/particles/qsgpointdirection.cpp create mode 100644 src/declarative/particles/qsgpointdirection_p.h create mode 100644 src/declarative/particles/qsgspritegoal.cpp create mode 100644 src/declarative/particles/qsgspritegoal_p.h create mode 100644 src/declarative/particles/qsgstochasticdirection.cpp create mode 100644 src/declarative/particles/qsgstochasticdirection_p.h create mode 100644 src/declarative/particles/qsgtargeteddirection.cpp create mode 100644 src/declarative/particles/qsgtargeteddirection_p.h create mode 100644 src/declarative/particles/qsgturbulence.cpp create mode 100644 src/declarative/particles/qsgturbulence_p.h create mode 100644 src/declarative/particles/qsgwander.cpp create mode 100644 src/declarative/particles/qsgwander_p.h delete mode 100644 src/imports/particles/angledvector.cpp delete mode 100644 src/imports/particles/angledvector.h delete mode 100644 src/imports/particles/attractoraffector.cpp delete mode 100644 src/imports/particles/attractoraffector.h delete mode 100644 src/imports/particles/burstemitter.cpp delete mode 100644 src/imports/particles/burstemitter.h delete mode 100644 src/imports/particles/coloredparticle.cpp delete mode 100644 src/imports/particles/coloredparticle.h delete mode 100644 src/imports/particles/dataparticle.cpp delete mode 100644 src/imports/particles/dataparticle.h delete mode 100644 src/imports/particles/deformableparticle.cpp delete mode 100644 src/imports/particles/deformableparticle.h delete mode 100644 src/imports/particles/directedvector.cpp delete mode 100644 src/imports/particles/directedvector.h delete mode 100644 src/imports/particles/driftaffector.cpp delete mode 100644 src/imports/particles/driftaffector.h delete mode 100644 src/imports/particles/ellipseextruder.cpp delete mode 100644 src/imports/particles/ellipseextruder.h delete mode 100644 src/imports/particles/eternalaffector.cpp delete mode 100644 src/imports/particles/eternalaffector.h delete mode 100644 src/imports/particles/followemitter.cpp delete mode 100644 src/imports/particles/followemitter.h delete mode 100644 src/imports/particles/frictionaffector.cpp delete mode 100644 src/imports/particles/frictionaffector.h delete mode 100644 src/imports/particles/gravitationalsingularityaffector.cpp delete mode 100644 src/imports/particles/gravitationalsingularityaffector.h delete mode 100644 src/imports/particles/gravityaffector.cpp delete mode 100644 src/imports/particles/gravityaffector.h delete mode 100644 src/imports/particles/itemparticle.cpp delete mode 100644 src/imports/particles/itemparticle.h delete mode 100644 src/imports/particles/killaffector.cpp delete mode 100644 src/imports/particles/killaffector.h delete mode 100644 src/imports/particles/lineextruder.cpp delete mode 100644 src/imports/particles/lineextruder.h delete mode 100644 src/imports/particles/main.cpp delete mode 100644 src/imports/particles/maskextruder.cpp delete mode 100644 src/imports/particles/maskextruder.h delete mode 100644 src/imports/particles/meanderaffector.cpp delete mode 100644 src/imports/particles/meanderaffector.h delete mode 100644 src/imports/particles/particle.cpp delete mode 100644 src/imports/particles/particle.h delete mode 100644 src/imports/particles/particleaffector.cpp delete mode 100644 src/imports/particles/particleaffector.h delete mode 100644 src/imports/particles/particleemitter.cpp delete mode 100644 src/imports/particles/particleemitter.h delete mode 100644 src/imports/particles/particleextruder.cpp delete mode 100644 src/imports/particles/particleextruder.h create mode 100644 src/imports/particles/particles.cpp delete mode 100644 src/imports/particles/particlesystem.cpp delete mode 100644 src/imports/particles/particlesystem.h delete mode 100644 src/imports/particles/pictureaffector.cpp delete mode 100644 src/imports/particles/pictureaffector.h delete mode 100644 src/imports/particles/pluginmain.h delete mode 100644 src/imports/particles/pointvector.cpp delete mode 100644 src/imports/particles/pointvector.h delete mode 100644 src/imports/particles/resetaffector.cpp delete mode 100644 src/imports/particles/resetaffector.h delete mode 100644 src/imports/particles/resources/ctfragment.shader delete mode 100644 src/imports/particles/resources/ctvertex.shader delete mode 100644 src/imports/particles/resources/defaultFadeInOut.png delete mode 100644 src/imports/particles/resources/deformablefragment.shader delete mode 100644 src/imports/particles/resources/deformablevertex.shader delete mode 100644 src/imports/particles/resources/identitytable.png delete mode 100644 src/imports/particles/resources/simplefragment.shader delete mode 100644 src/imports/particles/resources/simplevertex.shader delete mode 100644 src/imports/particles/resources/spritefragment.shader delete mode 100644 src/imports/particles/resources/spriteimagefragment.shader delete mode 100644 src/imports/particles/resources/spriteimagevertex.shader delete mode 100644 src/imports/particles/resources/spritevertex.shader delete mode 100644 src/imports/particles/resources/superfragment.shader delete mode 100644 src/imports/particles/resources/supervertex.shader delete mode 100644 src/imports/particles/resources/trailsfragment.shader delete mode 100644 src/imports/particles/resources/trailsvertex.shader delete mode 100644 src/imports/particles/resources/ultrafragment.shader delete mode 100644 src/imports/particles/resources/ultravertex.shader delete mode 100644 src/imports/particles/speedlimitaffector.cpp delete mode 100644 src/imports/particles/speedlimitaffector.h delete mode 100644 src/imports/particles/spriteengine.cpp delete mode 100644 src/imports/particles/spriteengine.h delete mode 100644 src/imports/particles/spritegoalaffector.cpp delete mode 100644 src/imports/particles/spritegoalaffector.h delete mode 100644 src/imports/particles/spriteimage.cpp delete mode 100644 src/imports/particles/spriteimage.h delete mode 100644 src/imports/particles/spriteparticle.cpp delete mode 100644 src/imports/particles/spriteparticle.h delete mode 100644 src/imports/particles/spriteparticles.qrc delete mode 100644 src/imports/particles/spritestate.cpp delete mode 100644 src/imports/particles/spritestate.h delete mode 100644 src/imports/particles/superparticle.cpp delete mode 100644 src/imports/particles/superparticle.h delete mode 100644 src/imports/particles/swarmaffector.cpp delete mode 100644 src/imports/particles/swarmaffector.h delete mode 100644 src/imports/particles/toggleaffector.cpp delete mode 100644 src/imports/particles/toggleaffector.h delete mode 100644 src/imports/particles/trailsemitter.cpp delete mode 100644 src/imports/particles/trailsemitter.h delete mode 100644 src/imports/particles/turbulenceaffector.cpp delete mode 100644 src/imports/particles/turbulenceaffector.h delete mode 100644 src/imports/particles/ultraparticle.cpp delete mode 100644 src/imports/particles/ultraparticle.h delete mode 100644 src/imports/particles/varyingvector.cpp delete mode 100644 src/imports/particles/varyingvector.h delete mode 100644 src/imports/particles/wanderaffector.cpp delete mode 100644 src/imports/particles/wanderaffector.h delete mode 100644 src/imports/particles/zoneaffector.cpp delete mode 100644 src/imports/particles/zoneaffector.h (limited to 'src') diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index adf1408c58..fc64fa07fb 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -33,6 +33,7 @@ include(qml/qml.pri) include(debugger/debugger.pri) include(scenegraph/scenegraph.pri) include(items/items.pri) +include(particles/particles.pri) symbian: { TARGET.UID3=0x2001E623 diff --git a/src/declarative/items/items.pri b/src/declarative/items/items.pri index d6942973cd..f29a82e77e 100644 --- a/src/declarative/items/items.pri +++ b/src/declarative/items/items.pri @@ -61,6 +61,9 @@ HEADERS += \ $$PWD/qsgcanvasitem_p.h \ $$PWD/qsgcontext2d_p.h \ $$PWD/qsgcontext2d_p_p.h \ + $$PWD/qsgspriteengine_p.h \ + $$PWD/qsgsprite_p.h \ + $$PWD/qsgspriteimage_p.h \ SOURCES += \ $$PWD/qsgevents.cpp \ @@ -100,6 +103,9 @@ SOURCES += \ $$PWD/qsgimplicitsizeitem.cpp \ $$PWD/qsgcanvasitem.cpp \ $$PWD/qsgcontext2d.cpp \ + $$PWD/qsgspriteengine.cpp \ + $$PWD/qsgsprite.cpp \ + $$PWD/qsgspriteimage.cpp \ SOURCES += \ $$PWD/qsgshadereffectitem.cpp \ diff --git a/src/declarative/items/qsgitemsmodule.cpp b/src/declarative/items/qsgitemsmodule.cpp index 6ea20bb38b..a29776fc68 100644 --- a/src/declarative/items/qsgitemsmodule.cpp +++ b/src/declarative/items/qsgitemsmodule.cpp @@ -75,6 +75,8 @@ //#include "private/qsgpincharea_p.h" #include "qsgcanvasitem_p.h" #include "qsgcontext2d_p.h" +#include "qsgsprite_p.h" +#include "qsgspriteimage_p.h" static QDeclarativePrivate::AutoParentResult qsgitem_autoParent(QObject *obj, QObject *parent) { @@ -179,6 +181,8 @@ static void qt_sgitems_defineModule(const char *uri, int major, int minor) qmlRegisterType(); qmlRegisterType(); + qmlRegisterType("QtQuick", 2, 0, "Sprite"); + qmlRegisterType("QtQuick", 2, 0, "SpriteImage"); qmlRegisterType(uri, major, minor,"ParentChange"); qmlRegisterType(uri, major, minor,"AnchorChanges"); diff --git a/src/declarative/items/qsgsprite.cpp b/src/declarative/items/qsgsprite.cpp new file mode 100644 index 0000000000..694976a540 --- /dev/null +++ b/src/declarative/items/qsgsprite.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsprite_p.h" + +QT_BEGIN_NAMESPACE + +QSGSprite::QSGSprite(QObject *parent) : + QObject(parent) + , m_generatedCount(0) + , m_framesPerRow(0) + , m_frames(1) + , m_frameHeight(0) + , m_frameWidth(0) + , m_duration(1000) +{ +} + +QT_END_NAMESPACE diff --git a/src/declarative/items/qsgsprite_p.h b/src/declarative/items/qsgsprite_p.h new file mode 100644 index 0000000000..652a4cd482 --- /dev/null +++ b/src/declarative/items/qsgsprite_p.h @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPRITESTATE_H +#define SPRITESTATE_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGSprite : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged) + //If frame height or width is not specified, it is assumed to be a single long row of frames. + //Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used. + Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged) + Q_PROPERTY(int frameWidth READ frameWidth WRITE setFrameWidth NOTIFY frameWidthChanged) + Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) + Q_PROPERTY(int durationVariance READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged) + Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged) + Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged) + +public: + explicit QSGSprite(QObject *parent = 0); + + QUrl source() const + { + return m_source; + } + + int frames() const + { + return m_frames; + } + + int frameHeight() const + { + return m_frameHeight; + } + + int frameWidth() const + { + return m_frameWidth; + } + + int duration() const + { + return m_duration; + } + + QString name() const + { + return m_name; + } + + QVariantMap to() const + { + return m_to; + } + + qreal speedModifer() const + { + return m_speedModifier; + } + + int durationVariance() const + { + return m_durationVariance; + } + +signals: + + void sourceChanged(QUrl arg); + + void framesChanged(int arg); + + void frameHeightChanged(int arg); + + void frameWidthChanged(int arg); + + void durationChanged(int arg); + + void nameChanged(QString arg); + + void toChanged(QVariantMap arg); + + void speedModifierChanged(qreal arg); + + void durationVarianceChanged(int arg); + +public slots: + + void setSource(QUrl arg) + { + if (m_source != arg) { + m_source = arg; + emit sourceChanged(arg); + } + } + + void setFrames(int arg) + { + if (m_frames != arg) { + m_frames = arg; + emit framesChanged(arg); + } + } + + void setFrameHeight(int arg) + { + if (m_frameHeight != arg) { + m_frameHeight = arg; + emit frameHeightChanged(arg); + } + } + + void setFrameWidth(int arg) + { + if (m_frameWidth != arg) { + m_frameWidth = arg; + emit frameWidthChanged(arg); + } + } + + void setDuration(int arg) + { + if (m_duration != arg) { + m_duration = arg; + emit durationChanged(arg); + } + } + + void setName(QString arg) + { + if (m_name != arg) { + m_name = arg; + emit nameChanged(arg); + } + } + + void setTo(QVariantMap arg) + { + if (m_to != arg) { + m_to = arg; + emit toChanged(arg); + } + } + + void setSpeedModifier(qreal arg) + { + if (m_speedModifier != arg) { + m_speedModifier = arg; + emit speedModifierChanged(arg); + } + } + + void setDurationVariance(int arg) + { + if (m_durationVariance != arg) { + m_durationVariance = arg; + emit durationVarianceChanged(arg); + } + } + +private: + friend class QSGImageParticle; + friend class QSGSpriteEngine; + int m_generatedCount; + int m_framesPerRow; + QUrl m_source; + int m_frames; + int m_frameHeight; + int m_frameWidth; + int m_duration; + QString m_name; + QVariantMap m_to; + qreal m_speedModifier; + int m_durationVariance; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // SPRITESTATE_H diff --git a/src/declarative/items/qsgspriteengine.cpp b/src/declarative/items/qsgspriteengine.cpp new file mode 100644 index 0000000000..27de0d94f6 --- /dev/null +++ b/src/declarative/items/qsgspriteengine.cpp @@ -0,0 +1,437 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgspriteengine_p.h" +#include "qsgsprite_p.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QSGSpriteEngine::QSGSpriteEngine(QObject *parent) : + QObject(parent), m_timeOffset(0) +{ + //Default size 1 + setCount(1); + m_advanceTime.start(); +} + +QSGSpriteEngine::QSGSpriteEngine(QList states, QObject *parent) : + QObject(parent), m_states(states), m_timeOffset(0) +{ + //Default size 1 + setCount(1); + m_advanceTime.start(); +} + +QSGSpriteEngine::~QSGSpriteEngine() +{ +} + +int QSGSpriteEngine::maxFrames() +{ + return m_maxFrames; +} + +/* States too large to fit in one row are split into multiple rows + This is more efficient for the implementation, but should remain an implementation detail (invisible from QML) + Therefore the below functions abstract sprite from the viewpoint of classes that pass the details onto shaders + But States maintain their listed index for internal structures +TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost +*/ +int QSGSpriteEngine::spriteState(int sprite) +{ + int state = m_sprites[sprite]; + if(!m_states[state]->m_generatedCount) + return state; + int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; + return state + extra; +} + +int QSGSpriteEngine::spriteStart(int sprite) +{ + int state = m_sprites[sprite]; + if(!m_states[state]->m_generatedCount) + return m_startTimes[sprite]; + int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; + return state + extra*rowDuration; +} + +int QSGSpriteEngine::spriteFrames(int sprite) +{ + int state = m_sprites[sprite]; + if(!m_states[state]->m_generatedCount) + return m_states[state]->frames(); + int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; + if(extra == m_states[state]->m_generatedCount - 1)//last state + return m_states[state]->frames() % m_states[state]->m_framesPerRow; + else + return m_states[state]->m_framesPerRow; +} + +int QSGSpriteEngine::spriteDuration(int sprite) +{ + int state = m_sprites[sprite]; + if(!m_states[state]->m_generatedCount) + return m_states[state]->duration(); + int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; + if(extra == m_states[state]->m_generatedCount - 1)//last state + return (m_states[state]->duration() * m_states[state]->frames()) % rowDuration; + else + return rowDuration; +} + +int QSGSpriteEngine::spriteCount()//TODO: Actually image state count, need to rename these things to make sense together +{ + return m_imageStateCount; +} + +void QSGSpriteEngine::setGoal(int state, int sprite, bool jump) +{ + if(sprite >= m_sprites.count() || state >= m_states.count()) + return; + if(!jump){ + m_goals[sprite] = state; + return; + } + + if(m_sprites[sprite] == state) + return;//Already there + m_sprites[sprite] = state; + m_goals[sprite] = -1; + restartSprite(sprite); + return; +} + +QImage QSGSpriteEngine::assembledImage() +{ + int frameHeight = 0; + int frameWidth = 0; + m_maxFrames = 0; + m_imageStateCount = 0; + + int maxSize; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); + + foreach(QSGSprite* state, m_states){ + if(state->frames() > m_maxFrames) + m_maxFrames = state->frames(); + + QImage img(state->source().toLocalFile()); + if (img.isNull()) { + qWarning() << "SpriteEngine: loading image failed..." << state->source().toLocalFile(); + return QImage(); + } + + //Check that the frame sizes are the same within one engine + int imgWidth = state->frameWidth(); + if(!imgWidth) + imgWidth = img.width() / state->frames(); + if(frameWidth){ + if(imgWidth != frameWidth){ + qWarning() << "SpriteEngine: Irregular frame width..." << state->source().toLocalFile(); + return QImage(); + } + }else{ + frameWidth = imgWidth; + } + + int imgHeight = state->frameHeight(); + if(!imgHeight) + imgHeight = img.height(); + if(frameHeight){ + if(imgHeight!=frameHeight){ + qWarning() << "SpriteEngine: Irregular frame height..." << state->source().toLocalFile(); + return QImage(); + } + }else{ + frameHeight = imgHeight; + } + + if(state->frames() * frameWidth > maxSize){ + struct helper{ + static int divRoundUp(int a, int b){return (a+b-1)/b;} + }; + int rowsNeeded = helper::divRoundUp(state->frames(), helper::divRoundUp(maxSize, frameWidth)); + if(rowsNeeded * frameHeight > maxSize){ + qWarning() << "SpriteEngine: Animation too large to fit in one texture..." << state->source().toLocalFile(); + qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; + } + state->m_generatedCount = rowsNeeded; + m_imageStateCount += rowsNeeded; + }else{ + m_imageStateCount++; + } + } + + //maxFrames is max number in a line of the texture + if(m_maxFrames * frameWidth > maxSize) + m_maxFrames = maxSize/frameWidth; + QImage image(frameWidth * m_maxFrames, frameHeight * m_imageStateCount, QImage::Format_ARGB32); + image.fill(0); + QPainter p(&image); + int y = 0; + foreach(QSGSprite* state, m_states){ + QImage img(state->source().toLocalFile()); + if(img.height() == frameHeight && img.width() < maxSize){//Simple case + p.drawImage(0,y,img); + y += frameHeight; + }else{ + state->m_framesPerRow = image.width()/frameWidth; + int x = 0; + int curX = 0; + int curY = 0; + int framesLeft = state->frames(); + while(framesLeft > 0){ + if(image.width() - x + curX <= img.width()){//finish a row in image (dest) + int copied = image.width() - x; + Q_ASSERT(!(copied % frameWidth));//XXX: Just checking + framesLeft -= copied/frameWidth; + p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight)); + y += frameHeight; + curX += copied; + x = 0; + if(curX == img.width()){ + curX = 0; + curY += frameHeight; + } + }else{//finish a row in img (src) + int copied = img.width() - curX; + Q_ASSERT(!(copied % frameWidth));//XXX: Just checking + framesLeft -= copied/frameWidth; + p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight)); + curY += frameHeight; + x += copied; + curX = 0; + } + } + if(x) + y += frameHeight; + } + } + + if(image.height() > maxSize){ + qWarning() << "SpriteEngine: Too many animations to fit in one texture..."; + qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; + return QImage(); + } + return image; +} + +void QSGSpriteEngine::setCount(int c) +{ + m_sprites.resize(c); + m_goals.resize(c); + m_startTimes.resize(c); +} + +void QSGSpriteEngine::startSprite(int index) +{ + if(index >= m_sprites.count()) + return; + m_sprites[index] = 0; + m_goals[index] = -1; + restartSprite(index); +} + +void QSGSpriteEngine::restartSprite(int index) +{ + m_startTimes[index] = m_timeOffset + m_advanceTime.elapsed(); + int time = m_states[m_sprites[index]]->duration() * m_states[m_sprites[index]]->frames() + m_startTimes[index]; + for(int i=0; i= m_stateUpdates.first().first){ + foreach(int idx, m_stateUpdates.first().second){ + if(idx >= m_sprites.count()) + continue;//TODO: Proper fix(because this does happen and I'm just ignoring it) + int stateIdx = m_sprites[idx]; + int nextIdx = -1; + int goalPath = goalSeek(stateIdx, idx); + if(goalPath == -1){//Random + qreal r =(qreal) qrand() / (qreal) RAND_MAX; + qreal total = 0.0; + for(QVariantMap::const_iterator iter=m_states[stateIdx]->m_to.constBegin(); + iter!=m_states[stateIdx]->m_to.constEnd(); iter++) + total += (*iter).toReal(); + r*=total; + for(QVariantMap::const_iterator iter= m_states[stateIdx]->m_to.constBegin(); + iter!=m_states[stateIdx]->m_to.constEnd(); iter++){ + if(r < (*iter).toReal()){ + bool superBreak = false; + for(int i=0; iname() == iter.key()){ + nextIdx = i; + superBreak = true; + break; + } + } + if(superBreak) + break; + } + r -= (*iter).toReal(); + } + }else{//Random out of shortest paths to goal + nextIdx = goalPath; + } + if(nextIdx == -1)//No to states means stay here + nextIdx = stateIdx; + + m_sprites[idx] = nextIdx; + m_startTimes[idx] = time; + //TODO: emit something? Remember to emit this when a psuedostate changes too + addToUpdateList((m_states[nextIdx]->duration() * m_states[nextIdx]->frames()) + time, idx); + } + m_stateUpdates.pop_front(); + } + + m_timeOffset = time; + m_advanceTime.start(); + if(m_stateUpdates.isEmpty()) + return -1; + return m_stateUpdates.first().first; +} + +int QSGSpriteEngine::goalSeek(int curIdx, int spriteIdx, int dist) +{ + QString goalName; + if(m_goals[spriteIdx] != -1) + goalName = m_states[m_goals[spriteIdx]]->name(); + else + goalName = m_globalGoal; + if(goalName.isEmpty()) + return -1; + //TODO: caching instead of excessively redoing iterative deepening (which was chosen arbitarily anyways) + // Paraphrased - implement in an *efficient* manner + for(int i=0; iname() == goalName) + return curIdx; + if(dist < 0) + dist = m_states.count(); + QSGSprite* curState = m_states[curIdx]; + for(QVariantMap::const_iterator iter = curState->m_to.constBegin(); + iter!=curState->m_to.constEnd(); iter++){ + if(iter.key() == goalName) + for(int i=0; iname() == goalName) + return i; + } + QSet options; + for(int i=1; im_to.constBegin(); + iter!=curState->m_to.constEnd(); iter++){ + int option = -1; + for(int j=0; jname() == iter.key()) + if(goalSeek(j, spriteIdx, i) != -1) + option = j; + if(option != -1) + options << option; + } + if(!options.isEmpty()){ + if(options.count()==1) + return *(options.begin()); + int option = -1; + qreal r =(qreal) qrand() / (qreal) RAND_MAX; + qreal total; + for(QSet::const_iterator iter=options.constBegin(); + iter!=options.constEnd(); iter++) + total += curState->m_to.value(m_states[(*iter)]->name()).toReal(); + r *= total; + for(QVariantMap::const_iterator iter = curState->m_to.constBegin(); + iter!=curState->m_to.constEnd(); iter++){ + bool superContinue = true; + for(int j=0; jname() == iter.key()) + if(options.contains(j)) + superContinue = false; + if(superContinue) + continue; + if(r < (*iter).toReal()){ + bool superBreak = false; + for(int j=0; jname() == iter.key()){ + option = j; + superBreak = true; + break; + } + } + if(superBreak) + break; + } + r-=(*iter).toReal(); + } + return option; + } + } + return -1; +} + +void QSGSpriteEngine::addToUpdateList(uint t, int idx) +{ + for(int i=0; i t){ + QList tmpList; + tmpList << idx; + m_stateUpdates.insert(i, qMakePair(t, tmpList)); + return; + } + } + QList tmpList; + tmpList << idx; + m_stateUpdates << qMakePair(t, tmpList); +} + +QT_END_NAMESPACE diff --git a/src/declarative/items/qsgspriteengine_p.h b/src/declarative/items/qsgspriteengine_p.h new file mode 100644 index 0000000000..8ab6e3a30a --- /dev/null +++ b/src/declarative/items/qsgspriteengine_p.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPRITEENGINE_H +#define SPRITEENGINE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGSprite; + +class QSGSpriteEngine : public QObject +{ + Q_OBJECT + //TODO: Optimize single sprite case + Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) + Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged) +public: + explicit QSGSpriteEngine(QObject *parent = 0); + QSGSpriteEngine(QList sprites, QObject *parent=0); + ~QSGSpriteEngine(); + + QDeclarativeListProperty sprites() + { + return QDeclarativeListProperty(this, m_states); + } + QString globalGoal() const + { + return m_globalGoal; + } + + int count() const {return m_sprites.count();} + void setCount(int c); + + int spriteState(int sprite=0);// {return m_sprites[sprite];} + int spriteStart(int sprite=0);// {return m_startTimes[sprite];} + int spriteFrames(int sprite=0); + int spriteDuration(int sprite=0); + int spriteCount();//Like state count, but for the image states + int maxFrames(); + + void setGoal(int state, int sprite=0, bool jump=false); + QImage assembledImage(); + + void startSprite(int index=0); + +private://Nothing outside should use this? + friend class QSGSpriteGoalAffector;//XXX: Fix interface + int stateCount() {return m_states.count();} + int stateIndex(QSGSprite* s){return m_states.indexOf(s);}//TODO: Does this need to be hidden? + QSGSprite* state(int idx){return m_states[idx];}//Used by spritegoal affector +signals: + + void globalGoalChanged(QString arg); + +public slots: + void setGlobalGoal(QString arg) + { + if (m_globalGoal != arg) { + m_globalGoal = arg; + emit globalGoalChanged(arg); + } + } + + uint updateSprites(uint time); + +private: + void restartSprite(int sprite); + void addToUpdateList(uint t, int idx); + int goalSeek(int curState, int spriteIdx, int dist=-1); + QList m_states; + QVector m_sprites;//int is the index in m_states of the current state + QVector m_goals; + QVector m_startTimes; + QList > > m_stateUpdates;//### This could be done faster + + QTime m_advanceTime; + uint m_timeOffset; + QString m_globalGoal; + int m_maxFrames; + int m_imageStateCount; +}; + +//Common use is to have your own list property which is transparently an engine +inline void spriteAppend(QDeclarativeListProperty *p, QSGSprite* s) +{ + reinterpret_cast *>(p->data)->append(s); + p->object->metaObject()->invokeMethod(p->object, "createEngine"); +} + +inline QSGSprite* spriteAt(QDeclarativeListProperty *p, int idx) +{ + return reinterpret_cast *>(p->data)->at(idx); +} + +inline void spriteClear(QDeclarativeListProperty *p) +{ + reinterpret_cast *>(p->data)->clear(); + p->object->metaObject()->invokeMethod(p->object, "createEngine"); +} + +inline int spriteCount(QDeclarativeListProperty *p) +{ + return reinterpret_cast *>(p->data)->count(); +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SPRITEENGINE_H diff --git a/src/declarative/items/qsgspriteimage.cpp b/src/declarative/items/qsgspriteimage.cpp new file mode 100644 index 0000000000..8cc0dc5b76 --- /dev/null +++ b/src/declarative/items/qsgspriteimage.cpp @@ -0,0 +1,353 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgspriteimage_p.h" +#include "qsgsprite_p.h" +#include "qsgspriteengine_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QSGSpriteMaterial : public QSGMaterial +{ +public: + QSGSpriteMaterial(); + virtual ~QSGSpriteMaterial(); + virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } + virtual QSGMaterialShader *createShader() const; + virtual int compare(const QSGMaterial *other) const + { + return this - static_cast(other); + } + + QSGTexture *texture; + + qreal timestamp; + qreal timelength; + int framecount; + int animcount; + int width; + int height; +}; + +QSGSpriteMaterial::QSGSpriteMaterial() + : timestamp(0) + , timelength(1) + , framecount(1) + , animcount(1) + , width(0) + , height(0) +{ + setFlag(Blending, true); +} + +QSGSpriteMaterial::~QSGSpriteMaterial() +{ + delete texture; +} + +class SpriteMaterialData : public QSGMaterialShader +{ +public: + SpriteMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) + { + QFile vf(vertexFile ? vertexFile : ":defaultshaders/spriteimagevertex.shader"); + vf.open(QFile::ReadOnly); + m_vertex_code = vf.readAll(); + + QFile ff(fragmentFile ? fragmentFile : ":defaultshaders/spriteimagefragment.shader"); + ff.open(QFile::ReadOnly); + m_fragment_code = ff.readAll(); + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + void deactivate() { + QSGMaterialShader::deactivate(); + + for (int i=0; i<8; ++i) { + program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); + } + } + + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) + { + QSGSpriteMaterial *m = static_cast(newEffect); + m->texture->bind(); + + program()->setUniformValue(m_opacity_id, state.opacity()); + program()->setUniformValue(m_timestamp_id, (float) m->timestamp); + program()->setUniformValue(m_framecount_id, (float) m->framecount); + program()->setUniformValue(m_animcount_id, (float) m->animcount); + program()->setUniformValue(m_width_id, (float) m->width); + program()->setUniformValue(m_height_id, (float) m->height); + + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); + } + + virtual void initialize() { + m_matrix_id = program()->uniformLocation("matrix"); + m_opacity_id = program()->uniformLocation("opacity"); + m_timestamp_id = program()->uniformLocation("timestamp"); + m_framecount_id = program()->uniformLocation("framecount"); + m_animcount_id = program()->uniformLocation("animcount"); + m_width_id = program()->uniformLocation("width"); + m_height_id = program()->uniformLocation("height"); + } + + virtual const char *vertexShader() const { return m_vertex_code.constData(); } + virtual const char *fragmentShader() const { return m_fragment_code.constData(); } + + virtual char const *const *attributeNames() const { + static const char *attr[] = { + "vTex", + "vAnimData", + 0 + }; + return attr; + } + + virtual bool isColorTable() const { return false; } + + int m_matrix_id; + int m_opacity_id; + int m_timestamp_id; + int m_framecount_id; + int m_animcount_id; + int m_width_id; + int m_height_id; + + QByteArray m_vertex_code; + QByteArray m_fragment_code; + + static float chunkOfBytes[1024]; +}; +float SpriteMaterialData::chunkOfBytes[1024]; + +QSGMaterialShader *QSGSpriteMaterial::createShader() const +{ + return new SpriteMaterialData; +} + +struct SpriteVertex { + float tx; + float ty; + float animIdx; + float frameDuration; + float frameCount; + float animT; +}; + +struct SpriteVertices { + SpriteVertex v1; + SpriteVertex v2; + SpriteVertex v3; + SpriteVertex v4; +}; + +QSGSpriteImage::QSGSpriteImage(QSGItem *parent) : + QSGItem(parent) + , m_node(0) + , m_material(0) + , m_spriteEngine(0) + , m_pleaseReset(false) + , m_running(true) +{ + setFlag(ItemHasContents); + connect(this, SIGNAL(runningChanged(bool)), + this, SLOT(update())); +} + +QDeclarativeListProperty QSGSpriteImage::sprites() +{ + return QDeclarativeListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); +} + +void QSGSpriteImage::createEngine() +{ + //TODO: delay until component complete + if(m_spriteEngine) + delete m_spriteEngine; + if(m_sprites.count()) + m_spriteEngine = new QSGSpriteEngine(m_sprites, this); + else + m_spriteEngine = 0; + reset(); +} + +static QSGGeometry::Attribute SpriteImage_Attributes[] = { + { 0, 2, GL_FLOAT }, // tex + { 1, 4, GL_FLOAT } // animData +}; + +static QSGGeometry::AttributeSet SpriteImage_AttributeSet = +{ + 2, // Attribute Count + (4 + 2) * sizeof(float), + SpriteImage_Attributes +}; + +QSGGeometryNode* QSGSpriteImage::buildNode() +{ + if (!m_spriteEngine) { + qWarning() << "SpriteImage: No sprite engine..."; + return 0; + } + + if (m_material) { + delete m_material; + m_material = 0; + } + + m_material = new QSGSpriteMaterial(); + + QImage image = m_spriteEngine->assembledImage(); + if(image.isNull()) + return 0; + m_material->texture = sceneGraphEngine()->createTextureFromImage(image); + m_material->texture->setFiltering(QSGTexture::Linear); + m_material->framecount = m_spriteEngine->maxFrames(); + + int vCount = 4; + int iCount = 6; + QSGGeometry *g = new QSGGeometry(SpriteImage_AttributeSet, vCount, iCount); + g->setDrawingMode(GL_TRIANGLES); + + SpriteVertices *p = (SpriteVertices *) g->vertexData(); + m_spriteEngine->startSprite(0); + p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = 0; + p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = 0; + p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames(); + p->v1.frameDuration = p->v2.frameDuration = p->v3.frameDuration = p->v4.frameDuration = m_spriteEngine->spriteDuration(); + + p->v1.tx = 0; + p->v1.ty = 0; + + p->v2.tx = 1.0; + p->v2.ty = 0; + + p->v3.tx = 0; + p->v3.ty = 1.0; + + p->v4.tx = 1.0; + p->v4.ty = 1.0; + + quint16 *indices = g->indexDataAsUShort(); + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + indices[3] = 1; + indices[4] = 3; + indices[5] = 2; + + + m_timestamp.start(); + m_node = new QSGGeometryNode(); + m_node->setGeometry(g); + m_node->setMaterial(m_material); + return m_node; +} + +void QSGSpriteImage::reset() +{ + m_pleaseReset = true; +} + +QSGNode *QSGSpriteImage::updatePaintNode(QSGNode *, UpdatePaintNodeData *) +{ + if(m_pleaseReset){ + delete m_node; + delete m_material; + + m_node = 0; + m_material = 0; + m_pleaseReset = false; + } + + prepareNextFrame(); + + if(m_running){ + update(); + if (m_node) + m_node->markDirty(QSGNode::DirtyMaterial); + } + + return m_node; +} + +void QSGSpriteImage::prepareNextFrame() +{ + if (m_node == 0) + m_node = buildNode(); + if (m_node == 0) //error creating node + return; + + uint timeInt = m_timestamp.elapsed(); + qreal time = timeInt / 1000.; + m_material->timestamp = time; + m_material->animcount = m_spriteEngine->spriteCount(); + m_material->height = height(); + m_material->width = width(); + + //Advance State + SpriteVertices *p = (SpriteVertices *) m_node->geometry()->vertexData(); + m_spriteEngine->updateSprites(timeInt); + int curIdx = m_spriteEngine->spriteState(); + if(curIdx != p->v1.animIdx){ + p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = curIdx; + p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = m_spriteEngine->spriteStart()/1000.0; + p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames(); + p->v1.frameDuration = p->v2.frameDuration = p->v3.frameDuration = p->v4.frameDuration = m_spriteEngine->spriteDuration(); + } +} + +QT_END_NAMESPACE diff --git a/src/declarative/items/qsgspriteimage_p.h b/src/declarative/items/qsgspriteimage_p.h new file mode 100644 index 0000000000..f03fd869f0 --- /dev/null +++ b/src/declarative/items/qsgspriteimage_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPRITEIMAGE_H +#define SPRITEIMAGE_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGContext; +class QSGSprite; +class QSGSpriteEngine; +class QSGGeometryNode; +class QSGSpriteMaterial; +class QSGSpriteImage : public QSGItem +{ + Q_OBJECT + Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged) + //###try to share similar spriteEngines for less overhead? + Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) + Q_CLASSINFO("DefaultProperty", "sprites") + +public: + explicit QSGSpriteImage(QSGItem *parent = 0); + + QDeclarativeListProperty sprites(); + + bool running() const + { + return m_running; + } + +signals: + + + void runningChanged(bool arg); + +public slots: + +void setRunning(bool arg) +{ + if (m_running != arg) { + m_running = arg; + emit runningChanged(arg); + } +} + +private slots: + void createEngine(); +protected: + void reset(); + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); +private: + void prepareNextFrame(); + QSGGeometryNode* buildNode(); + QSGGeometryNode *m_node; + QSGSpriteMaterial *m_material; + QList m_sprites; + QSGSpriteEngine* m_spriteEngine; + QTime m_timestamp; + int m_maxFrames; + bool m_pleaseReset; + bool m_running; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SPRITEIMAGE_H diff --git a/src/declarative/particles/defaultshaders/ctfragment.shader b/src/declarative/particles/defaultshaders/ctfragment.shader new file mode 100644 index 0000000000..a17f5841ca --- /dev/null +++ b/src/declarative/particles/defaultshaders/ctfragment.shader @@ -0,0 +1,11 @@ +uniform sampler2D texture; +uniform sampler2D colortable; +uniform sampler2D opacitytable; + +varying highp vec2 fTex; +varying lowp vec4 fColor; +varying lowp float tt; + +void main() { + gl_FragColor = (texture2D(texture, fTex).w) * fColor * texture2D(colortable, vec2(tt, 0.5)) *( texture2D(opacitytable, vec2(tt, 0.5)).w); +} diff --git a/src/declarative/particles/defaultshaders/ctvertex.shader b/src/declarative/particles/defaultshaders/ctvertex.shader new file mode 100644 index 0000000000..b20676cc49 --- /dev/null +++ b/src/declarative/particles/defaultshaders/ctvertex.shader @@ -0,0 +1,38 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration +attribute lowp vec4 vColor; + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform sampler2D sizetable; +uniform sampler2D opacitytable; + +varying highp vec2 fTex; +varying lowp vec4 fColor; +varying lowp float tt; + +void main() { + fTex = vTex; + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + highp float currentSize = mix(size, endSize, t * t) * texture2D(sizetable, vec2(t,0.5)).w; + + if (t < 0. || t > 1.) + currentSize = 0.; + + highp vec2 pos = vPos + - currentSize / 2. + currentSize * vTex // adjust size + + vVec.xy * t * vData.y // apply speed vector.. + + 0.5 * vVec.zw * pow(t * vData.y, 2.); + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + fColor = vColor; + tt = t; + +} diff --git a/src/declarative/particles/defaultshaders/defaultFadeInOut.png b/src/declarative/particles/defaultshaders/defaultFadeInOut.png new file mode 100644 index 0000000000..89c04eaefe Binary files /dev/null and b/src/declarative/particles/defaultshaders/defaultFadeInOut.png differ diff --git a/src/declarative/particles/defaultshaders/deformablefragment.shader b/src/declarative/particles/defaultshaders/deformablefragment.shader new file mode 100644 index 0000000000..494053e319 --- /dev/null +++ b/src/declarative/particles/defaultshaders/deformablefragment.shader @@ -0,0 +1,8 @@ +uniform sampler2D texture; + +varying highp vec2 fTex; +varying lowp float fFade; + +void main() { + gl_FragColor = (texture2D(texture, fTex)) * fFade; +} diff --git a/src/declarative/particles/defaultshaders/deformablevertex.shader b/src/declarative/particles/defaultshaders/deformablevertex.shader new file mode 100644 index 0000000000..01570950b1 --- /dev/null +++ b/src/declarative/particles/defaultshaders/deformablevertex.shader @@ -0,0 +1,57 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration +attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector +attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform lowp float opacity; + +varying highp vec2 fTex; +varying lowp float fFade; + +void main() { + fTex = vTex; + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + highp float currentSize = mix(size, endSize, t * t); + + highp vec2 pos; + if (t < 0. || t > 1.){ + currentSize = 0.; + pos = vPos; + }else{ + highp float rotation = vRotation.x + vRotation.y * t * vData.y; + if(vRotation.z == 1.0){ + highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy; + rotation += atan(curVel.y, curVel.x); + } + highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); + highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); + highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); + highp vec2 xRotatedDeform; + xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; + xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; + highp vec2 yRotatedDeform; + yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; + yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; + pos = vPos + + xRotatedDeform + + yRotatedDeform + //- vec2(1,1) * currentSize * 0.5 // 'center' + + vVec.xy * t * vData.y // apply speed + + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration + } + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + highp float fadeIn = min(t * 10., 1.); + highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); + + fFade = fadeIn * fadeOut * opacity; +} diff --git a/src/declarative/particles/defaultshaders/identitytable.png b/src/declarative/particles/defaultshaders/identitytable.png new file mode 100644 index 0000000000..2cada1bfad Binary files /dev/null and b/src/declarative/particles/defaultshaders/identitytable.png differ diff --git a/src/declarative/particles/defaultshaders/simplefragment.shader b/src/declarative/particles/defaultshaders/simplefragment.shader new file mode 100644 index 0000000000..494053e319 --- /dev/null +++ b/src/declarative/particles/defaultshaders/simplefragment.shader @@ -0,0 +1,8 @@ +uniform sampler2D texture; + +varying highp vec2 fTex; +varying lowp float fFade; + +void main() { + gl_FragColor = (texture2D(texture, fTex)) * fFade; +} diff --git a/src/declarative/particles/defaultshaders/simplevertex.shader b/src/declarative/particles/defaultshaders/simplevertex.shader new file mode 100644 index 0000000000..f185ef0700 --- /dev/null +++ b/src/declarative/particles/defaultshaders/simplevertex.shader @@ -0,0 +1,36 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform lowp float opacity; + +varying highp vec2 fTex; +varying lowp float fFade; + +void main() { + fTex = vTex; + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + highp float currentSize = mix(size, endSize, t * t); + + if (t < 0. || t > 1.) + currentSize = 0.; + + highp vec2 pos = vPos + - currentSize / 2. + currentSize * vTex // adjust size + + vVec.xy * t * vData.y // apply speed vector.. + + 0.5 * vVec.zw * pow(t * vData.y, 2.); + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + highp float fadeIn = min(t * 10., 1.); + highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); + + fFade = fadeIn * fadeOut * opacity; +} diff --git a/src/declarative/particles/defaultshaders/spritefragment.shader b/src/declarative/particles/defaultshaders/spritefragment.shader new file mode 100644 index 0000000000..4d89d69c6a --- /dev/null +++ b/src/declarative/particles/defaultshaders/spritefragment.shader @@ -0,0 +1,10 @@ +uniform sampler2D texture; + +varying highp vec2 fTexA; +varying highp vec2 fTexB; +varying lowp float progress; +varying lowp vec4 fColor; + +void main() { + gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress) * fColor.w; +} diff --git a/src/declarative/particles/defaultshaders/spriteimagefragment.shader b/src/declarative/particles/defaultshaders/spriteimagefragment.shader new file mode 100644 index 0000000000..ecd62cf390 --- /dev/null +++ b/src/declarative/particles/defaultshaders/spriteimagefragment.shader @@ -0,0 +1,9 @@ +uniform sampler2D texture; + +varying highp vec2 fTexA; +varying highp vec2 fTexB; +varying lowp float progress; + +void main() { + gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress); +} diff --git a/src/declarative/particles/defaultshaders/spriteimagevertex.shader b/src/declarative/particles/defaultshaders/spriteimagevertex.shader new file mode 100644 index 0000000000..27de2ada6a --- /dev/null +++ b/src/declarative/particles/defaultshaders/spriteimagevertex.shader @@ -0,0 +1,52 @@ +attribute highp vec2 vTex; +attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim) + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform lowp float opacity; +uniform highp float framecount; //maximum of all anims +uniform highp float animcount; +uniform highp float width; +uniform highp float height; + +varying highp vec2 fTexA; +varying highp vec2 fTexB; +varying lowp float progress; + + +void main() { + //Calculate frame location in texture + highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z); + progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y; + + frameIndex = floor(frameIndex); + highp vec2 frameTex; + if(vTex.x == 0.) + frameTex.x = (frameIndex/framecount); + else + frameTex.x = 1. * ((frameIndex + 1.)/framecount); + + if(vTex.y == 0.) + frameTex.y = (vAnimData.x/animcount); + else + frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); + + fTexA = frameTex; + //Next frame is also passed, for interpolation + if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop + frameIndex = mod(frameIndex+1., vAnimData.z); + + if(vTex.x == 0.) + frameTex.x = (frameIndex/framecount); + else + frameTex.x = 1. * ((frameIndex + 1.)/framecount); + + if(vTex.y == 0.) + frameTex.y = (vAnimData.x/animcount); + else + frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); + fTexB = frameTex; + + + gl_Position = matrix * vec4(width * vTex.x, height * vTex.y, 0, 1); +} diff --git a/src/declarative/particles/defaultshaders/spritevertex.shader b/src/declarative/particles/defaultshaders/spritevertex.shader new file mode 100644 index 0000000000..78b8e36b3b --- /dev/null +++ b/src/declarative/particles/defaultshaders/spritevertex.shader @@ -0,0 +1,77 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration +attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim) + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform lowp float opacity; +uniform highp float framecount; //maximum of all anims +uniform highp float animcount; + +varying highp vec2 fTexA; +varying highp vec2 fTexB; +varying lowp float progress; +varying lowp vec4 fColor; + +void main() { + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + //Calculate frame location in texture + highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z); + progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y; + + frameIndex = floor(frameIndex); + highp vec2 frameTex = vTex; + if(vTex.x == 0.) + frameTex.x = (frameIndex/framecount); + else + frameTex.x = 1. * ((frameIndex + 1.)/framecount); + + if(vTex.y == 0.) + frameTex.y = (vAnimData.x/animcount); + else + frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); + + fTexA = frameTex; + //Next frame is also passed, for interpolation + //### Should the next anim be precalculated to allow for interpolation there? + if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop + frameIndex = mod(frameIndex+1., vAnimData.z); + + if(vTex.x == 0.) + frameTex.x = (frameIndex/framecount); + else + frameTex.x = 1. * ((frameIndex + 1.)/framecount); + + if(vTex.y == 0.) + frameTex.y = (vAnimData.x/animcount); + else + frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); + fTexB = frameTex; + + //Applying Size here seems to screw with RockingAffector? + highp float currentSize = mix(size, endSize, t * t); + + if (t < 0. || t > 1.) + currentSize = 0.; + + //If affector is mananging pos, they don't set speed? + highp vec2 pos = vPos + - currentSize / 2. + currentSize * vTex // adjust size + + vVec.xy * t * vData.y // apply speed vector.. + + 0.5 * vVec.zw * pow(t * vData.y, 2.); + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + // calculate opacity + highp float fadeIn = min(t * 10., 1.); + highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); + + lowp vec4 white = vec4(1.); + fColor = white * fadeIn * fadeOut * opacity; +} diff --git a/src/declarative/particles/defaultshaders/superfragment.shader b/src/declarative/particles/defaultshaders/superfragment.shader new file mode 100644 index 0000000000..a17f5841ca --- /dev/null +++ b/src/declarative/particles/defaultshaders/superfragment.shader @@ -0,0 +1,11 @@ +uniform sampler2D texture; +uniform sampler2D colortable; +uniform sampler2D opacitytable; + +varying highp vec2 fTex; +varying lowp vec4 fColor; +varying lowp float tt; + +void main() { + gl_FragColor = (texture2D(texture, fTex).w) * fColor * texture2D(colortable, vec2(tt, 0.5)) *( texture2D(opacitytable, vec2(tt, 0.5)).w); +} diff --git a/src/declarative/particles/defaultshaders/supervertex.shader b/src/declarative/particles/defaultshaders/supervertex.shader new file mode 100644 index 0000000000..432a23ce05 --- /dev/null +++ b/src/declarative/particles/defaultshaders/supervertex.shader @@ -0,0 +1,57 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration +attribute lowp vec4 vColor; +attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector +attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform sampler2D sizetable; +uniform sampler2D opacitytable; + +varying highp vec2 fTex; +varying lowp vec4 fColor; +varying lowp float tt; + +void main() { + fTex = vTex; + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + highp float currentSize = mix(size, endSize, t * t) * texture2D(sizetable, vec2(t,0.5)).w; + + if (t < 0. || t > 1.) + currentSize = 0.; + + highp vec2 pos; + highp float rotation = vRotation.x + vRotation.y * t * vData.y; + if(vRotation.z == 1.0){ + highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy; + rotation += atan(curVel.y, curVel.x); + } + highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); + highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); + highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); + highp vec2 xRotatedDeform; + xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; + xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; + highp vec2 yRotatedDeform; + yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; + yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; + pos = vPos + + xRotatedDeform + + yRotatedDeform + //- vec2(1,1) * currentSize * 0.5 // 'center' + + vVec.xy * t * vData.y // apply speed + + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + fColor = vColor; + tt = t; + +} diff --git a/src/declarative/particles/defaultshaders/trailsfragment.shader b/src/declarative/particles/defaultshaders/trailsfragment.shader new file mode 100644 index 0000000000..d3db87fa30 --- /dev/null +++ b/src/declarative/particles/defaultshaders/trailsfragment.shader @@ -0,0 +1,8 @@ +uniform sampler2D texture; + +varying highp vec2 fTex; +varying lowp vec4 fColor; + +void main() { + gl_FragColor = (texture2D(texture, fTex).w) * fColor; +} diff --git a/src/declarative/particles/defaultshaders/trailsvertex.shader b/src/declarative/particles/defaultshaders/trailsvertex.shader new file mode 100644 index 0000000000..7bc1d66b71 --- /dev/null +++ b/src/declarative/particles/defaultshaders/trailsvertex.shader @@ -0,0 +1,37 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration +attribute lowp vec4 vColor; + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform lowp float opacity; + +varying highp vec2 fTex; +varying lowp vec4 fColor; + +void main() { + fTex = vTex; + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + highp float currentSize = mix(size, endSize, t * t); + + if (t < 0. || t > 1.) + currentSize = 0.; + + highp vec2 pos = vPos + - currentSize / 2. + currentSize * vTex // adjust size + + vVec.xy * t * vData.y // apply speed vector.. + + 0.5 * vVec.zw * pow(t * vData.y, 2.); + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + highp float fadeIn = min(t * 10., 1.); + highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); + + fColor = vColor * fadeIn * fadeOut * opacity; +} diff --git a/src/declarative/particles/defaultshaders/ultrafragment.shader b/src/declarative/particles/defaultshaders/ultrafragment.shader new file mode 100644 index 0000000000..0627d0f1e8 --- /dev/null +++ b/src/declarative/particles/defaultshaders/ultrafragment.shader @@ -0,0 +1,16 @@ +uniform sampler2D texture; +uniform sampler2D colortable; +uniform sampler2D opacitytable; + +varying highp vec2 fTexA; +varying highp vec2 fTexB; +varying lowp float progress; +varying lowp vec4 fColor; +varying lowp float tt; + +void main() { + gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress) + * fColor + * texture2D(colortable, vec2(tt, 0.5)) + *( texture2D(opacitytable, vec2(tt, 0.5)).w); +} diff --git a/src/declarative/particles/defaultshaders/ultravertex.shader b/src/declarative/particles/defaultshaders/ultravertex.shader new file mode 100644 index 0000000000..65a1a3077a --- /dev/null +++ b/src/declarative/particles/defaultshaders/ultravertex.shader @@ -0,0 +1,94 @@ +attribute highp vec2 vPos; +attribute highp vec2 vTex; +attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration +attribute lowp vec4 vColor; +attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector +attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate +attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim) + +uniform highp mat4 matrix; +uniform highp float timestamp; +uniform highp float framecount; //maximum of all anims +uniform highp float animcount; +uniform sampler2D sizetable; + +varying lowp float tt; +varying highp vec2 fTexA; +varying highp vec2 fTexB; +varying lowp float progress; +varying lowp vec4 fColor; + + +void main() { + highp float size = vData.z; + highp float endSize = vData.w; + + highp float t = (timestamp - vData.x) / vData.y; + + //Calculate frame location in texture + highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z); + progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y; + + frameIndex = floor(frameIndex); + highp vec2 frameTex = vTex; + if(vTex.x == 0.) + frameTex.x = (frameIndex/framecount); + else + frameTex.x = 1. * ((frameIndex + 1.)/framecount); + + if(vTex.y == 0.) + frameTex.y = (vAnimData.x/animcount); + else + frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); + + fTexA = frameTex; + //Next frame is also passed, for interpolation + //### Should the next anim be precalculated to allow for interpolation there? + if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop + frameIndex = mod(frameIndex+1., vAnimData.z); + + if(vTex.x == 0.) + frameTex.x = (frameIndex/framecount); + else + frameTex.x = 1. * ((frameIndex + 1.)/framecount); + + if(vTex.y == 0.) + frameTex.y = (vAnimData.x/animcount); + else + frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); + fTexB = frameTex; + + highp float currentSize = mix(size, endSize, t * t) * texture2D(sizetable, vec2(t,0.5)).w; + + if (t < 0. || t > 1.) + currentSize = 0.; + + highp vec2 pos; + highp float rotation = vRotation.x + vRotation.y * t * vData.y; + if(vRotation.z == 1.0){ + highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy; + rotation += atan(curVel.y, curVel.x); + } + highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); + highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); + highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); + highp vec2 xRotatedDeform; + xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; + xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; + highp vec2 yRotatedDeform; + yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; + yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; + pos = vPos + + xRotatedDeform + + yRotatedDeform + //- vec2(1,1) * currentSize * 0.5 // 'center' + + vVec.xy * t * vData.y // apply speed + + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration + + gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); + + fColor = vColor; + tt = t; + +} diff --git a/src/declarative/particles/particles.pri b/src/declarative/particles/particles.pri new file mode 100644 index 0000000000..04200a380e --- /dev/null +++ b/src/declarative/particles/particles.pri @@ -0,0 +1,60 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qsgangleddirection_p.h \ + $$PWD/qsgcustomparticle_p.h \ + $$PWD/qsgellipseextruder_p.h \ + $$PWD/qsgemitter_p.h \ + $$PWD/qsgfollowemitter_p.h \ + $$PWD/qsgfriction_p.h \ + $$PWD/qsggravity_p.h \ + $$PWD/qsgimageparticle_p.h \ + $$PWD/qsgitemparticle_p.h \ + $$PWD/qsgkill_p.h \ + $$PWD/qsglineextruder_p.h \ + $$PWD/qsgmaskextruder_p.h \ + $$PWD/qsgmodelparticle_p.h \ + $$PWD/qsgparticleaffector_p.h \ + $$PWD/qsgparticleemitter_p.h \ + $$PWD/qsgparticleextruder_p.h \ + $$PWD/qsgparticlepainter_p.h \ + $$PWD/qsgparticlesmodule_p.h \ + $$PWD/qsgparticlesystem_p.h \ + $$PWD/qsgpointattractor_p.h \ + $$PWD/qsgpointdirection_p.h \ + $$PWD/qsgspritegoal_p.h \ + $$PWD/qsgstochasticdirection_p.h \ + $$PWD/qsgtargeteddirection_p.h \ + $$PWD/qsgturbulence_p.h \ + $$PWD/qsgwander_p.h + +SOURCES += \ + $$PWD/qsgangleddirection.cpp \ + $$PWD/qsgcustomparticle.cpp \ + $$PWD/qsgellipseextruder.cpp \ + $$PWD/qsgemitter.cpp \ + $$PWD/qsgfollowemitter.cpp \ + $$PWD/qsgfriction.cpp \ + $$PWD/qsggravity.cpp \ + $$PWD/qsgimageparticle.cpp \ + $$PWD/qsgitemparticle.cpp \ + $$PWD/qsgkill.cpp \ + $$PWD/qsglineextruder.cpp \ + $$PWD/qsgmaskextruder.cpp \ + $$PWD/qsgmodelparticle.cpp \ + $$PWD/qsgparticleaffector.cpp \ + $$PWD/qsgparticleemitter.cpp \ + $$PWD/qsgparticleextruder.cpp \ + $$PWD/qsgparticlepainter.cpp \ + $$PWD/qsgparticlesmodule.cpp \ + $$PWD/qsgparticlesystem.cpp \ + $$PWD/qsgpointattractor.cpp \ + $$PWD/qsgpointdirection.cpp \ + $$PWD/qsgspritegoal.cpp \ + $$PWD/qsgstochasticdirection.cpp \ + $$PWD/qsgtargeteddirection.cpp \ + $$PWD/qsgturbulence.cpp \ + $$PWD/qsgwander.cpp + +RESOURCES += \ + $$PWD/particles.qrc diff --git a/src/declarative/particles/particles.qrc b/src/declarative/particles/particles.qrc new file mode 100644 index 0000000000..85931ec9ce --- /dev/null +++ b/src/declarative/particles/particles.qrc @@ -0,0 +1,22 @@ + + + defaultshaders/spritefragment.shader + defaultshaders/spritevertex.shader + defaultshaders/ctfragment.shader + defaultshaders/ctvertex.shader + defaultshaders/trailsfragment.shader + defaultshaders/trailsvertex.shader + defaultshaders/spriteimagefragment.shader + defaultshaders/spriteimagevertex.shader + defaultshaders/identitytable.png + defaultshaders/defaultFadeInOut.png + defaultshaders/deformablefragment.shader + defaultshaders/deformablevertex.shader + defaultshaders/ultravertex.shader + defaultshaders/ultrafragment.shader + defaultshaders/supervertex.shader + defaultshaders/superfragment.shader + defaultshaders/simplevertex.shader + defaultshaders/simplefragment.shader + + diff --git a/src/declarative/particles/qsgangleddirection.cpp b/src/declarative/particles/qsgangleddirection.cpp new file mode 100644 index 0000000000..5c32b53e3e --- /dev/null +++ b/src/declarative/particles/qsgangleddirection.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgangleddirection_p.h" +#include +QT_BEGIN_NAMESPACE +const qreal CONV = 0.017453292519943295; +QSGAngledDirection::QSGAngledDirection(QObject *parent) : + QSGStochasticDirection(parent) + , m_angle(0) + , m_magnitude(0) + , m_angleVariation(0) + , m_magnitudeVariation(0) +{ + +} + +const QPointF &QSGAngledDirection::sample(const QPointF &from) +{ + //TODO: Faster + qreal theta = m_angle*CONV - m_angleVariation*CONV + rand()/float(RAND_MAX) * m_angleVariation*CONV * 2; + qreal mag = m_magnitude- m_magnitudeVariation + rand()/float(RAND_MAX) * m_magnitudeVariation * 2; + m_ret.setX(mag * cos(theta)); + m_ret.setY(mag * sin(theta)); + return m_ret; +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgangleddirection_p.h b/src/declarative/particles/qsgangleddirection_p.h new file mode 100644 index 0000000000..76262453a9 --- /dev/null +++ b/src/declarative/particles/qsgangleddirection_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGANGLEDDIRECTION_H +#define QSGANGLEDDIRECTION_H +#include "qsgstochasticdirection_p.h" +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGAngledDirection : public QSGStochasticDirection +{ + Q_OBJECT + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) + Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) + Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged) + Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) +public: + explicit QSGAngledDirection(QObject *parent = 0); + const QPointF &sample(const QPointF &from); + qreal angle() const + { + return m_angle; + } + + qreal magnitude() const + { + return m_magnitude; + } + + qreal angleVariation() const + { + return m_angleVariation; + } + + qreal magnitudeVariation() const + { + return m_magnitudeVariation; + } + +signals: + + void angleChanged(qreal arg); + + void magnitudeChanged(qreal arg); + + void angleVariationChanged(qreal arg); + + void magnitudeVariationChanged(qreal arg); + +public slots: +void setAngle(qreal arg) +{ + if (m_angle != arg) { + m_angle = arg; + emit angleChanged(arg); + } +} + +void setMagnitude(qreal arg) +{ + if (m_magnitude != arg) { + m_magnitude = arg; + emit magnitudeChanged(arg); + } +} + +void setAngleVariation(qreal arg) +{ + if (m_angleVariation != arg) { + m_angleVariation = arg; + emit angleVariationChanged(arg); + } +} + +void setMagnitudeVariation(qreal arg) +{ + if (m_magnitudeVariation != arg) { + m_magnitudeVariation = arg; + emit magnitudeVariationChanged(arg); + } +} + +private: +qreal m_angle; +qreal m_magnitude; +qreal m_angleVariation; +qreal m_magnitudeVariation; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // QSGANGLEDDIRECTION_H diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp new file mode 100644 index 0000000000..808ff1c427 --- /dev/null +++ b/src/declarative/particles/qsgcustomparticle.cpp @@ -0,0 +1,581 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgcustomparticle_p.h" +#include +#include + +QT_BEGIN_NAMESPACE +/* + "uniform highp mat4 qt_ModelViewProjectionMatrix; \n" + "attribute highp vec4 qt_Vertex; \n" + "attribute highp vec2 qt_MultiTexCoord0; \n" + "varying highp vec2 qt_TexCoord0; \n" + "void main() { \n" + " qt_TexCoord0 = qt_MultiTexCoord0; \n" + " gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; \n" + "}"; +*/ +//Includes comments because the code isn't self explanatory +static const char qt_particles_default_vertex_code[] = + "attribute highp vec2 vPos; \n" + "attribute highp vec2 vTex; \n" + "attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize \n" + "attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration \n" + "uniform highp mat4 qt_ModelViewProjectionMatrix; \n" + "uniform highp float timestamp; \n" + "varying highp vec2 fTex; \n" + "void main() { \n" + " fTex = vTex; \n" + " highp float size = vData.z; \n" + " highp float endSize = vData.w; \n" + " highp float t = (timestamp - vData.x) / vData.y; \n" + " highp float currentSize = mix(size, endSize, t * t); \n" + " if (t < 0. || t > 1.) \n" + " currentSize = 0.; \n" + " highp vec2 pos = vPos \n" + " - currentSize / 2. + currentSize * vTex // adjust size \n" + " + vVec.xy * t * vData.y // apply speed vector.. \n" + " + 0.5 * vVec.zw * pow(t * vData.y, 2.); \n" + " gl_Position = qt_ModelViewProjectionMatrix * vec4(pos.x, pos.y, 0, 1); \n" + "}"; + +static const char qt_particles_default_fragment_code[] =//TODO: Default frag requires source? + "uniform sampler2D source; \n" + "varying highp vec2 fTex; \n" + "uniform lowp float qt_Opacity; \n" + "void main() { \n" + " gl_FragColor = texture2D(source, fTex) * qt_Opacity; \n" + "}"; + +/* +static const char qt_particles_default_vertex_code[] = + "attribute highp vec2 vPos; \n" + "attribute highp vec2 vTex; \n" + "uniform highp mat4 qt_ModelViewProjectionMatrix; \n" + "void main() { \n" + " highp float currentSize = 1000.0; \n" + " highp vec2 pos = vec2(100.0,100.0) \n" + " - currentSize / 2. + currentSize * vTex; // adjust size \n" + " gl_Position = qt_ModelViewProjectionMatrix * vec4(pos.x, pos.y, 0, 1); \n" + "}"; +static const char qt_particles_default_fragment_code[] =//TODO: Default frag requires source? + "void main() { \n" + " gl_FragColor = vec4(0,255,0,255); \n" + "}"; +*/ + +static const char qt_position_attribute_name[] = "qt_Vertex"; +static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0"; + +static QSGGeometry::Attribute PlainParticle_Attributes[] = { + { 0, 2, GL_FLOAT }, // Position + { 1, 2, GL_FLOAT }, // TexCoord + { 2, 4, GL_FLOAT }, // Data + { 3, 4, GL_FLOAT }, // Vectors + { 4, 1, GL_FLOAT } // r +}; + +static QSGGeometry::AttributeSet PlainParticle_AttributeSet = +{ + 5, // Attribute Count + (2 + 2 + 4 + 4 + 1) * sizeof(float), + PlainParticle_Attributes +}; + +struct PlainVertex { + float x; + float y; + float tx; + float ty; + float t; + float lifeSpan; + float size; + float endSize; + float sx; + float sy; + float ax; + float ay; + float r; +}; + +struct PlainVertices { + PlainVertex v1; + PlainVertex v2; + PlainVertex v3; + PlainVertex v4; +}; + +QSGCustomParticle::QSGCustomParticle(QSGItem* parent) + : QSGParticlePainter(parent) + , m_pleaseReset(true) + , m_dirtyData(true) +{ + setFlag(QSGItem::ItemHasContents); +} + +void QSGCustomParticle::componentComplete() +{ + reset(); + QSGParticlePainter::componentComplete(); +} + + +//Trying to keep the shader conventions the same as in qsgshadereffectitem +/*! + \qmlproperty string CustomParticle::fragmentShader + + This property holds the fragment shader's GLSL source code. + The default shader passes the texture coordinate along to the fragment + shader as "varying highp vec2 qt_TexCoord0". +*/ + +void QSGCustomParticle::setFragmentShader(const QByteArray &code) +{ + if (m_source.fragmentCode.constData() == code.constData()) + return; + m_source.fragmentCode = code; + if (isComponentComplete()) { + reset(); + } + emit fragmentShaderChanged(); +} + +/*! + \qmlproperty string CustomParticle::vertexShader + + This property holds the vertex shader's GLSL source code. + The default shader expects the texture coordinate to be passed from the + vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a + sampler2D named "source". +*/ + +void QSGCustomParticle::setVertexShader(const QByteArray &code) +{ + if (m_source.vertexCode.constData() == code.constData()) + return; + m_source.vertexCode = code; + if (isComponentComplete()) { + reset(); + } + emit vertexShaderChanged(); +} + +void QSGCustomParticle::setCount(int c) +{ + QSGParticlePainter::setCount(c); + m_pleaseReset = true; +} + +void QSGCustomParticle::reset() +{ + disconnectPropertySignals(); + + m_source.attributeNames.clear(); + m_source.uniformNames.clear(); + m_source.respectsOpacity = false; + m_source.respectsMatrix = false; + m_source.className = metaObject()->className(); + + for (int i = 0; i < m_sources.size(); ++i) { + const SourceData &source = m_sources.at(i); + delete source.mapper; + if (source.item && source.item->parentItem() == this) + source.item->setParentItem(0); + } + m_sources.clear(); + + QSGParticlePainter::reset(); + m_pleaseReset = true; +} + + +void QSGCustomParticle::changeSource(int index) +{ + Q_ASSERT(index >= 0 && index < m_sources.size()); + QVariant v = property(m_sources.at(index).name.constData()); + setSource(v, index); +} + +void QSGCustomParticle::updateData() +{ + m_dirtyData = true; + update(); +} + +void QSGCustomParticle::setSource(const QVariant &var, int index) +{ + Q_ASSERT(index >= 0 && index < m_sources.size()); + + SourceData &source = m_sources[index]; + + source.item = 0; + if (var.isNull()) { + return; + } else if (!qVariantCanConvert(var)) { + qWarning("Could not assign source of type '%s' to property '%s'.", var.typeName(), source.name.constData()); + return; + } + + QObject *obj = qVariantValue(var); + + QSGTextureProvider *int3rface = QSGTextureProvider::from(obj); + if (!int3rface) { + qWarning("Could not assign property '%s', did not implement QSGTextureProvider.", source.name.constData()); + } + + source.item = qobject_cast(obj); + + // TODO: Copy better solution in QSGShaderEffectItem when they find it. + // 'source.item' needs a canvas to get a scenegraph node. + // The easiest way to make sure it gets a canvas is to + // make it a part of the same item tree as 'this'. + if (source.item && source.item->parentItem() == 0) { + source.item->setParentItem(this); + source.item->setVisible(false); + } +} + +void QSGCustomParticle::disconnectPropertySignals() +{ + disconnect(this, 0, this, SLOT(updateData())); + for (int i = 0; i < m_sources.size(); ++i) { + SourceData &source = m_sources[i]; + disconnect(this, 0, source.mapper, 0); + disconnect(source.mapper, 0, this, 0); + } +} + +void QSGCustomParticle::connectPropertySignals() +{ + QSet::const_iterator it; + for (it = m_source.uniformNames.begin(); it != m_source.uniformNames.end(); ++it) { + int pi = metaObject()->indexOfProperty(it->constData()); + if (pi >= 0) { + QMetaProperty mp = metaObject()->property(pi); + if (!mp.hasNotifySignal()) + qWarning("QSGShaderEffectItem: property '%s' does not have notification method!", it->constData()); + QByteArray signalName("2"); + signalName.append(mp.notifySignal().signature()); + connect(this, signalName, this, SLOT(updateData())); + } else { + qWarning("QSGShaderEffectItem: '%s' does not have a matching property!", it->constData()); + } + } + for (int i = 0; i < m_sources.size(); ++i) { + SourceData &source = m_sources[i]; + int pi = metaObject()->indexOfProperty(source.name.constData()); + if (pi >= 0) { + QMetaProperty mp = metaObject()->property(pi); + QByteArray signalName("2"); + signalName.append(mp.notifySignal().signature()); + connect(this, signalName, source.mapper, SLOT(map())); + source.mapper->setMapping(this, i); + connect(source.mapper, SIGNAL(mapped(int)), this, SLOT(changeSource(int))); + } else { + qWarning("QSGShaderEffectItem: '%s' does not have a matching source!", source.name.constData()); + } + } +} + +void QSGCustomParticle::updateProperties() +{ + QByteArray vertexCode = m_source.vertexCode; + QByteArray fragmentCode = m_source.fragmentCode; + if (vertexCode.isEmpty()) + vertexCode = qt_particles_default_vertex_code; + if (fragmentCode.isEmpty()) + fragmentCode = qt_particles_default_fragment_code; + + m_source.attributeNames.clear(); + m_source.attributeNames << "vPos" << "vTex" << "vData" << "vVec" << "r"; + + lookThroughShaderCode(vertexCode); + lookThroughShaderCode(fragmentCode); + + if (!m_source.attributeNames.contains(qt_position_attribute_name)) + qWarning("QSGShaderEffectItem: Missing reference to \'%s\'.", qt_position_attribute_name); + if (!m_source.attributeNames.contains(qt_texcoord_attribute_name)) + qWarning("QSGShaderEffectItem: Missing reference to \'%s\'.", qt_texcoord_attribute_name); + if (!m_source.respectsMatrix) + qWarning("QSGShaderEffectItem: Missing reference to \'qt_ModelViewProjectionMatrix\'."); + if (!m_source.respectsOpacity) + qWarning("QSGShaderEffectItem: Missing reference to \'qt_Opacity\'."); + + for (int i = 0; i < m_sources.size(); ++i) { + QVariant v = property(m_sources.at(i).name); + setSource(v, i); + } + + connectPropertySignals(); +} + +void QSGCustomParticle::lookThroughShaderCode(const QByteArray &code) +{ + // Regexp for matching attributes and uniforms. + // In human readable form: attribute|uniform [lowp|mediump|highp] + static QRegExp re(QLatin1String("\\b(attribute|uniform)\\b\\s*\\b(?:lowp|mediump|highp)?\\b\\s*\\b(\\w+)\\b\\s*\\b(\\w+)")); + Q_ASSERT(re.isValid()); + + int pos = -1; + + QString wideCode = QString::fromLatin1(code.constData(), code.size()); + + while ((pos = re.indexIn(wideCode, pos + 1)) != -1) { + QByteArray decl = re.cap(1).toLatin1(); // uniform or attribute + QByteArray type = re.cap(2).toLatin1(); // type + QByteArray name = re.cap(3).toLatin1(); // variable name + + if (decl == "attribute") { + if(!m_source.attributeNames.contains(name))//TODO: Can they add custom attributes? + qWarning() << "Custom Particle: Unknown attribute " << name; + } else { + Q_ASSERT(decl == "uniform");//TODO: Shouldn't assert + + if (name == "qt_ModelViewProjectionMatrix") { + m_source.respectsMatrix = true; + } else if (name == "qt_Opacity") { + m_source.respectsOpacity = true; + } else if (name == "timestamp") { + //TODO: Copy the whole thing just because I have one more uniform? + } else { + m_source.uniformNames.insert(name); + if (type == "sampler2D") { + SourceData d; + d.mapper = new QSignalMapper; + d.name = name; + d.item = 0; + m_sources.append(d); + } + } + } + } +} + +QSGNode *QSGCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + if(m_pleaseReset){ + if(m_node) + delete m_node; + //delete m_material;//Shader effect item doesn't regen material? + + m_node = 0; + m_pleaseReset = false; + m_dirtyData = false; + } + + if(m_system && m_system->isRunning()) + prepareNextFrame(); + if (m_node){ + if(oldNode) + Q_ASSERT(oldNode == m_node); + update(); + m_node->markDirty(QSGNode::DirtyMaterial); //done in buildData? + } + + return m_node; +} + +void QSGCustomParticle::prepareNextFrame(){ + if(!m_node) + m_node = buildCustomNode(); + if(!m_node) + return; + + m_lastTime = m_system->systemSync(this) / 1000.; + if(m_dirtyData || true)//Currently this is how we update timestamp... potentially over expensive. + buildData(); +} + +QSGShaderEffectNode* QSGCustomParticle::buildCustomNode() +{ + if (m_count * 4 > 0xffff) { + printf("CustomParticle: Too many particles... \n");//####Why is this here? + return 0; + } + + if(m_count <= 0) { + printf("CustomParticle: Too few particles... \n"); + return 0; + } + + + //Create Particle Geometry + int vCount = m_count * 4; + int iCount = m_count * 6; + QSGGeometry *g = new QSGGeometry(PlainParticle_AttributeSet, vCount, iCount); + g->setDrawingMode(GL_TRIANGLES); + PlainVertex *vertices = (PlainVertex *) g->vertexData(); + for (int p=0; pindexDataAsUShort(); + for (int i=0; isetGeometry(g); + node->setMaterial(&m_material); + + /* + //For debugging, just use grid vertices like ShaderEffect + node->setGeometry(0); + QSGShaderEffectMesh* mesh = new QSGGridMesh(); + node->setFlag(QSGNode::OwnsGeometry, false); + + qDebug() << m_source.attributeNames; + QSGGeometry* geometry = node->geometry(); + geometry = mesh->updateGeometry(geometry, m_source.attributeNames, QRectF(0,0,width(),height())); + if(!geometry) + qDebug() << "Should have written the error handling"; + else + qDebug() << "Mesh Loaded"; + node->setGeometry(geometry); + qDebug() << QString("INIT") << geometry << (QObject*)node; + node->setFlag(QSGNode::OwnsGeometry, true); + */ + QSGShaderEffectProgram s = m_source; + if (s.fragmentCode.isEmpty()) + s.fragmentCode = qt_particles_default_fragment_code; + if (s.vertexCode.isEmpty()) + s.vertexCode = qt_particles_default_vertex_code; + m_material.setProgramSource(s); + node->markDirty(QSGNode::DirtyMaterial); + node->markDirty(QSGNode::DirtyAll); + return node; +} + +static const QByteArray timestampName("timestamp"); + +void QSGCustomParticle::buildData() +{ + if(!m_node)//Operates on m_node + return; + QVector > values; + QVector > > textures; + const QVector > > &oldTextures = m_material.textureProviders(); + + for (QSet::const_iterator it = m_source.uniformNames.begin(); + it != m_source.uniformNames.end(); ++it) { + values.append(qMakePair(*it, property(*it))); + } + for (int i = 0; i < oldTextures.size(); ++i) { + QSGTextureProvider *oldSource = QSGTextureProvider::from(oldTextures.at(i).second); + if (oldSource && oldSource->textureChangedSignal()) + disconnect(oldTextures.at(i).second, oldSource->textureChangedSignal(), m_node, SLOT(markDirtyTexture())); + } + for (int i = 0; i < m_sources.size(); ++i) { + const SourceData &source = m_sources.at(i); + textures.append(qMakePair(source.name, source.item)); + QSGTextureProvider *t = QSGTextureProvider::from(source.item); + if (t && t->textureChangedSignal()) + connect(source.item, t->textureChangedSignal(), m_node, SLOT(markDirtyTexture()), Qt::DirectConnection); + } + values.append(qMakePair(timestampName, QVariant(m_lastTime))); + m_material.setUniforms(values); + m_material.setTextureProviders(textures); + m_node->markDirty(QSGNode::DirtyMaterial); + m_dirtyData = false; +} + +void QSGCustomParticle::load(QSGParticleData *d) +{ + reload(d);//We don't do anything special in C++ here. +} + +void QSGCustomParticle::reload(QSGParticleData *d) +{ + if (m_node == 0) + return; + + PlainVertices *particles = (PlainVertices *) m_node->geometry()->vertexData(); + + int pos = particleTypeIndex(d); + + PlainVertices &p = particles[pos]; + + //Perhaps we could be more efficient? + vertexCopy(p.v1, d->pv); + vertexCopy(p.v2, d->pv); + vertexCopy(p.v3, d->pv); + vertexCopy(p.v4, d->pv); + +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgcustomparticle_p.h b/src/declarative/particles/qsgcustomparticle_p.h new file mode 100644 index 0000000000..95144ef638 --- /dev/null +++ b/src/declarative/particles/qsgcustomparticle_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOM_PARTICLE_H +#define CUSTOM_PARTICLE_H +#include "qsgparticlepainter_p.h" +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGNode; + +//Genealogy: Hybrid of UltraParticle and ShaderEffectItem +class QSGCustomParticle : public QSGParticlePainter +{ + Q_OBJECT + Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged) + Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged) + +public: + explicit QSGCustomParticle(QSGItem* parent=0); + virtual void load(QSGParticleData*); + virtual void reload(QSGParticleData*); + virtual void setCount(int c); + + QByteArray fragmentShader() const { return m_source.fragmentCode; } + void setFragmentShader(const QByteArray &code); + + QByteArray vertexShader() const { return m_source.vertexCode; } + void setVertexShader(const QByteArray &code); +public Q_SLOTS: + void updateData(); + void changeSource(int); +Q_SIGNALS: + void fragmentShaderChanged(); + void vertexShaderChanged(); +protected: + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + void prepareNextFrame(); + void setSource(const QVariant &var, int index); + void disconnectPropertySignals(); + void connectPropertySignals(); + void reset(); + void updateProperties(); + void lookThroughShaderCode(const QByteArray &code); + virtual void componentComplete(); + QSGShaderEffectNode *buildCustomNode(); + +private: + void buildData(); + + bool m_pleaseReset; + bool m_dirtyData; + QSGShaderEffectProgram m_source; + struct SourceData + { + QSignalMapper *mapper; + QPointer item; + QByteArray name; + }; + QVector m_sources; + QSGShaderEffectMaterial m_material; + QSGShaderEffectNode* m_node; + qreal m_lastTime; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //HEADER_GUARD diff --git a/src/declarative/particles/qsgellipseextruder.cpp b/src/declarative/particles/qsgellipseextruder.cpp new file mode 100644 index 0000000000..76925895b9 --- /dev/null +++ b/src/declarative/particles/qsgellipseextruder.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgellipseextruder_p.h" +#include +QT_BEGIN_NAMESPACE +QSGEllipseExtruder::QSGEllipseExtruder(QObject *parent) : + QSGParticleExtruder(parent) + , m_fill(true) +{ +} + +QPointF QSGEllipseExtruder::extrude(const QRectF & r) +{ + qreal theta = ((qreal)rand()/RAND_MAX) * 6.2831853071795862; + qreal mag = m_fill ? ((qreal)rand()/RAND_MAX) : 1; + return QPointF(r.x() + r.width()/2 + mag * (r.width()/2) * cos(theta), + r.y() + r.height()/2 + mag * (r.height()/2) * sin(theta)); +} + +bool QSGEllipseExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + return bounds.contains(point);//TODO: Ellipse +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgellipseextruder_p.h b/src/declarative/particles/qsgellipseextruder_p.h new file mode 100644 index 0000000000..9f770a7ee6 --- /dev/null +++ b/src/declarative/particles/qsgellipseextruder_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ELLIPSEEXTRUDER_H +#define ELLIPSEEXTRUDER_H +#include "qsgparticleextruder_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGEllipseExtruder : public QSGParticleExtruder +{ + Q_OBJECT + Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box +public: + explicit QSGEllipseExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point); + + bool fill() const + { + return m_fill; + } + +signals: + + void fillChanged(bool arg); + +public slots: + + void setFill(bool arg) + { + if (m_fill != arg) { + m_fill = arg; + emit fillChanged(arg); + } + } +private: + bool m_fill; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // ELLIPSEEXTRUDER_H diff --git a/src/declarative/particles/qsgemitter.cpp b/src/declarative/particles/qsgemitter.cpp new file mode 100644 index 0000000000..081dd8dec5 --- /dev/null +++ b/src/declarative/particles/qsgemitter.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgemitter_p.h" +#include "qsgparticlesystem_p.h" +#include "qsgparticlepainter_p.h"//TODO: What was this for again? +QT_BEGIN_NAMESPACE + +QSGBasicEmitter::QSGBasicEmitter(QSGItem* parent) + : QSGParticleEmitter(parent) + , m_speed_from_movement(0) + , m_particle_count(0) + , m_reset_last(true) + , m_last_timestamp(0) + , m_last_emission(0) +{ +// setFlag(ItemHasContents); +} + +void QSGBasicEmitter::setSpeedFromMovement(qreal t) +{ + if (t == m_speed_from_movement) + return; + m_speed_from_movement = t; + emit speedFromMovementChanged(); +} + +void QSGBasicEmitter::reset() +{ + m_reset_last = true; +} + +void QSGBasicEmitter::emitWindow(int timeStamp) +{ + if (m_system == 0) + return; + if((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && m_burstQueue.isEmpty()){ + m_reset_last = true; + return; + } + + if (m_reset_last) { + m_last_emitter = m_last_last_emitter = QPointF(x(), y()); + m_last_timestamp = timeStamp/1000.; + m_last_emission = m_last_timestamp; + m_reset_last = false; + } + + if(m_burstLeft){ + m_burstLeft -= timeStamp - m_last_timestamp * 1000.; + if(m_burstLeft < 0){ + if(!m_emitting) + timeStamp += m_burstLeft; + m_burstLeft = 0; + } + } + + qreal time = timeStamp / 1000.; + + qreal particleRatio = 1. / m_particlesPerSecond; + qreal pt = m_last_emission; + + qreal opt = pt; // original particle time + qreal dt = time - m_last_timestamp; // timestamp delta... + if(!dt) + dt = 0.000001; + + // emitter difference since last... + qreal dex = (x() - m_last_emitter.x()); + qreal dey = (y() - m_last_emitter.y()); + + qreal ax = (m_last_last_emitter.x() + m_last_emitter.x()) / 2; + qreal bx = m_last_emitter.x(); + qreal cx = (x() + m_last_emitter.x()) / 2; + qreal ay = (m_last_last_emitter.y() + m_last_emitter.y()) / 2; + qreal by = m_last_emitter.y(); + qreal cy = (y() + m_last_emitter.y()) / 2; + + qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; + qreal emitter_x_offset = m_last_emitter.x() - x(); + qreal emitter_y_offset = m_last_emitter.y() - y(); + if(!m_burstQueue.isEmpty() && !m_burstLeft && !m_emitting)//'outside time' emissions only + pt = time; + while (pt < time || !m_burstQueue.isEmpty()) { + //int pos = m_last_particle % m_particle_count; + QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle]); + if(datum){//actually emit(otherwise we've been asked to skip this one) + datum->e = this;//###useful? + ParticleVertex &p = datum->pv; + qreal t = 1 - (pt - opt) / dt; + qreal vx = + - 2 * ax * (1 - t) + + 2 * bx * (1 - 2 * t) + + 2 * cx * t; + qreal vy = + - 2 * ay * (1 - t) + + 2 * by * (1 - 2 * t) + + 2 * cy * t; + + + // Particle timestamp + p.t = pt; + p.lifeSpan = //TODO:Promote to base class? + (m_particleDuration + + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) + / 1000.0; + + // Particle position + QRectF boundsRect; + if(!m_burstQueue.isEmpty()){ + boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(), + width(), height()); + } else { + boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt + , width(), height()); + } + QPointF newPos = effectiveExtruder()->extrude(boundsRect); + p.x = newPos.x(); + p.y = newPos.y(); + + // Particle speed + const QPointF &speed = m_speed->sample(newPos); + p.sx = speed.x() + + m_speed_from_movement * vx; + p.sy = speed.y() + + m_speed_from_movement * vy; + + // Particle acceleration + const QPointF &accel = m_acceleration->sample(newPos); + p.ax = accel.x(); + p.ay = accel.y(); + + // Particle size + float sizeVariation = -m_particleSizeVariation + + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; + + float size = qMax((qreal)0.0 , m_particleSize + sizeVariation); + float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation); + + p.size = size;// * float(m_emitting); + p.endSize = endSize;// * float(m_emitting); + + m_system->emitParticle(datum); + } + if(m_burstQueue.isEmpty()){ + pt += particleRatio; + }else{ + m_burstQueue.first().first--; + if(m_burstQueue.first().first <= 0) + m_burstQueue.pop_front(); + } + } + m_last_emission = pt; + + m_last_last_last_emitter = m_last_last_emitter; + m_last_last_emitter = m_last_emitter; + m_last_emitter = QPointF(x(), y()); + m_last_timestamp = time; +} + + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgemitter_p.h b/src/declarative/particles/qsgemitter_p.h new file mode 100644 index 0000000000..3988c71cdf --- /dev/null +++ b/src/declarative/particles/qsgemitter_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TRAILSEMITTER_H +#define TRAILSEMITTER_H + +#include +#include + +#include "qsgparticleemitter_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGGeometryNode; + +class QSGBasicEmitter : public QSGParticleEmitter +{ + Q_OBJECT + + Q_PROPERTY(qreal speedFromMovement READ speedFromMovement WRITE setSpeedFromMovement NOTIFY speedFromMovementChanged) + +public: + explicit QSGBasicEmitter(QSGItem* parent=0); + virtual ~QSGBasicEmitter(){} + virtual void emitWindow(int timeStamp); + + + qreal speedFromMovement() const { return m_speed_from_movement; } + void setSpeedFromMovement(qreal s); + + qreal renderOpacity() const { return m_render_opacity; } + +signals: + + void speedFromMovementChanged(); + +public slots: +public: + virtual void reset(); +protected: + +private: + + qreal m_speed_from_movement; + + // derived values... + int m_particle_count; + bool m_reset_last; + qreal m_last_timestamp; + qreal m_last_emission; + + QPointF m_last_emitter; + QPointF m_last_last_emitter; + QPointF m_last_last_last_emitter; + + qreal m_render_opacity; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // TRAILSEMITTER_H diff --git a/src/declarative/particles/qsgfollowemitter.cpp b/src/declarative/particles/qsgfollowemitter.cpp new file mode 100644 index 0000000000..442cff9ec8 --- /dev/null +++ b/src/declarative/particles/qsgfollowemitter.cpp @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgfollowemitter_p.h" +#include "qsgparticlepainter_p.h"//TODO: What was this for again? +#include +QT_BEGIN_NAMESPACE + +QSGFollowEmitter::QSGFollowEmitter(QSGItem *parent) : + QSGParticleEmitter(parent) + , m_particlesPerParticlePerSecond(0) + , m_lastTimeStamp(0) + , m_emitterXVariation(0) + , m_emitterYVariation(0) + , m_followCount(0) + , m_emissionExtruder(0) + , m_defaultEmissionExtruder(new QSGParticleExtruder(this)) +{ + connect(this, SIGNAL(followChanged(QString)), + this, SLOT(recalcParticlesPerSecond())); + connect(this, SIGNAL(particleDurationChanged(int)), + this, SLOT(recalcParticlesPerSecond())); + connect(this, SIGNAL(particlesPerParticlePerSecondChanged(int)), + this, SLOT(recalcParticlesPerSecond())); +} + +void QSGFollowEmitter::recalcParticlesPerSecond(){ + if(!m_system) + return; + m_followCount = m_system->m_groupData[m_system->m_groupIds[m_follow]]->size; + if(!m_followCount){ + setParticlesPerSecond(1000);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS) + }else{ + setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount); + m_lastEmission.resize(m_followCount); + m_lastEmission.fill(0); + } +} + +void QSGFollowEmitter::reset() +{ + m_followCount = 0; +} + +void QSGFollowEmitter::emitWindow(int timeStamp) +{ + if (m_system == 0) + return; + if(!m_emitting && !m_burstLeft && m_burstQueue.isEmpty()) + return; + if(m_followCount != m_system->m_groupData[m_system->m_groupIds[m_follow]]->size){ + qreal oldPPS = m_particlesPerSecond; + recalcParticlesPerSecond(); + if(m_particlesPerSecond != oldPPS) + return;//system may need to update + } + + if(m_burstLeft){ + m_burstLeft -= timeStamp - m_lastTimeStamp * 1000.; + if(m_burstLeft < 0){ + timeStamp += m_burstLeft; + m_burstLeft = 0; + } + } + + qreal time = timeStamp / 1000.; + qreal particleRatio = 1. / m_particlesPerParticlePerSecond; + qreal pt; + + //Have to map it into this system, because particlesystem automaps it back + QPointF offset = m_system->mapFromItem(this, QPointF(0, 0)); + qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; + + int gId = m_system->m_groupIds[m_follow]; + int gId2 = m_system->m_groupIds[m_particle]; + for(int i=0; im_groupData[gId]->size; i++){ + pt = m_lastEmission[i]; + QSGParticleData* d = m_system->m_data[i + m_system->m_groupData[gId]->start]; + if(!d || !d->stillAlive()) + continue; + if(pt < d->pv.t) + pt = d->pv.t; + + if(!effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),QPointF(d->curX(), d->curY()))){ + m_lastEmission[i] = time;//jump over this time period without emitting, because it's outside + continue; + } + while(pt < time || !m_burstQueue.isEmpty()){ + QSGParticleData* datum = m_system->newDatum(gId2); + if(datum){//else, skip this emission + datum->e = this;//###useful? + ParticleVertex &p = datum->pv; + + // Particle timestamp + p.t = pt; + p.lifeSpan = + (m_particleDuration + + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) + / 1000.0; + + // Particle position + // Note that burst location doesn't get used for follow emitter + qreal followT = pt - d->pv.t; + qreal followT2 = followT * followT * 0.5; + qreal sizeOffset = d->pv.size/2;//TODO: Current size? As an option + //TODO: Set variations + //Subtract offset, because PS expects this in emitter coordinates + QRectF boundsRect(d->pv.x - offset.x() + d->pv.sx * followT + d->pv.ax * followT2 - m_emitterXVariation/2, + d->pv.y - offset.y() + d->pv.sy * followT + d->pv.ay * followT2 - m_emitterYVariation/2, + m_emitterXVariation, + m_emitterYVariation); + // QRectF boundsRect(d->pv.x + d->pv.sx * followT + d->pv.ax * followT2 + offset.x() - sizeOffset, + // d->pv.y + d->pv.sy * followT + d->pv.ay * followT2 + offset.y() - sizeOffset, + // sizeOffset*2, + // sizeOffset*2); + + QSGParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder; + const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect); + p.x = newPos.x(); + p.y = newPos.y(); + + // Particle speed + const QPointF &speed = m_speed->sample(newPos); + p.sx = speed.x(); + p.sy = speed.y(); + + // Particle acceleration + const QPointF &accel = m_acceleration->sample(newPos); + p.ax = accel.x(); + p.ay = accel.y(); + + // Particle size + float sizeVariation = -m_particleSizeVariation + + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; + + float size = qMax((qreal)0.0, m_particleSize + sizeVariation); + float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation); + + p.size = size * float(m_emitting); + p.endSize = endSize * float(m_emitting); + + m_system->emitParticle(datum); + } + if(!m_burstQueue.isEmpty()){ + m_burstQueue.first().first--; + if(m_burstQueue.first().first <= 0) + m_burstQueue.pop_front(); + }else{ + pt += particleRatio; + } + } + m_lastEmission[i] = pt; + } + + m_lastTimeStamp = time; +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgfollowemitter_p.h b/src/declarative/particles/qsgfollowemitter_p.h new file mode 100644 index 0000000000..314bd4e7c1 --- /dev/null +++ b/src/declarative/particles/qsgfollowemitter_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FOLLOWEMITTER_H +#define FOLLOWEMITTER_H +#include "qsgparticleemitter_p.h" +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGFollowEmitter : public QSGParticleEmitter +{ + Q_OBJECT + Q_PROPERTY(QString follow READ follow WRITE setFollow NOTIFY followChanged) + //### Remove, and just document that particles per second is per particle? But has count issues + Q_PROPERTY(int particlesPerParticlePerSecond READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged) + + //TODO: Document that FollowEmitter's box is where it follows. It emits in a rect centered on the followed particle + //TODO: A set of properties that can involve the particle size of the followed + Q_PROPERTY(QSGParticleExtruder* emissionShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged) + Q_PROPERTY(qreal emissionHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) + Q_PROPERTY(qreal emissionWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) + +public: + explicit QSGFollowEmitter(QSGItem *parent = 0); + virtual void emitWindow(int timeStamp); + virtual void reset(); + + int particlesPerParticlePerSecond() const + { + return m_particlesPerParticlePerSecond; + } + + qreal emitterXVariation() const + { + return m_emitterXVariation; + } + + qreal emitterYVariation() const + { + return m_emitterYVariation; + } + + QString follow() const + { + return m_follow; + } + + QSGParticleExtruder* emissonShape() const + { + return m_emissionExtruder; + } + +signals: + + void particlesPerParticlePerSecondChanged(int arg); + + void emitterXVariationChanged(qreal arg); + + void emitterYVariationChanged(qreal arg); + + void followChanged(QString arg); + + void emissionShapeChanged(QSGParticleExtruder* arg); + +public slots: + + void setParticlesPerParticlePerSecond(int arg) + { + if (m_particlesPerParticlePerSecond != arg) { + m_particlesPerParticlePerSecond = arg; + emit particlesPerParticlePerSecondChanged(arg); + } + } + void setEmitterXVariation(qreal arg) + { + if (m_emitterXVariation != arg) { + m_emitterXVariation = arg; + emit emitterXVariationChanged(arg); + } + } + + void setEmitterYVariation(qreal arg) + { + if (m_emitterYVariation != arg) { + m_emitterYVariation = arg; + emit emitterYVariationChanged(arg); + } + } + + void setFollow(QString arg) + { + if (m_follow != arg) { + m_follow = arg; + emit followChanged(arg); + } + } + + void setEmissionShape(QSGParticleExtruder* arg) + { + if (m_emissionExtruder != arg) { + m_emissionExtruder = arg; + emit emissionShapeChanged(arg); + } + } + +private slots: + void recalcParticlesPerSecond(); + +private: + QSet m_pending; + QVector m_lastEmission; + int m_particlesPerParticlePerSecond; + qreal m_lastTimeStamp; + qreal m_emitterXVariation; + qreal m_emitterYVariation; + QString m_follow; + int m_followCount; + QSGParticleExtruder* m_emissionExtruder; + QSGParticleExtruder* m_defaultEmissionExtruder; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // FOLLOWEMITTER_H diff --git a/src/declarative/particles/qsgfriction.cpp b/src/declarative/particles/qsgfriction.cpp new file mode 100644 index 0000000000..828d20556d --- /dev/null +++ b/src/declarative/particles/qsgfriction.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgfriction_p.h" +QT_BEGIN_NAMESPACE +QSGFrictionAffector::QSGFrictionAffector(QSGItem *parent) : + QSGParticleAffector(parent), m_factor(0.0) +{ +} + +bool QSGFrictionAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + if(!m_factor) + return false; + qreal curSX = d->curSX(); + qreal curSY = d->curSY(); + d->setInstantaneousSX(curSX + (curSX * m_factor * -1 * dt)); + d->setInstantaneousSY(curSY + (curSY * m_factor * -1 * dt)); + return true; +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgfriction_p.h b/src/declarative/particles/qsgfriction_p.h new file mode 100644 index 0000000000..6b5a86f3f2 --- /dev/null +++ b/src/declarative/particles/qsgfriction_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FRICTIONAFFECTOR_H +#define FRICTIONAFFECTOR_H +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGFrictionAffector : public QSGParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged) +public: + explicit QSGFrictionAffector(QSGItem *parent = 0); + + qreal factor() const + { + return m_factor; + } +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +signals: + + void factorChanged(qreal arg); + +public slots: + +void setFactor(qreal arg) +{ + if (m_factor != arg) { + m_factor = arg; + emit factorChanged(arg); + } +} + +private: +qreal m_factor; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // FRICTIONAFFECTOR_H diff --git a/src/declarative/particles/qsggravity.cpp b/src/declarative/particles/qsggravity.cpp new file mode 100644 index 0000000000..de735da5ad --- /dev/null +++ b/src/declarative/particles/qsggravity.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsggravity_p.h" +#include +QT_BEGIN_NAMESPACE +const qreal CONV = 0.017453292520444443; +QSGGravityAffector::QSGGravityAffector(QSGItem *parent) : + QSGParticleAffector(parent), m_acceleration(-10), m_angle(90), m_xAcc(0), m_yAcc(0) +{ + connect(this, SIGNAL(accelerationChanged(qreal)), + this, SLOT(recalc())); + connect(this, SIGNAL(angleChanged(qreal)), + this, SLOT(recalc())); + recalc(); +} + +void QSGGravityAffector::recalc() +{ + qreal theta = m_angle * CONV; + m_xAcc = m_acceleration * cos(theta); + m_yAcc = m_acceleration * sin(theta); +} + +bool QSGGravityAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + Q_UNUSED(dt); + bool changed = false; + if(d->pv.ax != m_xAcc){ + d->setInstantaneousAX(m_xAcc); + changed = true; + } + if(d->pv.ay != m_yAcc){ + d->setInstantaneousAY(m_yAcc); + changed = true; + } + return changed; +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsggravity_p.h b/src/declarative/particles/qsggravity_p.h new file mode 100644 index 0000000000..57b2511911 --- /dev/null +++ b/src/declarative/particles/qsggravity_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GRAVITYAFFECTOR_H +#define GRAVITYAFFECTOR_H +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGGravityAffector : public QSGParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) +public: + explicit QSGGravityAffector(QSGItem *parent = 0); + qreal acceleration() const + { + return m_acceleration; + } + + qreal angle() const + { + return m_angle; + } +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +signals: + + void accelerationChanged(qreal arg); + + void angleChanged(qreal arg); + +public slots: +void setAcceleration(qreal arg) +{ + if (m_acceleration != arg) { + m_acceleration = arg; + emit accelerationChanged(arg); + } +} + +void setAngle(qreal arg) +{ + if (m_angle != arg) { + m_angle = arg; + emit angleChanged(arg); + } +} + +private slots: + void recalc(); +private: + qreal m_acceleration; + qreal m_angle; + + qreal m_xAcc; + qreal m_yAcc; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // GRAVITYAFFECTOR_H diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp new file mode 100644 index 0000000000..c9df5f4dbd --- /dev/null +++ b/src/declarative/particles/qsgimageparticle.cpp @@ -0,0 +1,993 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "qsgimageparticle_p.h" +#include "qsgparticleemitter_p.h" +#include "qsgsprite_p.h" +#include "qsgspriteengine_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +const float CONV = 0.017453292519943295; +class UltraMaterial : public QSGMaterial +{ +public: + UltraMaterial(bool withSprites=false) + : timestamp(0) + , framecount(1) + , animcount(1) + , usesSprites(withSprites) + { + setFlag(Blending, true); + } + + ~UltraMaterial() + { + delete texture; + delete colortable; + delete sizetable; + delete opacitytable; + } + + virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } + virtual QSGMaterialShader *createShader() const; + virtual int compare(const QSGMaterial *other) const + { + return this - static_cast(other); + } + + QSGTexture *texture; + QSGTexture *colortable; + QSGTexture *sizetable; + QSGTexture *opacitytable; + + qreal timestamp; + int framecount; + int animcount; + bool usesSprites; +}; +class UltraMaterialData : public QSGMaterialShader +{ +public: + UltraMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) + { + QFile vf(vertexFile ? vertexFile : ":defaultshaders/ultravertex.shader"); + vf.open(QFile::ReadOnly); + m_vertex_code = vf.readAll(); + + QFile ff(fragmentFile ? fragmentFile : ":defaultshaders/ultrafragment.shader"); + ff.open(QFile::ReadOnly); + m_fragment_code = ff.readAll(); + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + void deactivate() { + QSGMaterialShader::deactivate(); + + for (int i=0; i<8; ++i) { + program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); + } + } + + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) + { + UltraMaterial *m = static_cast(newEffect); + state.context()->functions()->glActiveTexture(GL_TEXTURE1); + m->colortable->bind(); + program()->setUniformValue(m_colortable_id, 1); + + state.context()->functions()->glActiveTexture(GL_TEXTURE2); + m->sizetable->bind(); + program()->setUniformValue(m_sizetable_id, 2); + + state.context()->functions()->glActiveTexture(GL_TEXTURE3); + m->opacitytable->bind(); + program()->setUniformValue(m_opacitytable_id, 3); + + state.context()->functions()->glActiveTexture(GL_TEXTURE0);//Investigate why this screws up Text{} if placed before 1 + m->texture->bind(); + + program()->setUniformValue(m_opacity_id, state.opacity()); + program()->setUniformValue(m_timestamp_id, (float) m->timestamp); + program()->setUniformValue(m_framecount_id, (float) m->framecount); + program()->setUniformValue(m_animcount_id, (float) m->animcount); + + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); + } + + virtual void initialize() { + m_colortable_id = program()->uniformLocation("colortable"); + m_sizetable_id = program()->uniformLocation("sizetable"); + m_opacitytable_id = program()->uniformLocation("opacitytable"); + m_matrix_id = program()->uniformLocation("matrix"); + m_opacity_id = program()->uniformLocation("opacity"); + m_timestamp_id = program()->uniformLocation("timestamp"); + m_framecount_id = program()->uniformLocation("framecount"); + m_animcount_id = program()->uniformLocation("animcount"); + } + + virtual const char *vertexShader() const { return m_vertex_code.constData(); } + virtual const char *fragmentShader() const { return m_fragment_code.constData(); } + + virtual char const *const *attributeNames() const { + static const char *attr[] = { + "vPos", + "vTex", + "vData", + "vVec", + "vColor", + "vDeformVec", + "vRotation", + "vAnimData", + 0 + }; + return attr; + } + + virtual bool isColorTable() const { return false; } + + int m_matrix_id; + int m_opacity_id; + int m_timestamp_id; + int m_colortable_id; + int m_sizetable_id; + int m_opacitytable_id; + int m_framecount_id; + int m_animcount_id; + + QByteArray m_vertex_code; + QByteArray m_fragment_code; + + static float chunkOfBytes[1024]; +}; +float UltraMaterialData::chunkOfBytes[1024]; + +QSGMaterialShader *UltraMaterial::createShader() const +{ + if(usesSprites)//TODO: Perhaps just swap the shaders, and don't mind the extra vector? + return new UltraMaterialData; + else + return new UltraMaterialData; +} + + +class SimpleMaterial : public UltraMaterial +{ + virtual QSGMaterialShader *createShader() const; + virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } +}; + +class SimpleMaterialData : public QSGMaterialShader +{ +public: + SimpleMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) + { + QFile vf(vertexFile ? vertexFile : ":defaultshaders/simplevertex.shader"); + vf.open(QFile::ReadOnly); + m_vertex_code = vf.readAll(); + + QFile ff(fragmentFile ? fragmentFile : ":defaultshaders/simplefragment.shader"); + ff.open(QFile::ReadOnly); + m_fragment_code = ff.readAll(); + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + void deactivate() { + QSGMaterialShader::deactivate(); + + for (int i=0; i<8; ++i) { + program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); + } + } + + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) + { + UltraMaterial *m = static_cast(newEffect); + state.context()->functions()->glActiveTexture(GL_TEXTURE0); + m->texture->bind(); + + program()->setUniformValue(m_opacity_id, state.opacity()); + program()->setUniformValue(m_timestamp_id, (float) m->timestamp); + + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); + } + + virtual void initialize() { + m_matrix_id = program()->uniformLocation("matrix"); + m_opacity_id = program()->uniformLocation("opacity"); + m_timestamp_id = program()->uniformLocation("timestamp"); + } + + virtual const char *vertexShader() const { return m_vertex_code.constData(); } + virtual const char *fragmentShader() const { return m_fragment_code.constData(); } + + virtual char const *const *attributeNames() const { + static const char *attr[] = { + "vPos", + "vTex", + "vData", + "vVec", + 0 + }; + return attr; + } + + virtual bool isColorTable() const { return false; } + + int m_matrix_id; + int m_opacity_id; + int m_timestamp_id; + + QByteArray m_vertex_code; + QByteArray m_fragment_code; + + static float chunkOfBytes[1024]; +}; +float SimpleMaterialData::chunkOfBytes[1024]; + +QSGMaterialShader *SimpleMaterial::createShader() const { + return new SimpleMaterialData; +} + +QSGImageParticle::QSGImageParticle(QSGItem* parent) + : QSGParticlePainter(parent) + , m_do_reset(false) + , m_color_variation(0.0) + , m_node(0) + , m_material(0) + , m_alphaVariation(0.0) + , m_alpha(1.0) + , m_redVariation(0.0) + , m_greenVariation(0.0) + , m_blueVariation(0.0) + , m_rotation(0) + , m_autoRotation(false) + , m_xVector(0) + , m_yVector(0) + , m_rotationVariation(0) + , m_rotationSpeed(0) + , m_rotationSpeedVariation(0) + , m_spriteEngine(0) + , m_bloat(false) + , perfLevel(Unknown) + , m_lastLevel(Unknown) +{ + setFlag(ItemHasContents); +} + +QDeclarativeListProperty QSGImageParticle::sprites() +{ + return QDeclarativeListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); +} + +void QSGImageParticle::setImage(const QUrl &image) +{ + if (image == m_image_name) + return; + m_image_name = image; + emit imageChanged(); + reset(); +} + + +void QSGImageParticle::setColortable(const QUrl &table) +{ + if (table == m_colortable_name) + return; + m_colortable_name = table; + emit colortableChanged(); + reset(); +} + +void QSGImageParticle::setSizetable(const QUrl &table) +{ + if (table == m_sizetable_name) + return; + m_sizetable_name = table; + emit sizetableChanged(); + reset(); +} + +void QSGImageParticle::setOpacitytable(const QUrl &table) +{ + if (table == m_opacitytable_name) + return; + m_opacitytable_name = table; + emit opacitytableChanged(); + reset(); +} + +void QSGImageParticle::setColor(const QColor &color) +{ + if (color == m_color) + return; + m_color = color; + emit colorChanged(); + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setColorVariation(qreal var) +{ + if (var == m_color_variation) + return; + m_color_variation = var; + emit colorVariationChanged(); + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setAlphaVariation(qreal arg) +{ + if (m_alphaVariation != arg) { + m_alphaVariation = arg; + emit alphaVariationChanged(arg); + } + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setAlpha(qreal arg) +{ + if (m_alpha != arg) { + m_alpha = arg; + emit alphaChanged(arg); + } + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setRedVariation(qreal arg) +{ + if (m_redVariation != arg) { + m_redVariation = arg; + emit redVariationChanged(arg); + } + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setGreenVariation(qreal arg) +{ + if (m_greenVariation != arg) { + m_greenVariation = arg; + emit greenVariationChanged(arg); + } + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setBlueVariation(qreal arg) +{ + if (m_blueVariation != arg) { + m_blueVariation = arg; + emit blueVariationChanged(arg); + } + if(perfLevel < Coloured) + reset(); +} + +void QSGImageParticle::setRotation(qreal arg) +{ + if (m_rotation != arg) { + m_rotation = arg; + emit rotationChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setRotationVariation(qreal arg) +{ + if (m_rotationVariation != arg) { + m_rotationVariation = arg; + emit rotationVariationChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setRotationSpeed(qreal arg) +{ + if (m_rotationSpeed != arg) { + m_rotationSpeed = arg; + emit rotationSpeedChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setRotationSpeedVariation(qreal arg) +{ + if (m_rotationSpeedVariation != arg) { + m_rotationSpeedVariation = arg; + emit rotationSpeedVariationChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setAutoRotation(bool arg) +{ + if (m_autoRotation != arg) { + m_autoRotation = arg; + emit autoRotationChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setXVector(QSGStochasticDirection* arg) +{ + if (m_xVector != arg) { + m_xVector = arg; + emit xVectorChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setYVector(QSGStochasticDirection* arg) +{ + if (m_yVector != arg) { + m_yVector = arg; + emit yVectorChanged(arg); + } + if(perfLevel < Deformable) + reset(); +} + +void QSGImageParticle::setBloat(bool arg) +{ + if (m_bloat != arg) { + m_bloat = arg; + emit bloatChanged(arg); + } + if(perfLevel < 9999) + reset(); +} +void QSGImageParticle::setCount(int c) +{ + QSGParticlePainter::setCount(c); + m_pleaseReset = true; +} + +void QSGImageParticle::reset() +{ + QSGParticlePainter::reset(); + m_pleaseReset = true; +} + +void QSGImageParticle::createEngine() +{ + if(m_spriteEngine) + delete m_spriteEngine; + if(m_sprites.count()) + m_spriteEngine = new QSGSpriteEngine(m_sprites, this); + else + m_spriteEngine = 0; + reset(); +} + +static QSGGeometry::Attribute SimpleParticle_Attributes[] = { + { 0, 2, GL_FLOAT }, // Position + { 1, 2, GL_FLOAT }, // TexCoord + { 2, 4, GL_FLOAT }, // Data + { 3, 4, GL_FLOAT } // Vectors +}; + +static QSGGeometry::AttributeSet SimpleParticle_AttributeSet = +{ + 4, // Attribute Count + (2 + 2 + 4 + 4 ) * sizeof(float), + SimpleParticle_Attributes +}; + +static QSGGeometry::Attribute UltraParticle_Attributes[] = { + { 0, 2, GL_FLOAT }, // Position + { 1, 2, GL_FLOAT }, // TexCoord + { 2, 4, GL_FLOAT }, // Data + { 3, 4, GL_FLOAT }, // Vectors + { 4, 4, GL_UNSIGNED_BYTE }, // Colors + { 5, 4, GL_FLOAT }, // DeformationVectors + { 6, 3, GL_FLOAT }, // Rotation + { 7, 4, GL_FLOAT } // Anim Data +}; + +static QSGGeometry::AttributeSet UltraParticle_AttributeSet = +{ + 8, // Attribute Count + (2 + 2 + 4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar), + UltraParticle_Attributes +}; + +QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode() +{ + perfLevel = Simple;//TODO: Intermediate levels + QImage image = QImage(m_image_name.toLocalFile()); + if (image.isNull()) { + printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile())); + return 0; + } + int vCount = m_count * 4; + int iCount = m_count * 6; + qDebug() << "Simple Case"; + + QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount); + g->setDrawingMode(GL_TRIANGLES); + + SimpleVertex *vertices = (SimpleVertex *) g->vertexData(); + for (int p=0; pindexDataAsUShort(); + for (int i=0; itexture = sceneGraphEngine()->createTextureFromImage(image); + m_material->texture->setFiltering(QSGTexture::Linear); + m_material->framecount = 1; + m_node = new QSGGeometryNode(); + m_node->setGeometry(g); + m_node->setMaterial(m_material); + + m_last_particle = 0; + + return m_node; +} + +QSGGeometryNode* QSGImageParticle::buildParticleNode() +{ + if (m_count * 4 > 0xffff) { + printf("UltraParticle: Too many particles... \n");//####Why is this here? + return 0; + } + + if(m_count <= 0) { + printf("UltraParticle: Too few particles... \n"); + return 0; + } + + if(!m_sprites.count() && !m_bloat + && m_colortable_name.isEmpty() + && m_sizetable_name.isEmpty() + && m_opacitytable_name.isEmpty() + && !m_autoRotation + && !m_rotation && !m_rotationVariation + && !m_rotationSpeed && !m_rotationSpeedVariation + && !m_alphaVariation && m_alpha == 1.0 + && !m_redVariation && !m_blueVariation && !m_greenVariation + && !m_color.isValid() + ) + return buildSimpleParticleNode(); + perfLevel = Sprites;//TODO: intermediate levels + if(!m_color.isValid())//But we're in colored level (or higher) + m_color = QColor(Qt::white); + qDebug() << "Complex Case"; + + QImage image; + if(m_sprites.count()){ + if (!m_spriteEngine) { + qWarning() << "UltraParticle: No sprite engine..."; + return 0; + } + image = m_spriteEngine->assembledImage(); + if(image.isNull())//Warning is printed in engine + return 0; + }else{ + image = QImage(m_image_name.toLocalFile()); + if (image.isNull()) { + printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile())); + return 0; + } + } + + int vCount = m_count * 4; + int iCount = m_count * 6; + + QSGGeometry *g = new QSGGeometry(UltraParticle_AttributeSet, vCount, iCount); + g->setDrawingMode(GL_TRIANGLES); + + UltraVertex *vertices = (UltraVertex *) g->vertexData(); + SimpleVertex *oldSimple = (SimpleVertex *) m_lastData;//TODO: Other levels + if(m_lastLevel == 1) + qDebug() << "Theta" << m_lastLevel << oldSimple[0].x << oldSimple[0].y << oldSimple[0].t; + for (int p=0; pindexDataAsUShort();//TODO: Speed gains by copying this over if count unchanged? + for (int i=0; icolortable = sceneGraphEngine()->createTextureFromImage(colortable); + m_material->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable); + m_material->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable); + + m_material->texture = sceneGraphEngine()->createTextureFromImage(image); + m_material->texture->setFiltering(QSGTexture::Linear); + + m_material->framecount = 1; + if(m_spriteEngine){ + m_material->framecount = m_spriteEngine->maxFrames(); + m_spriteEngine->setCount(m_count); + } + + m_node = new QSGGeometryNode(); + m_node->setGeometry(g); + m_node->setMaterial(m_material); + + m_last_particle = 0; + + return m_node; +} + +QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) +{ + if(m_pleaseReset){ + if(m_node){ + if(perfLevel == 1){ + qDebug() << "Beta"; + m_lastData = qMalloc(m_count*sizeof(SimpleVertices));//TODO: Account for count_changed possibility + memcpy(m_lastData, m_node->geometry()->vertexData(), m_count * sizeof(SimpleVertices));//TODO: Multiple levels + } + m_lastLevel = perfLevel; + delete m_node; + } + if(m_material) + delete m_material; + + m_node = 0; + m_material = 0; + m_pleaseReset = false; + } + + if(m_system && m_system->isRunning()) + prepareNextFrame(); + if (m_node){ + update(); + m_node->markDirty(QSGNode::DirtyMaterial); + } + + return m_node; +} + +void QSGImageParticle::prepareNextFrame() +{ + if (m_node == 0){ //TODO: Staggered loading (as emitted) + m_node = buildParticleNode(); + if(m_node == 0) + return; + qDebug() << "Feature level: " << perfLevel; + } + qint64 timeStamp = m_system->systemSync(this); + + qreal time = timeStamp / 1000.; + m_material->timestamp = time; + + //Advance State + if(m_spriteEngine){//perfLevel == Sprites? + m_material->animcount = m_spriteEngine->spriteCount(); + UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData(); + m_spriteEngine->updateSprites(timeStamp); + for(int i=0; ispriteState(i); + if(curIdx != p.v1.animIdx){ + p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx; + p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(i)/1000.0; + p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(i); + p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(i); + } + } + }else{ + m_material->animcount = 1; + } +} + +template +IntermediateVertices* transplant(IntermediateVertices* iv, VT &v) +{//Deliberate typemangling cast + iv->v1 = (UltraVertex*)&(v.v1); + iv->v2 = (UltraVertex*)&(v.v2); + iv->v3 = (UltraVertex*)&(v.v3); + iv->v4 = (UltraVertex*)&(v.v4); + return iv; +} + +IntermediateVertices* QSGImageParticle::fetchIntermediateVertices(int pos) +{ + //Note that this class ruins typesafety for you. Maybe even thread safety. + //TODO: Something better, possibly with templates or inheritance + static IntermediateVertices iv; + SimpleVertices *sv; + UltraVertices *uv; + switch(perfLevel){ + case Simple: + sv = (SimpleVertices *) m_node->geometry()->vertexData(); + return transplant(&iv, sv[pos]); + case Coloured: + case Deformable: + case Tabled: + case Sprites: + default: + uv = (UltraVertices *) m_node->geometry()->vertexData(); + return transplant(&iv,uv[pos]); + } +} + +void QSGImageParticle::reloadColor(const Color4ub &c, QSGParticleData* d) +{ + UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData(); + int pos = particleTypeIndex(d); + UltraVertices &p = particles[pos]; + p.v1.color = p.v2.color = p.v3.color = p.v4.color = c; +} + +void QSGImageParticle::reload(QSGParticleData *d) +{ + if (m_node == 0) + return; + + int pos = particleTypeIndex(d); + IntermediateVertices* p = fetchIntermediateVertices(pos); + + //Perhaps we could be more efficient? + vertexCopy(*p->v1, d->pv); + vertexCopy(*p->v2, d->pv); + vertexCopy(*p->v3, d->pv); + vertexCopy(*p->v4, d->pv); +} + +void QSGImageParticle::load(QSGParticleData *d) +{ + if (m_node == 0) + return; + + int pos = particleTypeIndex(d); + IntermediateVertices* p = fetchIntermediateVertices(pos);//Remember this removes typesafety! + Color4ub color; + qreal redVariation = m_color_variation + m_redVariation; + qreal greenVariation = m_color_variation + m_greenVariation; + qreal blueVariation = m_color_variation + m_blueVariation; + switch(perfLevel){//Fall-through is intended on all of them + case Sprites: + // Initial Sprite State + p->v1->animT = p->v2->animT = p->v3->animT = p->v4->animT = p->v1->t; + p->v1->animIdx = p->v2->animIdx = p->v3->animIdx = p->v4->animIdx = 0; + if(m_spriteEngine){ + m_spriteEngine->startSprite(pos); + p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = m_spriteEngine->spriteFrames(pos); + p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = m_spriteEngine->spriteDuration(pos); + }else{ + p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = 1; + p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = 9999; + } + case Tabled: + case Deformable: + //Initial Rotation + if(m_xVector){ + const QPointF &ret = m_xVector->sample(QPointF(d->pv.x, d->pv.y)); + p->v1->xx = p->v2->xx = p->v3->xx = p->v4->xx = ret.x(); + p->v1->xy = p->v2->xy = p->v3->xy = p->v4->xy = ret.y(); + } + if(m_yVector){ + const QPointF &ret = m_yVector->sample(QPointF(d->pv.x, d->pv.y)); + p->v1->yx = p->v2->yx = p->v3->yx = p->v4->yx = ret.x(); + p->v1->yy = p->v2->yy = p->v3->yy = p->v4->yy = ret.y(); + } + p->v1->rotation = p->v2->rotation = p->v3->rotation = p->v4->rotation = + (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; + p->v1->rotationSpeed = p->v2->rotationSpeed = p->v3->rotationSpeed = p->v4->rotationSpeed = + (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; + p->v1->autoRotate = p->v2->autoRotate = p->v3->autoRotate = p->v4->autoRotate = m_autoRotation?1.0:0.0; + case Coloured: + //Color initialization + // Particle color + color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; + color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; + color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; + color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; + p->v1->color = p->v2->color = p->v3->color = p->v4->color = color; + default: + break; + } + + vertexCopy(*p->v1, d->pv); + vertexCopy(*p->v2, d->pv); + vertexCopy(*p->v3, d->pv); + vertexCopy(*p->v4, d->pv); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgimageparticle_p.h b/src/declarative/particles/qsgimageparticle_p.h new file mode 100644 index 0000000000..1318647cc9 --- /dev/null +++ b/src/declarative/particles/qsgimageparticle_p.h @@ -0,0 +1,352 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ULTRAPARTICLE_H +#define ULTRAPARTICLE_H +#include "qsgparticlepainter_p.h" +#include "qsgstochasticdirection_p.h" +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class UltraMaterial; +class QSGGeometryNode; + +class QSGSprite; +class QSGSpriteEngine; + +struct Color4ub { + uchar r; + uchar g; + uchar b; + uchar a; +}; + +struct SimpleVertex { + float x; + float y; + float tx; + float ty; + float t; + float lifeSpan; + float size; + float endSize; + float sx; + float sy; + float ax; + float ay; +}; + +struct SimpleVertices { + SimpleVertex v1; + SimpleVertex v2; + SimpleVertex v3; + SimpleVertex v4; +}; + +struct UltraVertex { + float x; + float y; + float tx; + float ty; + float t; + float lifeSpan; + float size; + float endSize; + float sx; + float sy; + float ax; + float ay; + Color4ub color; + float xx; + float xy; + float yx; + float yy; + float rotation; + float rotationSpeed; + float autoRotate;//Assume that GPUs prefer floats to bools + float animIdx; + float frameDuration; + float frameCount; + float animT; +}; + +struct UltraVertices { + UltraVertex v1; + UltraVertex v2; + UltraVertex v3; + UltraVertex v4; +}; + +struct IntermediateVertices { + UltraVertex* v1; + UltraVertex* v2; + UltraVertex* v3; + UltraVertex* v4; +}; + +class QSGImageParticle : public QSGParticlePainter +{ + Q_OBJECT + Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) + Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) + Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) + Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) + + //###Now just colorize - add a flag for 'solid' color particles(where the img is just a mask?)? + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + //Stacks (added) with individual colorVariations + Q_PROPERTY(qreal colorVariation READ colorVariation WRITE setColorVariation NOTIFY colorVariationChanged) + Q_PROPERTY(qreal redVariation READ redVariation WRITE setRedVariation NOTIFY redVariationChanged) + Q_PROPERTY(qreal greenVariation READ greenVariation WRITE setGreenVariation NOTIFY greenVariationChanged) + Q_PROPERTY(qreal blueVariation READ blueVariation WRITE setBlueVariation NOTIFY blueVariationChanged) + //Stacks (multiplies) with the Alpha in the color, mostly here so you can use svg color names (which have full alpha) + Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged) + Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged) + + Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) + Q_PROPERTY(qreal rotationVariation READ rotationVariation WRITE setRotationVariation NOTIFY rotationVariationChanged) + Q_PROPERTY(qreal rotationSpeed READ rotationSpeed WRITE setRotationSpeed NOTIFY rotationSpeedChanged) + Q_PROPERTY(qreal rotationSpeedVariation READ rotationSpeedVariation WRITE setRotationSpeedVariation NOTIFY rotationSpeedVariationChanged) + //If true, then will face the direction of motion. Stacks with rotation, e.g. setting rotation + //to 180 will lead to facing away from the direction of motion + Q_PROPERTY(bool autoRotation READ autoRotation WRITE setAutoRotation NOTIFY autoRotationChanged) + + //###Call i/j? Makes more sense to those with vector calculus experience, and I could even add the cirumflex in QML? + //xVector is the vector from the top-left point to the top-right point, and is multiplied by current size + Q_PROPERTY(QSGStochasticDirection* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged) + //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram. + Q_PROPERTY(QSGStochasticDirection* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged) + Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) + Q_PROPERTY(bool bloat READ bloat WRITE setBloat NOTIFY bloatChanged)//Just a debugging property to bypass optimizations +public: + explicit QSGImageParticle(QSGItem *parent = 0); + virtual ~QSGImageParticle(){} + + virtual void load(QSGParticleData*); + virtual void reload(QSGParticleData*); + virtual void setCount(int c); + + QDeclarativeListProperty sprites(); + QSGSpriteEngine* spriteEngine() {return m_spriteEngine;} + + enum PerformanceLevel{//TODO: Expose? + Unknown = 0, + Simple, + Coloured, + Deformable, + Tabled, + Sprites + }; + + QUrl image() const { return m_image_name; } + void setImage(const QUrl &image); + + QUrl colortable() const { return m_colortable_name; } + void setColortable(const QUrl &table); + + QUrl sizetable() const { return m_sizetable_name; } + void setSizetable (const QUrl &table); + + QUrl opacitytable() const { return m_opacitytable_name; } + void setOpacitytable(const QUrl &table); + + QColor color() const { return m_color; } + void setColor(const QColor &color); + + qreal colorVariation() const { return m_color_variation; } + void setColorVariation(qreal var); + + qreal renderOpacity() const { return m_render_opacity; } + + qreal alphaVariation() const { return m_alphaVariation; } + + qreal alpha() const { return m_alpha; } + + qreal redVariation() const { return m_redVariation; } + + qreal greenVariation() const { return m_greenVariation; } + + qreal blueVariation() const { return m_blueVariation; } + + qreal rotation() const { return m_rotation; } + + qreal rotationVariation() const { return m_rotationVariation; } + + qreal rotationSpeed() const { return m_rotationSpeed; } + + qreal rotationSpeedVariation() const { return m_rotationSpeedVariation; } + + bool autoRotation() const { return m_autoRotation; } + + QSGStochasticDirection* xVector() const { return m_xVector; } + + QSGStochasticDirection* yVector() const { return m_yVector; } + + bool bloat() const { return m_bloat; } + +signals: + + void imageChanged(); + void colortableChanged(); + void sizetableChanged(); + void opacitytableChanged(); + + void colorChanged(); + void colorVariationChanged(); + + void particleDurationChanged(); + void alphaVariationChanged(qreal arg); + + void alphaChanged(qreal arg); + + void redVariationChanged(qreal arg); + + void greenVariationChanged(qreal arg); + + void blueVariationChanged(qreal arg); + + void rotationChanged(qreal arg); + + void rotationVariationChanged(qreal arg); + + void rotationSpeedChanged(qreal arg); + + void rotationSpeedVariationChanged(qreal arg); + + void autoRotationChanged(bool arg); + + void xVectorChanged(QSGStochasticDirection* arg); + + void yVectorChanged(QSGStochasticDirection* arg); + + void bloatChanged(bool arg); + +public slots: + void reloadColor(const Color4ub &c, QSGParticleData* d); + void setAlphaVariation(qreal arg); + + void setAlpha(qreal arg); + + void setRedVariation(qreal arg); + + void setGreenVariation(qreal arg); + + void setBlueVariation(qreal arg); + + void setRotation(qreal arg); + + void setRotationVariation(qreal arg); + + void setRotationSpeed(qreal arg); + + void setRotationSpeedVariation(qreal arg); + + void setAutoRotation(bool arg); + + void setXVector(QSGStochasticDirection* arg); + + void setYVector(QSGStochasticDirection* arg); + + void setBloat(bool arg); + +protected: + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + void reset(); + void prepareNextFrame(); + QSGGeometryNode* buildParticleNode(); + QSGGeometryNode* buildSimpleParticleNode(); + +private slots: + void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty + +private: + //void vertexCopy(UltraVertex &b,const ParticleVertex& a); + IntermediateVertices* fetchIntermediateVertices(int pos); + bool m_do_reset; + + QUrl m_image_name; + QUrl m_colortable_name; + QUrl m_sizetable_name; + QUrl m_opacitytable_name; + + + QColor m_color; + qreal m_color_variation; + qreal m_particleDuration; + + QSGGeometryNode *m_node; + UltraMaterial *m_material; + + // derived values... + int m_last_particle; + + qreal m_render_opacity; + qreal m_alphaVariation; + qreal m_alpha; + qreal m_redVariation; + qreal m_greenVariation; + qreal m_blueVariation; + qreal m_rotation; + qreal m_rotationVariation; + qreal m_rotationSpeed; + qreal m_rotationSpeedVariation; + bool m_autoRotation; + QSGStochasticDirection* m_xVector; + QSGStochasticDirection* m_yVector; + + QList m_sprites; + QSGSpriteEngine* m_spriteEngine; + + bool m_bloat; + PerformanceLevel perfLevel; + + PerformanceLevel m_lastLevel; + void* m_lastData; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // ULTRAPARTICLE_H diff --git a/src/declarative/particles/qsgitemparticle.cpp b/src/declarative/particles/qsgitemparticle.cpp new file mode 100644 index 0000000000..819c823155 --- /dev/null +++ b/src/declarative/particles/qsgitemparticle.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgitemparticle_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QSGItemParticle::QSGItemParticle(QSGItem *parent) : + QSGParticlePainter(parent), m_fade(true) +{ + setFlag(QSGItem::ItemHasContents); +} + + +void QSGItemParticle::freeze(QSGItem* item) +{ + m_stasis << item; +} + + +void QSGItemParticle::unfreeze(QSGItem* item) +{ + m_stasis.remove(item); +} + +void QSGItemParticle::take(QSGItem *item, bool prioritize) +{ + if(prioritize) + m_pendingItems.push_front(item); + else + m_pendingItems.push_back(item); +} + +void QSGItemParticle::give(QSGItem *item) +{ + //TODO: This +} + +void QSGItemParticle::load(QSGParticleData* d) +{ + if(m_pendingItems.isEmpty()) + return; + int pos = particleTypeIndex(d); + if(m_items[pos]){ + if(m_stasis.contains(m_items[pos])) + qWarning() << "Current model particles prefers overwrite:false"; + //remove old item from the particle that is dying to make room for this one + m_items[pos]->setOpacity(0.); + QSGItemParticleAttached* mpa; + if((mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[pos], false)))) + mpa->detach();//reparent as well? + m_items[pos] = 0; + m_data[pos] = 0; + m_activeCount--; + } + m_items[pos] = m_pendingItems.front(); + m_pendingItems.pop_front(); + m_items[pos]->setX(d->curX() - m_items[pos]->width()/2); + m_items[pos]->setY(d->curY() - m_items[pos]->height()/2); + QSGItemParticleAttached* mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[pos])); + if(mpa){ + mpa->m_mp = this; + mpa->attach(); + } + m_items[pos]->setParentItem(this); + m_data[pos] = d; + m_activeCount++; +} + +void QSGItemParticle::reload(QSGParticleData* d) +{ + //No-op unless we start copying the data. +} + +void QSGItemParticle::setCount(int c) +{ + QSGParticlePainter::setCount(c);//###Do we need our own? + m_particleCount = c; + reset(); +} + +int QSGItemParticle::count() +{ + return m_particleCount; +} + +void QSGItemParticle::reset() +{ + QSGParticlePainter::reset(); + //TODO: Cleanup items? + m_items.resize(m_particleCount); + m_data.resize(m_particleCount); + m_items.fill(0); + m_data.fill(0); + //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal? +} + + +QSGNode* QSGItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d) +{ + //Dummy update just to get painting tick + if(m_pleaseReset){ + m_pleaseReset = false; + reset(); + } + prepareNextFrame(); + + update();//Get called again + if(n) + n->markDirty(QSGNode::DirtyMaterial); + return QSGItem::updatePaintNode(n,d); +} + +void QSGItemParticle::prepareNextFrame() +{ + qint64 timeStamp = m_system->systemSync(this); + qreal curT = timeStamp/1000.0; + qreal dt = curT - m_lastT; + m_lastT = curT; + if(!m_activeCount) + return; + + //TODO: Size, better fade? + for(int i=0; ipv.t) / data->pv.lifeSpan; + if(m_stasis.contains(item)) { + m_data[i]->pv.t += dt;//Stasis effect + continue; + } + if(t >= 1.0){//Usually happens from load + item->setOpacity(0.); + QSGItemParticleAttached* mpa; + if((mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[i])))) + mpa->detach();//reparent as well? + m_items[i] = 0; + m_data[i] = 0; + m_activeCount--; + }else{//Fade + if(m_fade){ + qreal o = 1.; + if(t<0.2) + o = t*5; + if(t>0.8) + o = (1-t)*5; + item->setOpacity(o); + }else{ + item->setOpacity(1.);//###Without fade, it's just a binary toggle - if we turn it off we have to turn it back on + } + } + item->setX(data->curX() - item->width()/2); + item->setY(data->curY() - item->height()/2); + } +} + +QSGItemParticleAttached *QSGItemParticle::qmlAttachedProperties(QObject *object) +{ + return new QSGItemParticleAttached(object); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgitemparticle_p.h b/src/declarative/particles/qsgitemparticle_p.h new file mode 100644 index 0000000000..fa3516b631 --- /dev/null +++ b/src/declarative/particles/qsgitemparticle_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ITEMPARTICLE_H +#define ITEMPARTICLE_H +#include "qsgparticlepainter_p.h" +#include +#include +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) +class QSGVisualDataModel; +class QSGItemParticleAttached; + +class QSGItemParticle : public QSGParticlePainter +{ + Q_OBJECT + + Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) +public: + explicit QSGItemParticle(QSGItem *parent = 0); + + bool fade() const { return m_fade; } + + virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + virtual void load(QSGParticleData*); + virtual void reload(QSGParticleData*); + virtual void setCount(int c); + virtual int count(); + + static QSGItemParticleAttached *qmlAttachedProperties(QObject *object); +signals: + void fadeChanged(); + +public slots: + //TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it? + void freeze(QSGItem* item); + void unfreeze(QSGItem* item); + void take(QSGItem* item,bool prioritize=false);//take by modelparticle + void give(QSGItem* item);//give from modelparticle + + void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();} +protected: + virtual void reset(); + void prepareNextFrame(); +private: + QList > m_deletables; + int m_particleCount; + bool m_fade; + + QList m_pendingItems; + QVector m_items; + QVector m_data; + QVector m_idx; + QList m_available; + QSet m_stasis; + qreal m_lastT; + int m_activeCount; +}; + +class QSGItemParticleAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSGItemParticle* particle READ particle CONSTANT); +public: + QSGItemParticleAttached(QObject* parent) + : QObject(parent), m_mp(0) + {;} + QSGItemParticle* particle() {return m_mp;} + void detach(){emit detached();} + void attach(){emit attached();} +private: + QSGItemParticle* m_mp; + friend class QSGItemParticle; +Q_SIGNALS: + void detached(); + void attached(); +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QSGItemParticle, QML_HAS_ATTACHED_PROPERTIES) + +QT_END_HEADER +#endif // ITEMPARTICLE_H diff --git a/src/declarative/particles/qsgkill.cpp b/src/declarative/particles/qsgkill.cpp new file mode 100644 index 0000000000..1321898dc9 --- /dev/null +++ b/src/declarative/particles/qsgkill.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgkill_p.h" +#include "qsgparticleemitter_p.h" +QT_BEGIN_NAMESPACE +QSGKillAffector::QSGKillAffector(QSGItem *parent) : + QSGParticleAffector(parent) +{ +} + + +bool QSGKillAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + Q_UNUSED(dt); + if(d->stillAlive()){ + d->pv.t -= d->pv.lifeSpan + 1; + return true; + } +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgkill_p.h b/src/declarative/particles/qsgkill_p.h new file mode 100644 index 0000000000..1b24b2fb40 --- /dev/null +++ b/src/declarative/particles/qsgkill_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef KILLAFFECTOR_H +#define KILLAFFECTOR_H +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGKillAffector : public QSGParticleAffector +{ + Q_OBJECT +public: + explicit QSGKillAffector(QSGItem *parent = 0); +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +signals: + +public slots: + +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // KILLAFFECTOR_H diff --git a/src/declarative/particles/qsglineextruder.cpp b/src/declarative/particles/qsglineextruder.cpp new file mode 100644 index 0000000000..f32b01402a --- /dev/null +++ b/src/declarative/particles/qsglineextruder.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qsglineextruder_p.h" +#include + +QSGLineExtruder::QSGLineExtruder(QObject *parent) : + QSGParticleExtruder(parent), m_mirrored(false) +{ +} + +QPointF QSGLineExtruder::extrude(const QRectF &r) +{ + qreal x,y; + if(!r.height()){ + x = r.width() * ((qreal)rand())/RAND_MAX; + y = 0; + }else{ + y = r.height() * ((qreal)rand())/RAND_MAX; + if(!r.width()){ + x = 0; + }else{ + x = r.width()/r.height() * y; + if(m_mirrored) + x = r.width() - x; + } + } + return QPointF(x,y); +} diff --git a/src/declarative/particles/qsglineextruder_p.h b/src/declarative/particles/qsglineextruder_p.h new file mode 100644 index 0000000000..f356ca332a --- /dev/null +++ b/src/declarative/particles/qsglineextruder_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LINEEXTRUDER_H +#define LINEEXTRUDER_H +#include "qsgparticleextruder_p.h" + +class QSGLineExtruder : public QSGParticleExtruder +{ + Q_OBJECT + //Default is topleft to bottom right. Flipped makes it topright to bottom left + Q_PROPERTY(bool mirrored READ mirrored WRITE setmirrored NOTIFY mirroredChanged) + +public: + explicit QSGLineExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + bool mirrored() const + { + return m_mirrored; + } + +signals: + + void mirroredChanged(bool arg); + +public slots: + + void setmirrored(bool arg) + { + if (m_mirrored != arg) { + m_mirrored = arg; + emit mirroredChanged(arg); + } + } +private: + bool m_mirrored; +}; + +#endif // LINEEXTRUDER_H diff --git a/src/declarative/particles/qsgmaskextruder.cpp b/src/declarative/particles/qsgmaskextruder.cpp new file mode 100644 index 0000000000..3fe28b30a3 --- /dev/null +++ b/src/declarative/particles/qsgmaskextruder.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgmaskextruder_p.h" +#include +#include +QT_BEGIN_NAMESPACE +QSGMaskExtruder::QSGMaskExtruder(QObject *parent) : + QSGParticleExtruder(parent) + , m_lastWidth(-1) + , m_lastHeight(-1) +{ +} + +QPointF QSGMaskExtruder::extrude(const QRectF &r) +{ + ensureInitialized(r); + if(!m_mask.count()) + return r.topLeft(); + const QPointF p = m_mask[rand() % m_mask.count()]; + //### Should random sub-pixel positioning be added? + return p + r.topLeft(); +} + +bool QSGMaskExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? + QPoint p = point.toPoint() - bounds.topLeft().toPoint(); + return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); +} + +void QSGMaskExtruder::ensureInitialized(const QRectF &r) +{ + if(m_lastWidth == r.width() && m_lastHeight == r.height()) + return; + m_lastWidth = r.width(); + m_lastHeight = r.height(); + + m_mask.clear(); + if(m_source.isEmpty()) + return; + m_img = QImage(m_source.toLocalFile()); + m_img = m_img.createAlphaMask(); + m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier + m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? + for(int i=0; i +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGMaskExtruder : public QSGParticleExtruder +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) +public: + explicit QSGMaskExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point); + + QUrl source() const + { + return m_source; + } + +signals: + + void sourceChanged(QUrl arg); + +public slots: + + void setSource(QUrl arg) + { + if (m_source != arg) { + m_source = arg; + m_lastHeight = -1;//Trigger reset + m_lastWidth = -1; + emit sourceChanged(arg); + } + } +private: + QUrl m_source; + + void ensureInitialized(const QRectF &r); + int m_lastWidth; + int m_lastHeight; + QImage m_img; + QList m_mask;//TODO: More memory efficient datastructures +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // MASKEXTRUDER_H diff --git a/src/declarative/particles/qsgmodelparticle.cpp b/src/declarative/particles/qsgmodelparticle.cpp new file mode 100644 index 0000000000..94ce082c9d --- /dev/null +++ b/src/declarative/particles/qsgmodelparticle.cpp @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgmodelparticle_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QSGModelParticle::QSGModelParticle(QSGItem *parent) : + QSGParticlePainter(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true), m_modelCount(0) +{ + setFlag(QSGItem::ItemHasContents); +} + +QVariant QSGModelParticle::model() const +{ + return m_dataSource; +} + +void QSGModelParticle::setModel(const QVariant &arg) +{ + if(arg == m_dataSource) + return; + m_dataSource = arg; + if(qobject_cast(arg.value())) { + if(m_ownModel && m_model) + delete m_model; + m_model = qobject_cast(arg.value()); + m_ownModel = false; + }else{ + if(!m_model || !m_ownModel) + m_model = new QSGVisualDataModel(qmlContext(this)); + m_model->setModel(m_dataSource); + m_ownModel = true; + } + if(m_comp) + m_model->setDelegate(m_comp); + emit modelChanged(); + emit modelCountChanged(); + connect(m_model, SIGNAL(countChanged()), + this, SIGNAL(modelCountChanged())); + connect(m_model, SIGNAL(countChanged()), + this, SLOT(updateCount())); + updateCount(); +} + +void QSGModelParticle::updateCount() +{ + int newCount = 0; + if(m_model) + newCount = m_model->count(); + if(newCount < 0) + return;//WTF? + if(m_modelCount == 0 || newCount == 0){ + m_available.clear(); + for(int i=0; i m_modelCount){ + for(int i=m_modelCount; idelegate(); + return 0; +} + +void QSGModelParticle::setDelegate(QDeclarativeComponent *comp) +{ + if (QSGVisualDataModel *dataModel = qobject_cast(m_model)) + if (comp == dataModel->delegate()) + return; + m_comp = comp; + if(m_model) + m_model->setDelegate(comp); + emit delegateChanged(); +} + +int QSGModelParticle::modelCount() const +{ + if(m_model) + const_cast(this)->updateCount();//TODO: Investigate why this doesn't get called properly + return m_modelCount; +} + + +void QSGModelParticle::freeze(QSGItem* item) +{ + m_stasis << item; +} + + +void QSGModelParticle::unfreeze(QSGItem* item) +{ + m_stasis.remove(item); +} + +void QSGModelParticle::load(QSGParticleData* d) +{ + if(!m_model || !m_model->count()) + return; + int pos = particleTypeIndex(d); + if(m_available.isEmpty()) + return; + if(m_items[pos]){ + if(m_stasis.contains(m_items[pos])) + qWarning() << "Current model particles prefers overwrite:false"; + //remove old item from the particle that is dying to make room for this one + m_items[pos]->setOpacity(0.); + m_available << m_idx[pos]; + m_model->release(m_items[pos]); + m_idx[pos] = -1; + m_items[pos] = 0; + m_data[pos] = 0; + m_activeCount--; + } + m_items[pos] = m_model->item(m_available.first()); + m_idx[pos] = m_available.first(); + m_available.pop_front(); + QSGModelParticleAttached* mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[pos])); + if(mpa){ + mpa->m_mp = this; + mpa->attach(); + } + m_items[pos]->setParentItem(this); + m_data[pos] = d; + m_activeCount++; +} + +void QSGModelParticle::reload(QSGParticleData* d) +{ + //No-op unless we start copying the data. +} + +void QSGModelParticle::setCount(int c) +{ + QSGParticlePainter::setCount(c);//###Do we need our own? + m_particleCount = c; + reset(); +} + +int QSGModelParticle::count() +{ + return m_particleCount; +} + +void QSGModelParticle::reset() +{ + QSGParticlePainter::reset(); + //TODO: Cleanup items? + m_items.resize(m_particleCount); + m_data.resize(m_particleCount); + m_idx.resize(m_particleCount); + m_items.fill(0); + m_data.fill(0); + m_idx.fill(-1); + //m_available.clear();//Should this be reset too? + //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal? +} + + +QSGNode* QSGModelParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d) +{ + //Dummy update just to get painting tick + if(m_pleaseReset){ + m_pleaseReset = false; + reset(); + } + prepareNextFrame(); + + update();//Get called again + if(n) + n->markDirty(QSGNode::DirtyMaterial); + return QSGItem::updatePaintNode(n,d); +} + +void QSGModelParticle::prepareNextFrame() +{ + qint64 timeStamp = m_system->systemSync(this); + qreal curT = timeStamp/1000.0; + qreal dt = curT - m_lastT; + m_lastT = curT; + if(!m_activeCount) + return; + + //TODO: Size, better fade? + for(int i=0; ipv.t) / data->pv.lifeSpan; + if(m_stasis.contains(item)) { + m_data[i]->pv.t += dt;//Stasis effect + continue; + } + if(t >= 1.0){//Usually happens from load + item->setOpacity(0.); + m_available << m_idx[i]; + m_model->release(m_items[i]); + m_idx[i] = -1; + m_items[i] = 0; + m_data[i] = 0; + m_activeCount--; + }else{//Fade + if(m_fade){ + qreal o = 1.; + if(t<0.2) + o = t*5; + if(t>0.8) + o = (1-t)*5; + item->setOpacity(o); + }else{ + item->setOpacity(1.);//###Without fade, it's just a binary toggle - if we turn it off we have to turn it back on + } + } + item->setX(data->curX() - item->width()/2); + item->setY(data->curY() - item->height()/2); + } +} + +QSGModelParticleAttached *QSGModelParticle::qmlAttachedProperties(QObject *object) +{ + return new QSGModelParticleAttached(object); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgmodelparticle_p.h b/src/declarative/particles/qsgmodelparticle_p.h new file mode 100644 index 0000000000..4dd8bfa710 --- /dev/null +++ b/src/declarative/particles/qsgmodelparticle_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DATAPARTICLE_H +#define DATAPARTICLE_H +#include "qsgparticlepainter_p.h" +#include +#include +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) +class QSGVisualDataModel; +class QSGModelParticleAttached; + +class QSGModelParticle : public QSGParticlePainter +{ + Q_OBJECT + + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) + Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) + Q_PROPERTY(int modelCount READ modelCount NOTIFY modelCountChanged) + Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) + Q_CLASSINFO("DefaultProperty", "delegate") +public: + explicit QSGModelParticle(QSGItem *parent = 0); + QVariant model() const; + void setModel(const QVariant &); + + QDeclarativeComponent *delegate() const; + void setDelegate(QDeclarativeComponent *); + + int modelCount() const; + + bool fade() const { return m_fade; } + + virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + virtual void load(QSGParticleData*); + virtual void reload(QSGParticleData*); + virtual void setCount(int c); + virtual int count(); + + static QSGModelParticleAttached *qmlAttachedProperties(QObject *object); +signals: + void modelChanged(); + void delegateChanged(); + void modelCountChanged(); + void fadeChanged(); + +public slots: + void freeze(QSGItem* item); + void unfreeze(QSGItem* item); + + void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();} +protected: + virtual void reset(); + void prepareNextFrame(); +private slots: + void updateCount(); +private: + bool m_ownModel; + QDeclarativeComponent* m_comp; + QSGVisualDataModel *m_model; + QVariant m_dataSource; + QList > m_deletables; + int m_particleCount; + bool m_fade; + + QList m_pendingItems; + QVector m_items; + QVector m_data; + QVector m_idx; + QList m_available; + QSet m_stasis; + qreal m_lastT; + int m_activeCount; + int m_modelCount; +}; + +class QSGModelParticleAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSGModelParticle* particle READ particle CONSTANT); +public: + QSGModelParticleAttached(QObject* parent) + : QObject(parent), m_mp(0) + {;} + QSGModelParticle* particle() {return m_mp;} + void detach(){emit detached();} + void attach(){emit attached();} +private: + QSGModelParticle* m_mp; + friend class QSGModelParticle; +Q_SIGNALS: + void detached(); + void attached(); +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QSGModelParticle, QML_HAS_ATTACHED_PROPERTIES) + +QT_END_HEADER +#endif // DATAPARTICLE_H diff --git a/src/declarative/particles/qsgparticleaffector.cpp b/src/declarative/particles/qsgparticleaffector.cpp new file mode 100644 index 0000000000..d4b588a44f --- /dev/null +++ b/src/declarative/particles/qsgparticleaffector.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgparticleaffector_p.h" +#include +QT_BEGIN_NAMESPACE +QSGParticleAffector::QSGParticleAffector(QSGItem *parent) : + QSGItem(parent), m_needsReset(false), m_system(0), m_active(true) + , m_updateIntSet(false), m_shape(new QSGParticleExtruder(this)), m_signal(false) +{ + connect(this, SIGNAL(systemChanged(QSGParticleSystem*)), + this, SLOT(updateOffsets())); + connect(this, SIGNAL(xChanged()), + this, SLOT(updateOffsets())); + connect(this, SIGNAL(yChanged()), + this, SLOT(updateOffsets()));//TODO: in componentComplete and all relevant signals +} + +void QSGParticleAffector::componentComplete() +{ + if(!m_system) + qWarning() << "Affector created without a particle system specified";//TODO: useful QML warnings, like line number? + QSGItem::componentComplete(); +} + +void QSGParticleAffector::affectSystem(qreal dt) +{ + if(!m_active) + return; + if(!m_system){ + qDebug() << "No system" << this; + return; + } + //If not reimplemented, calls affect particle per particle + //But only on particles in targeted system/area + if(m_updateIntSet){ + m_groups.clear(); + foreach(const QString &p, m_particles) + m_groups << m_system->m_groupIds[p];//###Can this occur before group ids are properly assigned? + m_updateIntSet = false; + } + //foreach(ParticleData* d, m_system->m_data){ + for(int i=0; im_particle_count; i++){ + QSGParticleData* d = m_system->m_data[i]; + if(!d || (m_onceOff && m_onceOffed.contains(d->systemIndex))) + continue; + if(m_groups.isEmpty() || m_groups.contains(d->group)){ + //Need to have previous location for affected. if signal || shape might be faster? + QPointF curPos = QPointF(d->curX(), d->curY()); + if(width() == 0 || height() == 0 + || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()),curPos)){ + if(affectParticle(d, dt)){ + m_system->m_needsReset << d; + if(m_onceOff) + m_onceOffed << d->systemIndex; + if(m_signal) + emit affected(curPos.x(), curPos.y()); + } + } + } + } +} + +bool QSGParticleAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + Q_UNUSED(d); + Q_UNUSED(dt); + return false; +} + +void QSGParticleAffector::reset(int idx) +{//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass + if(m_onceOff) + m_onceOffed.remove(idx); +} + +void QSGParticleAffector::updateOffsets() +{ + if(m_system) + m_offset = m_system->mapFromItem(this, QPointF(0, 0)); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgparticleaffector_p.h b/src/declarative/particles/qsgparticleaffector_p.h new file mode 100644 index 0000000000..1572ad8102 --- /dev/null +++ b/src/declarative/particles/qsgparticleaffector_p.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLEAFFECTOR_H +#define PARTICLEAFFECTOR_H + +#include +#include "qsgparticlesystem_p.h" +#include "qsgparticleextruder_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGParticleAffector : public QSGItem +{ + Q_OBJECT + Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(bool onceOff READ onceOff WRITE setOnceOff NOTIFY onceOffChanged) + Q_PROPERTY(QSGParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) + Q_PROPERTY(bool signal READ signal WRITE setSignal NOTIFY signalChanged) + +public: + explicit QSGParticleAffector(QSGItem *parent = 0); + virtual void affectSystem(qreal dt); + virtual void reset(int systemIdx);//As some store their own data per idx? + QSGParticleSystem* system() const + { + return m_system; + } + + QStringList particles() const + { + return m_particles; + } + + bool active() const + { + return m_active; + } + + bool onceOff() const + { + return m_onceOff; + } + + QSGParticleExtruder* shape() const + { + return m_shape; + } + + bool signal() const + { + return m_signal; + } + +signals: + + void systemChanged(QSGParticleSystem* arg); + + void particlesChanged(QStringList arg); + + void activeChanged(bool arg); + + void onceOffChanged(bool arg); + + void shapeChanged(QSGParticleExtruder* arg); + + void affected(qreal x, qreal y);//###Idx too? + void signalChanged(bool arg); + +public slots: +void setSystem(QSGParticleSystem* arg) +{ + if (m_system != arg) { + m_system = arg; + m_system->registerParticleAffector(this); + emit systemChanged(arg); + } +} + +void setParticles(QStringList arg) +{ + if (m_particles != arg) { + m_particles = arg; + m_updateIntSet = true; + emit particlesChanged(arg); + } +} + +void setActive(bool arg) +{ + if (m_active != arg) { + m_active = arg; + emit activeChanged(arg); + } +} + +void setOnceOff(bool arg) +{ + if (m_onceOff != arg) { + m_onceOff = arg; + emit onceOffChanged(arg); + } +} + +void setShape(QSGParticleExtruder* arg) +{ + if (m_shape != arg) { + m_shape = arg; + emit shapeChanged(arg); + } +} + +void setSignal(bool arg) +{ + if (m_signal != arg) { + m_signal = arg; + emit signalChanged(arg); + } +} + +protected: + friend class QSGParticleSystem; + virtual bool affectParticle(QSGParticleData *d, qreal dt); + bool m_needsReset;//### What is this really saving? + QSGParticleSystem* m_system; + QStringList m_particles; + bool activeGroup(int g) {return m_groups.isEmpty() || m_groups.contains(g);} + bool m_active; + virtual void componentComplete(); + QPointF m_offset; +private: + QSet m_groups; + QSet m_onceOffed; + bool m_updateIntSet; + + bool m_onceOff; + + QSGParticleExtruder* m_shape; + + bool m_signal; + +private slots: + void updateOffsets(); +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // PARTICLEAFFECTOR_H diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp new file mode 100644 index 0000000000..c04c86cfe5 --- /dev/null +++ b/src/declarative/particles/qsgparticleemitter.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgparticleemitter_p.h" +QT_BEGIN_NAMESPACE +QSGParticleEmitter::QSGParticleEmitter(QSGItem *parent) : + QSGItem(parent) + , m_particlesPerSecond(10) + , m_particleDuration(1000) + , m_particleDurationVariation(0) + , m_emitting(true) + , m_system(0) + , m_extruder(0) + , m_defaultExtruder(0) + , m_speed(&m_nullVector) + , m_acceleration(&m_nullVector) + , m_particleSize(16) + , m_particleEndSize(-1) + , m_particleSizeVariation(0) + , m_maxParticleCount(-1) + , m_burstLeft(0) + +{ + //TODO: Reset speed/acc back to null vector? Or allow null pointer? + connect(this, SIGNAL(maxParticleCountChanged(int)), + this, SIGNAL(particleCountChanged())); + connect(this, SIGNAL(particlesPerSecondChanged(qreal)), + this, SIGNAL(particleCountChanged())); + connect(this, SIGNAL(particleDurationChanged(int)), + this, SIGNAL(particleCountChanged())); +} + +QSGParticleEmitter::~QSGParticleEmitter() +{ + if(m_defaultExtruder) + delete m_defaultExtruder; +} + +void QSGParticleEmitter::componentComplete() +{ + if(!m_system) + qWarning() << "Emitter created without a particle system specified";//TODO: useful QML warnings, like line number? + QSGItem::componentComplete(); +} +void QSGParticleEmitter::emitWindow(int timeStamp) +{ + Q_UNUSED(timeStamp); +} + + +void QSGParticleEmitter::setEmitting(bool arg) +{ + if (m_emitting != arg) { + m_emitting = arg; + emit emittingChanged(arg); + } +} + + +QSGParticleExtruder* QSGParticleEmitter::effectiveExtruder() +{ + if(m_extruder) + return m_extruder; + if(!m_defaultExtruder) + m_defaultExtruder = new QSGParticleExtruder; + return m_defaultExtruder; +} + +void QSGParticleEmitter::pulse(qreal seconds) +{ + if(!particleCount()) + qWarning() << "pulse called on an emitter with a particle count of zero"; + if(!m_emitting) + m_burstLeft = seconds*1000.0;//TODO: Change name to match +} + +void QSGParticleEmitter::burst(int num) +{ + if(!particleCount()) + qWarning() << "burst called on an emitter with a particle count of zero"; + m_burstQueue << qMakePair(num, QPointF(x(), y())); +} + +void QSGParticleEmitter::setMaxParticleCount(int arg) +{ + if (m_maxParticleCount != arg) { + if(arg < 0 && m_maxParticleCount >= 0){ + connect(this, SIGNAL(particlesPerSecondChanged(qreal)), + this, SIGNAL(particleCountChanged())); + connect(this, SIGNAL(particleDurationChanged(int)), + this, SIGNAL(particleCountChanged())); + }else if(arg >= 0 && m_maxParticleCount < 0){ + disconnect(this, SIGNAL(particlesPerSecondChanged(qreal)), + this, SIGNAL(particleCountChanged())); + disconnect(this, SIGNAL(particleDurationChanged(int)), + this, SIGNAL(particleCountChanged())); + } + m_maxParticleCount = arg; + emit maxParticleCountChanged(arg); + } +} + +int QSGParticleEmitter::particleCount() const +{ + if(m_maxParticleCount >= 0) + return m_maxParticleCount; + return m_particlesPerSecond*((m_particleDuration+m_particleDurationVariation)/1000.0); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h new file mode 100644 index 0000000000..ad6a5f645f --- /dev/null +++ b/src/declarative/particles/qsgparticleemitter_p.h @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLEEMITTER_H +#define PARTICLEEMITTER_H + +#include +#include +#include "qsgparticlesystem_p.h" +#include "qsgparticleextruder_p.h" +#include "qsgstochasticdirection_p.h" + +#include +#include +#include +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGParticleEmitter : public QSGItem +{ + Q_OBJECT + //###currently goes in emitters OR sets system. Pick one? + Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + Q_PROPERTY(QString particle READ particle WRITE setParticle NOTIFY particleChanged) + Q_PROPERTY(QSGParticleExtruder* shape READ extruder WRITE setExtruder NOTIFY extruderChanged) + Q_PROPERTY(bool emitting READ emitting WRITE setEmitting NOTIFY emittingChanged) + + Q_PROPERTY(qreal particlesPerSecond READ particlesPerSecond WRITE setParticlesPerSecond NOTIFY particlesPerSecondChanged) + Q_PROPERTY(int particleDuration READ particleDuration WRITE setParticleDuration NOTIFY particleDurationChanged) + Q_PROPERTY(int particleDurationVariation READ particleDurationVariation WRITE setParticleDurationVariation NOTIFY particleDurationVariationChanged) + Q_PROPERTY(int maxParticles READ maxParticleCount WRITE setMaxParticleCount NOTIFY maxParticleCountChanged) + + Q_PROPERTY(qreal particleSize READ particleSize WRITE setParticleSize NOTIFY particleSizeChanged) + Q_PROPERTY(qreal particleEndSize READ particleEndSize WRITE setParticleEndSize NOTIFY particleEndSizeChanged) + Q_PROPERTY(qreal particleSizeVariation READ particleSizeVariation WRITE setParticleSizeVariation NOTIFY particleSizeVariationChanged) + + Q_PROPERTY(QSGStochasticDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged) + Q_PROPERTY(QSGStochasticDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) +public: + explicit QSGParticleEmitter(QSGItem *parent = 0); + virtual ~QSGParticleEmitter(); + virtual void emitWindow(int timeStamp); + + bool emitting() const + { + return m_emitting; + } + + qreal particlesPerSecond() const + { + return m_particlesPerSecond; + } + + int particleDuration() const + { + return m_particleDuration; + } + + QSGParticleSystem* system() const + { + return m_system; + } + + QString particle() const + { + return m_particle; + } + + int particleDurationVariation() const + { + return m_particleDurationVariation; + } + + virtual void componentComplete(); +signals: + void particlesPerSecondChanged(qreal); + void particleDurationChanged(int); + void emittingChanged(bool); + + void systemChanged(QSGParticleSystem* arg); + + void particleChanged(QString arg); + + void particleDurationVariationChanged(int arg); + + void extruderChanged(QSGParticleExtruder* arg); + + void particleSizeChanged(qreal arg); + + void particleEndSizeChanged(qreal arg); + + void particleSizeVariationChanged(qreal arg); + + void speedChanged(QSGStochasticDirection * arg); + + void accelerationChanged(QSGStochasticDirection * arg); + + void maxParticleCountChanged(int arg); + void particleCountChanged(); + +public slots: + void pulse(qreal seconds); + void burst(int num); + + void setEmitting(bool arg); + + void setParticlesPerSecond(qreal arg) + { + if (m_particlesPerSecond != arg) { + m_particlesPerSecond = arg; + emit particlesPerSecondChanged(arg); + } + } + + void setParticleDuration(int arg) + { + if (m_particleDuration != arg) { + m_particleDuration = arg; + emit particleDurationChanged(arg); + } + } + + void setSystem(QSGParticleSystem* arg) + { + if (m_system != arg) { + m_system = arg; + m_system->registerParticleEmitter(this); + emit systemChanged(arg); + } + } + + void setParticle(QString arg) + { + if (m_particle != arg) { + m_particle = arg; + emit particleChanged(arg); + } + } + + void setParticleDurationVariation(int arg) + { + if (m_particleDurationVariation != arg) { + m_particleDurationVariation = arg; + emit particleDurationVariationChanged(arg); + } + } + void setExtruder(QSGParticleExtruder* arg) + { + if (m_extruder != arg) { + m_extruder = arg; + emit extruderChanged(arg); + } + } + + void setParticleSize(qreal arg) + { + if (m_particleSize != arg) { + m_particleSize = arg; + emit particleSizeChanged(arg); + } + } + + void setParticleEndSize(qreal arg) + { + if (m_particleEndSize != arg) { + m_particleEndSize = arg; + emit particleEndSizeChanged(arg); + } + } + + void setParticleSizeVariation(qreal arg) + { + if (m_particleSizeVariation != arg) { + m_particleSizeVariation = arg; + emit particleSizeVariationChanged(arg); + } + } + + void setSpeed(QSGStochasticDirection * arg) + { + if (m_speed != arg) { + m_speed = arg; + emit speedChanged(arg); + } + } + + void setAcceleration(QSGStochasticDirection * arg) + { + if (m_acceleration != arg) { + m_acceleration = arg; + emit accelerationChanged(arg); + } + } + + void setMaxParticleCount(int arg); + +public: + int particleCount() const; + + virtual void reset(){;} + QSGParticleExtruder* extruder() const + { + return m_extruder; + } + + qreal particleSize() const + { + return m_particleSize; + } + + qreal particleEndSize() const + { + return m_particleEndSize; + } + + qreal particleSizeVariation() const + { + return m_particleSizeVariation; + } + + QSGStochasticDirection * speed() const + { + return m_speed; + } + + QSGStochasticDirection * acceleration() const + { + return m_acceleration; + } + + int maxParticleCount() const + { + return m_maxParticleCount; + } + +protected: + qreal m_particlesPerSecond; + int m_particleDuration; + int m_particleDurationVariation; + bool m_emitting; + QSGParticleSystem* m_system; + QString m_particle; + QSGParticleExtruder* m_extruder; + QSGParticleExtruder* m_defaultExtruder; + QSGParticleExtruder* effectiveExtruder(); + QSGStochasticDirection * m_speed; + QSGStochasticDirection * m_acceleration; + qreal m_particleSize; + qreal m_particleEndSize; + qreal m_particleSizeVariation; + + int m_burstLeft;//TODO: Rename to pulse + QList > m_burstQueue; + int m_maxParticleCount; +private: + QSGStochasticDirection m_nullVector; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // PARTICLEEMITTER_H diff --git a/src/declarative/particles/qsgparticleextruder.cpp b/src/declarative/particles/qsgparticleextruder.cpp new file mode 100644 index 0000000000..91b968c8af --- /dev/null +++ b/src/declarative/particles/qsgparticleextruder.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgparticleextruder_p.h" + +QT_BEGIN_NAMESPACE + +QSGParticleExtruder::QSGParticleExtruder(QObject *parent) : + QObject(parent), m_fill(true) +{ +} + +QPointF QSGParticleExtruder::extrude(const QRectF &rect) +{ + if(m_fill) + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); + int side = rand() % 4; + switch(side){//TODO: Doesn't this overlap the corners? + case 0: + return QPointF(rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); + case 1: + return QPointF(rect.width() + rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); + case 2: + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + rect.y()); + default: + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + rect.height() + rect.y()); + } +} + +bool QSGParticleExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + return bounds.contains(point); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgparticleextruder_p.h b/src/declarative/particles/qsgparticleextruder_p.h new file mode 100644 index 0000000000..41e27eb2fa --- /dev/null +++ b/src/declarative/particles/qsgparticleextruder_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLEEXTRUDER_H +#define PARTICLEEXTRUDER_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGParticleExtruder : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Should this be base class, or a BoxExtruder? + +public: + explicit QSGParticleExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point);//###Needed for follow emitter, but does it belong? Only marginally conceptually valid, and that's from user's perspective + bool fill() const + { + return m_fill; + } + +signals: + + void fillChanged(bool arg); + +public slots: + + void setFill(bool arg) + { + if (m_fill != arg) { + m_fill = arg; + emit fillChanged(arg); + } + } +protected: + bool m_fill; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // PARTICLEEXTRUDER_H diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp new file mode 100644 index 0000000000..8814c61b56 --- /dev/null +++ b/src/declarative/particles/qsgparticlepainter.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgparticlepainter_p.h" +#include +QT_BEGIN_NAMESPACE +QSGParticlePainter::QSGParticlePainter(QSGItem *parent) : + QSGItem(parent), + m_system(0) +{ + connect(this, SIGNAL(xChanged()), + this, SLOT(calcSystemOffset())); + connect(this, SIGNAL(yChanged()), + this, SLOT(calcSystemOffset())); +} + +void QSGParticlePainter::componentComplete() +{ + if(!m_system) + qWarning() << "Particle created without a particle system specified";//TODO: useful QML warnings, like line number? + QSGItem::componentComplete(); +} + + +void QSGParticlePainter::setSystem(QSGParticleSystem *arg) +{ + if (m_system != arg) { + m_system = arg; + if(m_system){ + m_system->registerParticleType(this); + connect(m_system, SIGNAL(xChanged()), + this, SLOT(calcSystemOffset())); + connect(m_system, SIGNAL(yChanged()), + this, SLOT(calcSystemOffset())); + calcSystemOffset(); + } + emit systemChanged(arg); + } +} + +void QSGParticlePainter::load(QSGParticleData*) +{ +} + +void QSGParticlePainter::reload(QSGParticleData*) +{ +} + +void QSGParticlePainter::reset() +{ + //Have to every time because what it's emitting may have changed and that affects particleTypeIndex + m_particleStarts.clear(); + m_lastStart = 0; +} + +void QSGParticlePainter::setCount(int c) +{ + if(c == m_count) + return; + m_count = c; + emit countChanged(); +} + +int QSGParticlePainter::count() +{ + return m_count; +} + + +int QSGParticlePainter::particleTypeIndex(QSGParticleData* d) +{ + if(!m_particleStarts.contains(d->group)){ + m_particleStarts.insert(d->group, m_lastStart); + m_lastStart += m_system->m_groupData[d->group]->size; + } + int ret = m_particleStarts[d->group] + d->particleIndex; + Q_ASSERT(ret >=0 && ret < m_count);//XXX: Possibly shouldn't assert, but bugs here were hard to find in the past + return ret; +} + + +void QSGParticlePainter::calcSystemOffset() +{ + if(!m_system) + return; + QPointF lastOffset = m_systemOffset; + m_systemOffset = -1 * this->mapFromItem(m_system, QPointF()); + if(lastOffset != m_systemOffset){ + //Reload all particles//TODO: Necessary? + foreach(const QString &g, m_particles){ + int gId = m_system->m_groupIds[g]; + for(int i=0; im_groupData[gId]->size; i++) + reload(m_system->m_data[m_system->m_groupData[gId]->start + i]); + } + } +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgparticlepainter_p.h b/src/declarative/particles/qsgparticlepainter_p.h new file mode 100644 index 0000000000..8f1e13b70f --- /dev/null +++ b/src/declarative/particles/qsgparticlepainter_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLE_H +#define PARTICLE_H + +#include +#include +#include "qsgparticlesystem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGParticlePainter : public QSGItem +{ + Q_OBJECT + Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) + +public: + explicit QSGParticlePainter(QSGItem *parent = 0); + virtual void load(QSGParticleData*); + virtual void reload(QSGParticleData*); + virtual void setCount(int c); + virtual int count(); + QSGParticleSystem* system() const + { + return m_system; + } + + + QStringList particles() const + { + return m_particles; + } + + int particleTypeIndex(QSGParticleData*); +signals: + void countChanged(); + void systemChanged(QSGParticleSystem* arg); + + void particlesChanged(QStringList arg); + +public slots: +void setSystem(QSGParticleSystem* arg); + +void setParticles(QStringList arg) +{ + if (m_particles != arg) { + m_particles = arg; + emit particlesChanged(arg); + } +} +private slots: + void calcSystemOffset(); +protected: + virtual void reset(); + virtual void componentComplete(); + +// virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *){ +// qDebug() << "Shouldn't be here..." << this; +// return 0; +// } + + QSGParticleSystem* m_system; + friend class QSGParticleSystem; + int m_count; + bool m_pleaseReset; + QStringList m_particles; + QHash m_particleStarts; + int m_lastStart; + QPointF m_systemOffset; + + template + void vertexCopy(VertexStruct &b, const ParticleVertex& a) + { + b.x = a.x - m_systemOffset.x(); + b.y = a.y - m_systemOffset.y(); + b.t = a.t; + b.lifeSpan = a.lifeSpan; + b.size = a.size; + b.endSize = a.endSize; + b.sx = a.sx; + b.sy = a.sy; + b.ax = a.ax; + b.ay = a.ay; + } + +private: +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // PARTICLE_H diff --git a/src/declarative/particles/qsgparticlesmodule.cpp b/src/declarative/particles/qsgparticlesmodule.cpp new file mode 100644 index 0000000000..a7a9a9253f --- /dev/null +++ b/src/declarative/particles/qsgparticlesmodule.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgangleddirection_p.h" +#include "qsgcustomparticle_p.h" +#include "qsgellipseextruder_p.h" +#include "qsgemitter_p.h" +#include "qsgfollowemitter_p.h" +#include "qsgfriction_p.h" +#include "qsggravity_p.h" +#include "qsgimageparticle_p.h" +#include "qsgitemparticle_p.h" +#include "qsgkill_p.h" +#include "qsglineextruder_p.h" +#include "qsgmaskextruder_p.h" +#include "qsgmodelparticle_p.h" +#include "qsgparticleaffector_p.h" +#include "qsgparticleemitter_p.h" +#include "qsgparticleextruder_p.h" +#include "qsgparticlepainter_p.h" +#include "qsgparticlesmodule_p.h" +#include "qsgparticlesystem_p.h" +#include "qsgpointattractor_p.h" +#include "qsgpointdirection_p.h" +#include "qsgspritegoal_p.h" +#include "qsgstochasticdirection_p.h" +#include "qsgtargeteddirection_p.h" +#include "qsgturbulence_p.h" +#include "qsgwander_p.h" + +QT_BEGIN_NAMESPACE + +void QSGParticlesModule::defineModule() +{ + const char* uri = "QtQuick.Particles"; + //Debugging only exposition + qmlRegisterType(uri, 2, 0, "ParticlePainter"); + qmlRegisterType(uri, 2, 0, "ParticleEmitter"); + qmlRegisterType(uri, 2, 0, "ParticleExtruder"); + qmlRegisterType(uri, 2, 0, "NullVector"); + //Probably should be nocreate types + + qmlRegisterType(uri, 2, 0, "ParticleSystem"); + + qmlRegisterType(uri, 2, 0, "ImageParticle"); + qmlRegisterType(uri, 2, 0, "CustomParticle"); + qmlRegisterType(uri, 2, 0, "ItemParticle"); + qmlRegisterType(uri, 2, 0, "ModelParticle"); + + qmlRegisterType(uri, 2, 0, "Emitter"); + qmlRegisterType(uri, 2, 0, "FollowEmitter"); + + qmlRegisterType(uri, 2, 0, "EllipseShape"); + qmlRegisterType(uri, 2, 0, "LineShape"); + qmlRegisterType(uri, 2, 0, "MaskShape"); + + qmlRegisterType(uri, 2, 0, "PointDirection"); + qmlRegisterType(uri, 2, 0, "AngledDirection"); + qmlRegisterType(uri, 2, 0, "TargetedDirection"); + + qmlRegisterType(uri, 2, 0, "ParticleAffector");//if it has a triggered signal, it's useful + qmlRegisterType(uri, 2, 0, "Wander"); + qmlRegisterType(uri, 2, 0, "Friction"); + qmlRegisterType(uri, 2, 0, "PointAttractor"); + qmlRegisterType(uri, 2, 0, "Gravity"); + qmlRegisterType(uri, 2, 0, "Kill"); + qmlRegisterType(uri, 2, 0, "SpriteGoal"); + qmlRegisterType(uri, 2, 0 , "Turbulence"); +} + +QT_END_NAMESPACE + +//Q_EXPORT_PLUGIN2(Particles, QT_PREPEND_NAMESPACE(ParticlesModule)) diff --git a/src/declarative/particles/qsgparticlesmodule_p.h b/src/declarative/particles/qsgparticlesmodule_p.h new file mode 100644 index 0000000000..1afe0654f6 --- /dev/null +++ b/src/declarative/particles/qsgparticlesmodule_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGPARTICLESMODULE_H +#define QSGPARTICLESMODULE_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGParticlesModule +{ +public: + static void defineModule(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSGPARTICLESMODULE_H diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp new file mode 100644 index 0000000000..a2aa377c82 --- /dev/null +++ b/src/declarative/particles/qsgparticlesystem.cpp @@ -0,0 +1,396 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgparticlesystem_p.h" +#include +#include "qsgparticleemitter_p.h" +#include "qsgparticleaffector_p.h" +#include "qsgparticlepainter_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +QSGParticleData::QSGParticleData() + : group(0) + , e(0) + , particleIndex(0) + , systemIndex(0) +{ + pv.x = 0; + pv.y = 0; + pv.t = -1; + pv.size = 0; + pv.endSize = 0; + pv.sx = 0; + pv.sy = 0; + pv.ax = 0; + pv.ay = 0; +} + +QSGParticleSystem::QSGParticleSystem(QSGItem *parent) : + QSGItem(parent), m_particle_count(0), m_running(true) , m_startTime(0), m_overwrite(false) +{ + m_groupIds = QHash(); +} + +void QSGParticleSystem::registerParticleType(QSGParticlePainter* p) +{ + m_particles << QPointer(p);//###Set or uniqueness checking? + reset(); +} + +void QSGParticleSystem::registerParticleEmitter(QSGParticleEmitter* e) +{ + m_emitters << QPointer(e);//###How to get them out? + connect(e, SIGNAL(particleCountChanged()), + this, SLOT(countChanged())); + connect(e, SIGNAL(particleChanged(QString)), + this, SLOT(countChanged())); + reset(); +} + +void QSGParticleSystem::registerParticleAffector(QSGParticleAffector* a) +{ + m_affectors << QPointer(a); + //reset();//TODO: Slim down the huge batch of resets at the start +} + +void QSGParticleSystem::countChanged() +{ + reset();//Need to give Particles new Count +} + +void QSGParticleSystem::setRunning(bool arg) +{ + if (m_running != arg) { + m_running = arg; + emit runningChanged(arg); + reset(); + } +} + +void QSGParticleSystem::componentComplete() +{ + QSGItem::componentComplete(); + reset(); +} + +void QSGParticleSystem::initializeSystem() +{ + int oldCount = m_particle_count; + m_particle_count = 0;//TODO: Only when changed? + + //### Reset the data too? + for(int i=0; i::iterator iter = m_groupData.begin(); iter != m_groupData.end(); iter++) + delete (*iter); + m_groupData.clear(); + m_groupIds.clear(); + + GroupData* gd = new GroupData;//Default group + gd->size = 0; + gd->start = -1; + gd->nextIdx = 0; + m_groupData.insert(0,gd); + m_groupIds.insert("",0); + m_nextGroupId = 1; + + if(!m_emitters.count() || !m_particles.count()) + return; + + foreach(QSGParticleEmitter* e, m_emitters){ + if(!m_groupIds.contains(e->particle()) + || (!e->particle().isEmpty() && !m_groupIds[e->particle()])){//or it was accidentally inserted by a failed lookup earlier + GroupData* gd = new GroupData; + gd->size = 0; + gd->start = -1; + gd->nextIdx = 0; + int id = m_nextGroupId++; + m_groupIds.insert(e->particle(), id); + m_groupData.insert(id, gd); + } + m_groupData[m_groupIds[e->particle()]]->size += e->particleCount(); + } + + for(QHash::iterator iter = m_groupData.begin(); iter != m_groupData.end(); iter++){ + (*iter)->start = m_particle_count; + m_particle_count += (*iter)->size; + } + m_data.resize(m_particle_count); + for(int i=oldCount; i 16000) + qWarning() << "Particle system contains a vast number of particles (>16000). Expect poor performance"; + + foreach(QSGParticlePainter* particle, m_particles){ + int particleCount = 0; + if(particle->particles().isEmpty()){//Uses default particle + particleCount += m_groupData[0]->size; + m_groupData[0]->types << particle; + }else{ + foreach(const QString &group, particle->particles()){ + particleCount += m_groupData[m_groupIds[group]]->size; + m_groupData[m_groupIds[group]]->types << particle; + } + } + particle->setCount(particleCount); + particle->m_pleaseReset = true; + } + + m_timestamp.start(); + m_initialized = true; + emit systemInitialized(); + qDebug() << "System Initialized. Size:" << m_particle_count; +} + +void QSGParticleSystem::reset() +{ + //Clear guarded pointers which have been deleted + int cleared = 0; + cleared += m_emitters.removeAll(0); + cleared += m_particles.removeAll(0); + cleared += m_affectors.removeAll(0); + //qDebug() << "Reset" << m_emitters.count() << m_particles.count() << "Cleared" << cleared; + foreach(QSGParticlePainter* p, m_particles) + p->reset(); + foreach(QSGParticleEmitter* e, m_emitters) + e->reset(); + if(!m_running) + return; + initializeSystem(); + foreach(QSGParticlePainter* p, m_particles) + p->update(); + foreach(QSGParticleEmitter* e, m_emitters) + e->emitWindow(0);//Start, so that starttime factors appropriately +} + +QSGParticleData* QSGParticleSystem::newDatum(int groupId) +{ + Q_ASSERT(groupId < m_groupData.count());//XXX shouldn't really be an assert + Q_ASSERT(m_groupData[groupId]->size); + int nextIdx = m_groupData[groupId]->start + m_groupData[groupId]->nextIdx++; + if( m_groupData[groupId]->nextIdx >= m_groupData[groupId]->size) + m_groupData[groupId]->nextIdx = 0; + + Q_ASSERT(nextIdx < m_data.size()); + QSGParticleData* ret; + if(m_data[nextIdx]){//Recycle, it's faster. + ret = m_data[nextIdx]; + if(!m_overwrite && ret->stillAlive()){ + return 0;//Artificial longevity (or too fast emission) means this guy hasn't died. To maintain count, don't emit a new one + }//###Reset? + }else{ + ret = new QSGParticleData; + m_data[nextIdx] = ret; + } + + ret->system = this; + ret->systemIndex = nextIdx; + ret->particleIndex = nextIdx - m_groupData[groupId]->start; + ret->group = groupId; + return ret; +} + +void QSGParticleSystem::emitParticle(QSGParticleData* pd) +{// called from prepareNextFrame()->emitWindow - enforce? + //Account for relative emitter position + QPointF offset = this->mapFromItem(pd->e, QPointF(0, 0)); + if(!offset.isNull()){ + pd->pv.x += offset.x(); + pd->pv.y += offset.y(); + } + + foreach(QSGParticleAffector *a, m_affectors) + if(a && a->m_needsReset) + a->reset(pd->systemIndex); + foreach(QSGParticlePainter* p, m_groupData[pd->group]->types) + if(p) + p->load(pd); +} + + + +qint64 QSGParticleSystem::systemSync(QSGParticlePainter* p) +{ + if (!m_running) + return 0; + if (!m_initialized) + return 0;//error in initialization + + if(m_syncList.isEmpty() || m_syncList.contains(p)){//Need to advance the simulation + m_syncList.clear(); + + //### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time. + qreal dt = m_timeInt / 1000.; + m_timeInt = m_timestamp.elapsed() + m_startTime; + qreal time = m_timeInt / 1000.; + dt = time - dt; + m_needsReset.clear(); + foreach(QSGParticleEmitter* emitter, m_emitters) + if(emitter) + emitter->emitWindow(m_timeInt); + foreach(QSGParticleAffector* a, m_affectors) + if(a) + a->affectSystem(dt); + foreach(QSGParticleData* d, m_needsReset) + foreach(QSGParticlePainter* p, m_groupData[d->group]->types) + if(p && d) + p->reload(d); + } + m_syncList << p; + return m_timeInt; +} + +//sets the x accleration without affecting the instantaneous x velocity or position +void QSGParticleData::setInstantaneousAX(qreal ax) +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + qreal sx = (pv.sx + t*pv.ax) - t*ax; + qreal ex = pv.x + pv.sx * t + 0.5 * pv.ax * t * t; + qreal x = ex - t*sx - 0.5 * t*t*ax; + + pv.ax = ax; + pv.sx = sx; + pv.x = x; +} + +//sets the x velocity without affecting the instantaneous x postion +void QSGParticleData::setInstantaneousSX(qreal vx) +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + qreal sx = vx - t*pv.ax; + qreal ex = pv.x + pv.sx * t + 0.5 * pv.ax * t * t; + qreal x = ex - t*sx - 0.5 * t*t*pv.ax; + + pv.sx = sx; + pv.x = x; +} + +//sets the instantaneous x postion +void QSGParticleData::setInstantaneousX(qreal x) +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + pv.x = x - t*pv.sx - 0.5 * t*t*pv.ax; +} + +//sets the y accleration without affecting the instantaneous y velocity or position +void QSGParticleData::setInstantaneousAY(qreal ay) +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + qreal sy = (pv.sy + t*pv.ay) - t*ay; + qreal ey = pv.y + pv.sy * t + 0.5 * pv.ay * t * t; + qreal y = ey - t*sy - 0.5 * t*t*ay; + + pv.ay = ay; + pv.sy = sy; + pv.y = y; +} + +//sets the y velocity without affecting the instantaneous y position +void QSGParticleData::setInstantaneousSY(qreal vy) +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + //qDebug() << t << (system->m_timeInt/1000.0) << pv.x << pv.sx << pv.ax << pv.x + pv.sx * t + 0.5 * pv.ax * t * t; + qreal sy = vy - t*pv.ay; + qreal ey = pv.y + pv.sy * t + 0.5 * pv.ay * t * t; + qreal y = ey - t*sy - 0.5 * t*t*pv.ay; + + pv.sy = sy; + pv.y = y; +} + +//sets the instantaneous Y position +void QSGParticleData::setInstantaneousY(qreal y) +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + pv.y = y - t*pv.sy - 0.5 * t*t*pv.ay; +} + +qreal QSGParticleData::curX() const +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + return pv.x + pv.sx * t + 0.5 * pv.ax * t * t; +} + +qreal QSGParticleData::curSX() const +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + return pv.sx + t*pv.ax; +} + +qreal QSGParticleData::curY() const +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + return pv.y + pv.sy * t + 0.5 * pv.ay * t * t; +} + +qreal QSGParticleData::curSY() const +{ + qreal t = (system->m_timeInt / 1000.0) - pv.t; + return pv.sy + t*pv.ay; +} + +void QSGParticleData::debugDump() +{ + qDebug() << "Particle" << group + << "Pos: " << pv.x << "," << pv.y + << "Vel: " << pv.sx << "," << pv.sy + << "Acc: " << pv.ax << "," << pv.ay + << "Size: " << pv.size << "," << pv.endSize + << "Time: " << pv.t << "," < (system->m_timeInt/1000.0); +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h new file mode 100644 index 0000000000..aab3c5d50f --- /dev/null +++ b/src/declarative/particles/qsgparticlesystem_p.h @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLESYSTEM_H +#define PARTICLESYSTEM_H + +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGParticleAffector; +class QSGParticleEmitter; +class QSGParticlePainter; +class QSGParticleData; + + +struct GroupData{ + int size; + int start; + int nextIdx; + QList types; +}; + +class QSGParticleSystem : public QSGItem +{ + Q_OBJECT + Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) + Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) + Q_PROPERTY(bool overwrite READ overwrite WRITE setOverwrite NOTIFY overwriteChanged)//XXX: Should just be an implementation detail, but I can't decide which way + /* The problem is that it ought to be false (usually) for stasis effects like model particles, + but it ought to be true (usually) for burst effects where you want it to burst, and forget the old stuff + Ideally burst never overflows? But that leads to crappy behaviour from crappy users... + */ + +public: + explicit QSGParticleSystem(QSGItem *parent = 0); + +bool isRunning() const +{ + return m_running; +} + +int startTime() const +{ + return m_startTime; +} + +int count(){ return m_particle_count; } + +signals: + +void systemInitialized(); +void runningChanged(bool arg); + +void startTimeChanged(int arg); + + +void overwriteChanged(bool arg); + +public slots: +void reset(); +void setRunning(bool arg); + + +void setStartTime(int arg) +{ + m_startTime = arg; +} + +void setOverwrite(bool arg) +{ + if (m_overwrite != arg) { + m_overwrite = arg; +emit overwriteChanged(arg); +} +} + +void fastForward(int ms) +{ + m_startTime += ms; +} + +protected: + void componentComplete(); + +private slots: + void countChanged(); +public://but only really for related class usage. Perhaps we should all be friends? + void emitParticle(QSGParticleData* p); + QSGParticleData* newDatum(int groupId); + qint64 systemSync(QSGParticlePainter* p); + QElapsedTimer m_timestamp; + QVector m_data; + QSet m_needsReset; + QHash m_groupIds; + QHash m_groupData;//id, size, start + qint64 m_timeInt; + bool m_initialized; + + void registerParticleType(QSGParticlePainter* p); + void registerParticleEmitter(QSGParticleEmitter* e); + void registerParticleAffector(QSGParticleAffector* a); + bool overwrite() const + { + return m_overwrite; + } + + int m_particle_count; +private: + void initializeSystem(); + bool m_running; + QList > m_emitters; + QList > m_affectors; + QList > m_particles; + QList > m_syncList; + qint64 m_startTime; + int m_nextGroupId; + bool m_overwrite; +}; + +//TODO: Clean up all this into ParticleData + +struct ParticleVertex { + float x; + float y; + float t; + float lifeSpan; + float size; + float endSize; + float sx; + float sy; + float ax; + float ay; + //TODO: Need opacity over life control. More variable size over life? +}; + +class QSGParticleData{ +public: + QSGParticleData(); + + ParticleVertex pv; + + //Convenience functions for working backwards, because parameters are from the start of particle life + //If setting multiple parameters at once, doing the conversion yourself will be faster. + + //sets the x accleration without affecting the instantaneous x velocity or position + void setInstantaneousAX(qreal ax); + //sets the x velocity without affecting the instantaneous x postion + void setInstantaneousSX(qreal vx); + //sets the instantaneous x postion + void setInstantaneousX(qreal x); + //sets the y accleration without affecting the instantaneous y velocity or position + void setInstantaneousAY(qreal ay); + //sets the y velocity without affecting the instantaneous y postion + void setInstantaneousSY(qreal vy); + //sets the instantaneous Y postion + void setInstantaneousY(qreal y); + + //TODO: Slight caching? + qreal curX() const; + qreal curSX() const; + qreal curY() const; + qreal curSY() const; + + int group; + QSGParticleEmitter* e; + QSGParticleSystem* system; + int particleIndex; + int systemIndex; + + void debugDump(); + bool stillAlive(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // PARTICLESYSTEM_H + + diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp new file mode 100644 index 0000000000..3c3ca33086 --- /dev/null +++ b/src/declarative/particles/qsgpointattractor.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgpointattractor_p.h" +#include +#include +QT_BEGIN_NAMESPACE +QSGPointAttractorAffector::QSGPointAttractorAffector(QSGItem *parent) : + QSGParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) +{ +} + +bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + if(m_strength == 0.0) + return false; + qreal dx = m_x - d->curX(); + qreal dy = m_y - d->curY(); + qreal r = sqrt((dx*dx) + (dy*dy)); + qreal theta = atan2(dy,dx); + qreal ds = (m_strength / r) * dt; + dx = ds * cos(theta); + dy = ds * sin(theta); + d->setInstantaneousSX(d->pv.sx + dx); + d->setInstantaneousSY(d->pv.sy + dy); + return true; +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgpointattractor_p.h b/src/declarative/particles/qsgpointattractor_p.h new file mode 100644 index 0000000000..d4f715928a --- /dev/null +++ b/src/declarative/particles/qsgpointattractor_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ATTRACTORAFFECTOR_H +#define ATTRACTORAFFECTOR_H +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGPointAttractorAffector : public QSGParticleAffector +{ + Q_OBJECT + //Like Gravitational singularity, but linear to distance instead of quadratic + //And affects ds/dt, not da/dt + Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) +public: + explicit QSGPointAttractorAffector(QSGItem *parent = 0); + + qreal strength() const + { + return m_strength; + } + + qreal x() const + { + return m_x; + } + + qreal y() const + { + return m_y; + } + +signals: + + void strengthChanged(qreal arg); + + void xChanged(qreal arg); + + void yChanged(qreal arg); + +public slots: +void setStrength(qreal arg) +{ + if (m_strength != arg) { + m_strength = arg; + emit strengthChanged(arg); + } +} + +void setX(qreal arg) +{ + if (m_x != arg) { + m_x = arg; + emit xChanged(arg); + } +} + +void setY(qreal arg) +{ + if (m_y != arg) { + m_y = arg; + emit yChanged(arg); + } +} +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +private: +qreal m_strength; +qreal m_x; +qreal m_y; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // ATTRACTORAFFECTOR_H diff --git a/src/declarative/particles/qsgpointdirection.cpp b/src/declarative/particles/qsgpointdirection.cpp new file mode 100644 index 0000000000..c3c4f1c5de --- /dev/null +++ b/src/declarative/particles/qsgpointdirection.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgpointdirection_p.h" + +QT_BEGIN_NAMESPACE + +QSGPointDirection::QSGPointDirection(QObject *parent) : + QSGStochasticDirection(parent) + , m_x(0) + , m_y(0) + , m_xVariation(0) + , m_yVariation(0) +{ +} + +const QPointF &QSGPointDirection::sample(const QPointF &) +{ + m_ret.setX(m_x - m_xVariation + rand() / float(RAND_MAX) * m_xVariation * 2); + m_ret.setY(m_y - m_yVariation + rand() / float(RAND_MAX) * m_yVariation * 2); + return m_ret; +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgpointdirection_p.h b/src/declarative/particles/qsgpointdirection_p.h new file mode 100644 index 0000000000..5e5b052744 --- /dev/null +++ b/src/declarative/particles/qsgpointdirection_p.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef POINTVECTOR_H +#define POINTVECTOR_H +#include "qsgstochasticdirection_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGPointDirection : public QSGStochasticDirection +{ + Q_OBJECT + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) + Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged) + Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged) +public: + explicit QSGPointDirection(QObject *parent = 0); + virtual const QPointF &sample(const QPointF &from); + qreal x() const + { + return m_x; + } + + qreal y() const + { + return m_y; + } + + qreal xVariation() const + { + return m_xVariation; + } + + qreal yVariation() const + { + return m_yVariation; + } + +signals: + + void xChanged(qreal arg); + + void yChanged(qreal arg); + + void xVariationChanged(qreal arg); + + void yVariationChanged(qreal arg); + +public slots: + void setX(qreal arg) + { + if (m_x != arg) { + m_x = arg; + emit xChanged(arg); + } + } + + void setY(qreal arg) + { + if (m_y != arg) { + m_y = arg; + emit yChanged(arg); + } + } + + void setXVariation(qreal arg) + { + if (m_xVariation != arg) { + m_xVariation = arg; + emit xVariationChanged(arg); + } + } + + void setYVariation(qreal arg) + { + if (m_yVariation != arg) { + m_yVariation = arg; + emit yVariationChanged(arg); + } + } + +private: + + qreal m_x; + qreal m_y; + qreal m_xVariation; + qreal m_yVariation; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // POINTVECTOR_H diff --git a/src/declarative/particles/qsgspritegoal.cpp b/src/declarative/particles/qsgspritegoal.cpp new file mode 100644 index 0000000000..8dc98ae314 --- /dev/null +++ b/src/declarative/particles/qsgspritegoal.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgspritegoal_p.h" +#include "private/qsgspriteengine_p.h" +#include "private/qsgsprite_p.h" +#include "qsgimageparticle_p.h" +#include + +QT_BEGIN_NAMESPACE + +QSGSpriteGoalAffector::QSGSpriteGoalAffector(QSGItem *parent) : + QSGParticleAffector(parent), m_goalIdx(-1), m_jump(false) +{ +} + +void QSGSpriteGoalAffector::updateStateIndex(QSGSpriteEngine* e) +{ + m_lastEngine = e; + for(int i=0; istateCount(); i++){ + if(e->state(i)->name() == m_goalState){ + m_goalIdx = i; + return; + } + } + m_goalIdx = -1;//Can't find it +} + +void QSGSpriteGoalAffector::setGoalState(QString arg) +{ + if (m_goalState != arg) { + m_goalState = arg; + emit goalStateChanged(arg); + if(m_goalState.isEmpty()) + m_goalIdx = -1; + else + m_goalIdx = -2; + } +} + +bool QSGSpriteGoalAffector::affectParticle(QSGParticleData *d, qreal dt) +{ + Q_UNUSED(dt); + //TODO: Affect all engines + QSGSpriteEngine *engine = 0; + foreach(QSGParticlePainter *p, m_system->m_groupData[d->group]->types) + if(qobject_cast(p)) + engine = qobject_cast(p)->spriteEngine(); + if(!engine) + return false; + + if(m_goalIdx == -2 || engine != m_lastEngine) + updateStateIndex(engine); + if(engine->spriteState(d->particleIndex) != m_goalIdx){ + engine->setGoal(m_goalIdx, d->particleIndex, m_jump); + emit affected(QPointF(d->curX(), d->curY()));//###Expensive if unconnected? Move to Affector? + return true; //Doesn't affect particle data, but necessary for onceOff + } + return false; +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgspritegoal_p.h b/src/declarative/particles/qsgspritegoal_p.h new file mode 100644 index 0000000000..28fb2939e6 --- /dev/null +++ b/src/declarative/particles/qsgspritegoal_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPRITEGOALAFFECTOR_H +#define SPRITEGOALAFFECTOR_H +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGSpriteEngine; + +class QSGSpriteGoalAffector : public QSGParticleAffector +{ + Q_OBJECT + Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) + Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) +public: + explicit QSGSpriteGoalAffector(QSGItem *parent = 0); + + QString goalState() const + { + return m_goalState; + } + + bool jump() const + { + return m_jump; + } +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +signals: + + void goalStateChanged(QString arg); + + void jumpChanged(bool arg); + + void affected(const QPointF &pos); +public slots: + +void setGoalState(QString arg); + +void setJump(bool arg) +{ + if (m_jump != arg) { + m_jump = arg; + emit jumpChanged(arg); + } +} + +private: + void updateStateIndex(QSGSpriteEngine* e); + QString m_goalState; + int m_goalIdx; + QSGSpriteEngine* m_lastEngine; + bool m_jump; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SPRITEGOALAFFECTOR_H diff --git a/src/declarative/particles/qsgstochasticdirection.cpp b/src/declarative/particles/qsgstochasticdirection.cpp new file mode 100644 index 0000000000..3673b9c7a7 --- /dev/null +++ b/src/declarative/particles/qsgstochasticdirection.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgstochasticdirection_p.h" + +QT_BEGIN_NAMESPACE + +QSGStochasticDirection::QSGStochasticDirection(QObject *parent) : + QObject(parent) +{ +} + +const QPointF &QSGStochasticDirection::sample(const QPointF &from) +{ + return m_ret; +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgstochasticdirection_p.h b/src/declarative/particles/qsgstochasticdirection_p.h new file mode 100644 index 0000000000..da3a4302b1 --- /dev/null +++ b/src/declarative/particles/qsgstochasticdirection_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VARYINGVECTOR_H +#define VARYINGVECTOR_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGStochasticDirection : public QObject +{ + Q_OBJECT +public: + explicit QSGStochasticDirection(QObject *parent = 0); + + virtual const QPointF &sample(const QPointF &from); +signals: + +public slots: + +protected: + QPointF m_ret; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // VARYINGVECTOR_H diff --git a/src/declarative/particles/qsgtargeteddirection.cpp b/src/declarative/particles/qsgtargeteddirection.cpp new file mode 100644 index 0000000000..9f1a868512 --- /dev/null +++ b/src/declarative/particles/qsgtargeteddirection.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgtargeteddirection_p.h" +#include "qsgparticleemitter_p.h" +#include +#include + +QT_BEGIN_NAMESPACE +QSGTargetedDirection::QSGTargetedDirection(QObject *parent) : + QSGStochasticDirection(parent) + , m_targetX(0) + , m_targetY(0) + , m_targetVariation(0) + , m_proportionalMagnitude(false) + , m_magnitude(0) + , m_magnitudeVariation(0) + , m_targetItem(0) +{ +} + +const QPointF &QSGTargetedDirection::sample(const QPointF &from) +{ + //###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile? + qreal targetX; + qreal targetY; + if(m_targetItem){ + QSGParticleEmitter* parentEmitter = qobject_cast(parent()); + targetX = m_targetItem->width()/2; + targetY = m_targetItem->height()/2; + if(!parentEmitter){ + qWarning() << "Directed vector is not a child of the emitter. Mapping of target item coordinates may fail."; + targetX += m_targetItem->x(); + targetY += m_targetItem->y(); + }else{ + m_ret = parentEmitter->mapFromItem(m_targetItem, QPointF(targetX, targetY)); + targetX = m_ret.x(); + targetY = m_ret.y(); + } + }else{ + targetX = m_targetX; + targetY = m_targetY; + } + targetX += 0 - from.x() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; + targetY += 0 - from.y() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; + qreal theta = atan2(targetY, targetX); + qreal mag = m_magnitude + rand()/(float)RAND_MAX * m_magnitudeVariation * 2 - m_magnitudeVariation; + if(m_proportionalMagnitude) + mag *= sqrt(targetX * targetX + targetY * targetY); + m_ret.setX(mag * cos(theta)); + m_ret.setY(mag * sin(theta)); + return m_ret; +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgtargeteddirection_p.h b/src/declarative/particles/qsgtargeteddirection_p.h new file mode 100644 index 0000000000..4010505858 --- /dev/null +++ b/src/declarative/particles/qsgtargeteddirection_p.h @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTEDVECTOR_H +#define DIRECTEDVECTOR_H +#include "qsgstochasticdirection_p.h" +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGItem; +class QSGTargetedDirection : public QSGStochasticDirection +{ + Q_OBJECT + Q_PROPERTY(qreal targetX READ targetX WRITE setTargetX NOTIFY targetXChanged) + Q_PROPERTY(qreal targetY READ targetY WRITE setTargetY NOTIFY targetYChanged) + //If targetItem is set, X/Y are ignored. Aims at middle of item, use variation for variation + Q_PROPERTY(QSGItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged) + + Q_PROPERTY(qreal targetVariation READ targetVariation WRITE setTargetVariation NOTIFY targetVariationChanged) + + Q_PROPERTY(bool proportionalMagnitude READ proportionalMagnitude WRITE setProportionalMagnitude NOTIFY proprotionalMagnitudeChanged) + Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) + Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) + +public: + explicit QSGTargetedDirection(QObject *parent = 0); + virtual const QPointF &sample(const QPointF &from); + + qreal targetX() const + { + return m_targetX; + } + + qreal targetY() const + { + return m_targetY; + } + + qreal targetVariation() const + { + return m_targetVariation; + } + + qreal magnitude() const + { + return m_magnitude; + } + + bool proportionalMagnitude() const + { + return m_proportionalMagnitude; + } + + qreal magnitudeVariation() const + { + return m_magnitudeVariation; + } + + QSGItem* targetItem() const + { + return m_targetItem; + } + +signals: + + void targetXChanged(qreal arg); + + void targetYChanged(qreal arg); + + void targetVariationChanged(qreal arg); + + void magnitudeChanged(qreal arg); + + void proprotionalMagnitudeChanged(bool arg); + + void magnitudeVariationChanged(qreal arg); + + void targetItemChanged(QSGItem* arg); + +public slots: + void setTargetX(qreal arg) + { + if (m_targetX != arg) { + m_targetX = arg; + emit targetXChanged(arg); + } + } + + void setTargetY(qreal arg) + { + if (m_targetY != arg) { + m_targetY = arg; + emit targetYChanged(arg); + } + } + + void setTargetVariation(qreal arg) + { + if (m_targetVariation != arg) { + m_targetVariation = arg; + emit targetVariationChanged(arg); + } + } + + void setMagnitude(qreal arg) + { + if (m_magnitude != arg) { + m_magnitude = arg; + emit magnitudeChanged(arg); + } + } + + void setProportionalMagnitude(bool arg) + { + if (m_proportionalMagnitude != arg) { + m_proportionalMagnitude = arg; + emit proprotionalMagnitudeChanged(arg); + } + } + + void setMagnitudeVariation(qreal arg) + { + if (m_magnitudeVariation != arg) { + m_magnitudeVariation = arg; + emit magnitudeVariationChanged(arg); + } + } + + void setTargetItem(QSGItem* arg) + { + if (m_targetItem != arg) { + m_targetItem = arg; + emit targetItemChanged(arg); + } + } + +private: + qreal m_targetX; + qreal m_targetY; + qreal m_targetVariation; + bool m_proportionalMagnitude; + qreal m_magnitude; + qreal m_magnitudeVariation; + QSGItem *m_targetItem; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // DIRECTEDVECTOR_H diff --git a/src/declarative/particles/qsgturbulence.cpp b/src/declarative/particles/qsgturbulence.cpp new file mode 100644 index 0000000000..476db9c4b0 --- /dev/null +++ b/src/declarative/particles/qsgturbulence.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgturbulence_p.h" +#include "qsgparticlepainter_p.h"//TODO: Why was this needed again? +#include +#include +#include +QT_BEGIN_NAMESPACE + +QSGTurbulenceAffector::QSGTurbulenceAffector(QSGItem *parent) : + QSGParticleAffector(parent), + m_strength(10), m_lastT(0), m_frequency(64), m_gridSize(10), m_field(0), m_inited(false) +{ + //TODO: Update grid on size change +} + +QSGTurbulenceAffector::~QSGTurbulenceAffector() +{ + if (m_field) { + for(int i=0; i m_strength){ + //Speed limit + qreal theta = atan2(m_field[i][j].y(), m_field[i][j].x()); + m_field[i][j].setX(m_strength * cos(theta)); + m_field[i][j].setY(m_strength * sin(theta)); + } + } + } +} + + +void QSGTurbulenceAffector::affectSystem(qreal dt) +{ + if(!m_system || !m_active) + return; + ensureInit(); + qreal period = 1.0/m_frequency; + qreal time = m_system->m_timeInt / 1000.0; + while( m_lastT < time ){ + mapUpdate(); + m_lastT += period; + } + + foreach(QSGParticleData *d, m_system->m_data){ + if(!d || !activeGroup(d->group)) + return; + qreal fx = 0.0; + qreal fy = 0.0; + QPointF pos = QPointF(d->curX() - x(), d->curY() - y());//TODO: Offset + QPointF nodePos = QPointF(pos.x() / m_spacing.x(), pos.y() / m_spacing.y()); + QSet > nodes; + nodes << qMakePair((int)ceil(nodePos.x()), (int)ceil(nodePos.y())); + nodes << qMakePair((int)ceil(nodePos.x()), (int)floor(nodePos.y())); + nodes << qMakePair((int)floor(nodePos.x()), (int)ceil(nodePos.y())); + nodes << qMakePair((int)floor(nodePos.x()), (int)floor(nodePos.y())); + typedef QPair intPair; + foreach(const intPair &p, nodes){ + if(!QRect(0,0,m_gridSize-1,m_gridSize-1).contains(QPoint(p.first, p.second))) + continue; + qreal dist = magnitude(pos.x() - p.first*m_spacing.x(), pos.y() - p.second*m_spacing.y());//TODO: Mathematically valid + fx += m_field[p.first][p.second].x() * ((m_magSum - dist)/m_magSum);//Proportionally weight nodes + fy += m_field[p.first][p.second].y() * ((m_magSum - dist)/m_magSum); + } + if(fx || fy){ + d->setInstantaneousSX(d->curSX()+ fx * dt); + d->setInstantaneousSY(d->curSY()+ fy * dt); + m_system->m_needsReset << d; + } + } +} + +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgturbulence_p.h b/src/declarative/particles/qsgturbulence_p.h new file mode 100644 index 0000000000..29483fbc70 --- /dev/null +++ b/src/declarative/particles/qsgturbulence_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TURBULENCEAFFECTOR_H +#define TURBULENCEAFFECTOR_H +#include "qsgparticleaffector_p.h" +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class QSGParticlePainter; + +class QSGTurbulenceAffector : public QSGParticleAffector +{ + Q_OBJECT + Q_PROPERTY(int strength READ strength WRITE setStrength NOTIFY strengthChanged) + Q_PROPERTY(int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged) + Q_PROPERTY(int gridSize READ size WRITE setSize NOTIFY sizeChanged) +public: + explicit QSGTurbulenceAffector(QSGItem *parent = 0); + ~QSGTurbulenceAffector(); + virtual void affectSystem(qreal dt); + + int strength() const + { + return m_strength; + } + + int frequency() const + { + return m_frequency; + } + + int size() const + { + return m_gridSize; + } + +signals: + + void strengthChanged(int arg); + + void frequencyChanged(int arg); + + void sizeChanged(int arg); + +public slots: + +void setStrength(int arg) +{ + if (m_strength != arg) { + m_strength = arg; + emit strengthChanged(arg); + } +} + +void setFrequency(int arg) +{ + if (m_frequency != arg) { + m_frequency = arg; + emit frequencyChanged(arg); + } +} + +void setSize(int arg); + +private: + void ensureInit(); + void mapUpdate(); + int m_strength; + qreal m_lastT; + int m_frequency; + int m_gridSize; + QPointF** m_field; + QPointF m_spacing; + qreal m_magSum; + bool m_inited; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // TURBULENCEAFFECTOR_H diff --git a/src/declarative/particles/qsgwander.cpp b/src/declarative/particles/qsgwander.cpp new file mode 100644 index 0000000000..e6787f2570 --- /dev/null +++ b/src/declarative/particles/qsgwander.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgwander_p.h" +#include "qsgparticlesystem_p.h"//for ParticlesVertices +QT_BEGIN_NAMESPACE + +QSGWanderAffector::QSGWanderAffector(QSGItem *parent) : + QSGParticleAffector(parent) +{ + m_needsReset = true; +} + +QSGWanderAffector::~QSGWanderAffector() +{ + for(QHash::const_iterator iter=m_wanderData.constBegin(); + iter != m_wanderData.constEnd(); iter++) + delete (*iter); +} + +WanderData* QSGWanderAffector::getData(int idx) +{ + if(m_wanderData.contains(idx)) + return m_wanderData[idx]; + WanderData* d = new WanderData; + d->x_vel = 0; + d->y_vel = 0; + d->x_peak = m_xVariance; + d->y_peak = m_yVariance; + d->x_var = m_pace * qreal(qrand()) / RAND_MAX; + d->y_var = m_pace * qreal(qrand()) / RAND_MAX; + + m_wanderData.insert(idx, d); + return d; +} + +void QSGWanderAffector::reset(int systemIdx) +{ + if(m_wanderData.contains(systemIdx)) + delete m_wanderData[systemIdx]; + m_wanderData.remove(systemIdx); +} + +bool QSGWanderAffector::affectParticle(QSGParticleData* data, qreal dt) +{ + WanderData* d = getData(data->systemIndex); + if (m_xVariance != 0.) { + if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) { + d->x_var = -d->x_var; + d->x_peak = m_xVariance + m_xVariance * qreal(qrand()) / RAND_MAX; + } + d->x_vel += d->x_var * dt; + } + qreal dx = dt * d->x_vel; + + if (m_yVariance != 0.) { + if ((d->y_vel > d->y_peak && d->y_var > 0.0) || (d->y_vel < -d->y_peak && d->y_var < 0.0)) { + d->y_var = -d->y_var; + d->y_peak = m_yVariance + m_yVariance * qreal(qrand()) / RAND_MAX; + } + d->y_vel += d->y_var * dt; + } + qreal dy = dt * d->x_vel; + + //### Should we be amending vel instead? + ParticleVertex* p = &(data->pv); + p->x += dx; + + p->y += dy; + return true; +} +QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgwander_p.h b/src/declarative/particles/qsgwander_p.h new file mode 100644 index 0000000000..45c8ca8b20 --- /dev/null +++ b/src/declarative/particles/qsgwander_p.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WANDERAFFECTOR_H +#define WANDERAFFECTOR_H +#include +#include "qsgparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +struct WanderData{ + qreal x_vel; + qreal y_vel; + qreal x_peak; + qreal x_var; + qreal y_peak; + qreal y_var; +}; + +class QSGWanderAffector : public QSGParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged) + Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) + Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) + +public: + explicit QSGWanderAffector(QSGItem *parent = 0); + ~QSGWanderAffector(); + virtual void reset(int systemIdx); + + qreal xVariance() const + { + return m_xVariance; + } + + qreal yVariance() const + { + return m_yVariance; + } + + qreal pace() const + { + return m_pace; + } +protected: + virtual bool affectParticle(QSGParticleData *d, qreal dt); +signals: + + void xVarianceChanged(qreal arg); + + void yVarianceChanged(qreal arg); + + void paceChanged(qreal arg); + +public slots: +void setXVariance(qreal arg) +{ + if (m_xVariance != arg) { + m_xVariance = arg; + emit xVarianceChanged(arg); + } +} + +void setYVariance(qreal arg) +{ + if (m_yVariance != arg) { + m_yVariance = arg; + emit yVarianceChanged(arg); + } +} + +void setPace(qreal arg) +{ + if (m_pace != arg) { + m_pace = arg; + emit paceChanged(arg); + } +} + +private: + WanderData* getData(int idx); + QHash m_wanderData; + qreal m_xVariance; + qreal m_yVariance; + qreal m_pace; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // WANDERAFFECTOR_H diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 80845b4c81..ab481ac87d 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -106,6 +106,7 @@ #include #include #include +#include #include #ifdef Q_OS_WIN // for %APPDATA% @@ -362,6 +363,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) QDeclarativeUtilModule::defineModule(); QDeclarativeEnginePrivate::defineModule(); QSGItemsModule::defineModule(); + QSGParticlesModule::defineModule(); QDeclarativeValueTypeFactory::registerValueTypes(); } globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine); diff --git a/src/imports/particles/angledvector.cpp b/src/imports/particles/angledvector.cpp deleted file mode 100644 index 85b5ed7472..0000000000 --- a/src/imports/particles/angledvector.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "angledvector.h" -#include -QT_BEGIN_NAMESPACE -const qreal CONV = 0.017453292519943295; -AngledVector::AngledVector(QObject *parent) : - VaryingVector(parent) - , m_angle(0) - , m_magnitude(0) - , m_angleVariation(0) - , m_magnitudeVariation(0) -{ - -} - -const QPointF &AngledVector::sample(const QPointF &from) -{ - //TODO: Faster - qreal theta = m_angle*CONV - m_angleVariation*CONV + rand()/float(RAND_MAX) * m_angleVariation*CONV * 2; - qreal mag = m_magnitude- m_magnitudeVariation + rand()/float(RAND_MAX) * m_magnitudeVariation * 2; - m_ret.setX(mag * cos(theta)); - m_ret.setY(mag * sin(theta)); - return m_ret; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/angledvector.h b/src/imports/particles/angledvector.h deleted file mode 100644 index ac78059e43..0000000000 --- a/src/imports/particles/angledvector.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANGLEDVECTOR_H -#define ANGLEDVECTOR_H -#include "varyingvector.h" -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class AngledVector : public VaryingVector -{ - Q_OBJECT - Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) - Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) - Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged) - Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) -public: - explicit AngledVector(QObject *parent = 0); - const QPointF &sample(const QPointF &from); - qreal angle() const - { - return m_angle; - } - - qreal magnitude() const - { - return m_magnitude; - } - - qreal angleVariation() const - { - return m_angleVariation; - } - - qreal magnitudeVariation() const - { - return m_magnitudeVariation; - } - -signals: - - void angleChanged(qreal arg); - - void magnitudeChanged(qreal arg); - - void angleVariationChanged(qreal arg); - - void magnitudeVariationChanged(qreal arg); - -public slots: -void setAngle(qreal arg) -{ - if (m_angle != arg) { - m_angle = arg; - emit angleChanged(arg); - } -} - -void setMagnitude(qreal arg) -{ - if (m_magnitude != arg) { - m_magnitude = arg; - emit magnitudeChanged(arg); - } -} - -void setAngleVariation(qreal arg) -{ - if (m_angleVariation != arg) { - m_angleVariation = arg; - emit angleVariationChanged(arg); - } -} - -void setMagnitudeVariation(qreal arg) -{ - if (m_magnitudeVariation != arg) { - m_magnitudeVariation = arg; - emit magnitudeVariationChanged(arg); - } -} - -private: -qreal m_angle; -qreal m_magnitude; -qreal m_angleVariation; -qreal m_magnitudeVariation; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ANGLEDVECTOR_H diff --git a/src/imports/particles/attractoraffector.cpp b/src/imports/particles/attractoraffector.cpp deleted file mode 100644 index 847cb2c471..0000000000 --- a/src/imports/particles/attractoraffector.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "attractoraffector.h" -#include -#include -QT_BEGIN_NAMESPACE -AttractorAffector::AttractorAffector(QSGItem *parent) : - ParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) -{ -} - -bool AttractorAffector::affectParticle(ParticleData *d, qreal dt) -{ - if(m_strength == 0.0) - return false; - qreal dx = m_x - d->curX(); - qreal dy = m_y - d->curY(); - qreal r = sqrt((dx*dx) + (dy*dy)); - qreal theta = atan2(dy,dx); - qreal ds = (m_strength / r) * dt; - dx = ds * cos(theta); - dy = ds * sin(theta); - d->setInstantaneousSX(d->pv.sx + dx); - d->setInstantaneousSY(d->pv.sy + dy); - return true; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/attractoraffector.h b/src/imports/particles/attractoraffector.h deleted file mode 100644 index f41e9ad5e4..0000000000 --- a/src/imports/particles/attractoraffector.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ATTRACTORAFFECTOR_H -#define ATTRACTORAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class AttractorAffector : public ParticleAffector -{ - Q_OBJECT - //Like Gravitational singularity, but linear to distance instead of quadratic - //And affects ds/dt, not da/dt - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) -public: - explicit AttractorAffector(QSGItem *parent = 0); - - qreal strength() const - { - return m_strength; - } - - qreal x() const - { - return m_x; - } - - qreal y() const - { - return m_y; - } - -signals: - - void strengthChanged(qreal arg); - - void xChanged(qreal arg); - - void yChanged(qreal arg); - -public slots: -void setStrength(qreal arg) -{ - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); - } -} - -void setX(qreal arg) -{ - if (m_x != arg) { - m_x = arg; - emit xChanged(arg); - } -} - -void setY(qreal arg) -{ - if (m_y != arg) { - m_y = arg; - emit yChanged(arg); - } -} -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -private: -qreal m_strength; -qreal m_x; -qreal m_y; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ATTRACTORAFFECTOR_H diff --git a/src/imports/particles/burstemitter.cpp b/src/imports/particles/burstemitter.cpp deleted file mode 100644 index a817172486..0000000000 --- a/src/imports/particles/burstemitter.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "burstemitter.h" -QT_BEGIN_NAMESPACE - -void BurstEmitter::burst(int count, qreal x, qreal y) -{ - qreal oldX = QSGItem::x(); - qreal oldY = QSGItem::y(); - setX(x); - setY(y); - TrailsEmitter::burst(count); - setX(oldX); - setY(oldY); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/burstemitter.h b/src/imports/particles/burstemitter.h deleted file mode 100644 index cffa7911af..0000000000 --- a/src/imports/particles/burstemitter.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BURSTEMITTER_H -#define BURSTEMITTER_H - -#include "trailsemitter.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -//Convenience Class - can't do function overloads in QML? -class BurstEmitter : public TrailsEmitter -{ - Q_OBJECT -public: - explicit BurstEmitter(QSGItem* parent = 0):TrailsEmitter(parent){} -public slots: - void burst(int count, qreal x, qreal y); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/imports/particles/coloredparticle.cpp b/src/imports/particles/coloredparticle.cpp deleted file mode 100644 index 22ef2d2eba..0000000000 --- a/src/imports/particles/coloredparticle.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "coloredparticle.h" -#include "particleemitter.h" -#include -#include - -QT_BEGIN_NAMESPACE - -class ParticleTrailsMaterial : public QSGMaterial -{ -public: - ParticleTrailsMaterial() - : timestamp(0) - { - setFlag(Blending, true); - } - - ~ParticleTrailsMaterial() - { - delete texture; - } - - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const - { - return this - static_cast(other); - } - - QSGTexture *texture; - - qreal timestamp; -}; - - -class ParticleTrailsMaterialData : public QSGMaterialShader -{ -public: - ParticleTrailsMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/trailsvertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/trailsfragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - ParticleTrailsMaterial *m = static_cast(newEffect); - state.context()->functions()->glActiveTexture(GL_TEXTURE0); - m->texture->bind(); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vPos", - "vTex", - "vData", - "vVec", - "vColor", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float ParticleTrailsMaterialData::chunkOfBytes[1024]; - - -QSGMaterialShader *ParticleTrailsMaterial::createShader() const -{ - return new ParticleTrailsMaterialData; -} - - -class ParticleTrailsMaterialCT : public ParticleTrailsMaterial -{ -public: - ParticleTrailsMaterialCT() - { - } - - ~ParticleTrailsMaterialCT() - { - delete colortable; - delete sizetable; - delete opacitytable; - } - - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - - QSGTexture *colortable; - QSGTexture *sizetable; - QSGTexture *opacitytable; -}; - - -class ParticleTrailsMaterialDataCT : public ParticleTrailsMaterialData -{ -public: - ParticleTrailsMaterialDataCT() - : ParticleTrailsMaterialData(":resources/ctvertex.shader", ":resources/ctfragment.shader") - { - } - - bool isColorTable() const { return true; } - - virtual void initialize() { - ParticleTrailsMaterialData::initialize(); - m_colortable_id = program()->uniformLocation("colortable"); - m_sizetable_id = program()->uniformLocation("sizetable"); - m_opacitytable_id = program()->uniformLocation("opacitytable"); - } - - virtual void updateState(const RenderState &state, QSGMaterial *current, QSGMaterial *old) - { - // Bind the texture to unit 1 before calling the base class, so that the - // base class can set active texture back to 0. - ParticleTrailsMaterialCT *m = static_cast(current); - state.context()->functions()->glActiveTexture(GL_TEXTURE1); - m->colortable->bind(); - program()->setUniformValue(m_colortable_id, 1); - - state.context()->functions()->glActiveTexture(GL_TEXTURE2); - m->sizetable->bind(); - program()->setUniformValue(m_sizetable_id, 2); - - state.context()->functions()->glActiveTexture(GL_TEXTURE3); - m->opacitytable->bind(); - program()->setUniformValue(m_opacitytable_id, 3); - - ParticleTrailsMaterialData::updateState(state, current, old); - } - - int m_colortable_id; - int m_sizetable_id; - int m_opacitytable_id; -}; - - -QSGMaterialShader *ParticleTrailsMaterialCT::createShader() const -{ - return new ParticleTrailsMaterialDataCT; -} - -ColoredParticle::ColoredParticle(QSGItem* parent) - : ParticleType(parent) - , m_do_reset(false) - , m_color(Qt::white) - , m_color_variation(0.5) - , m_node(0) - , m_material(0) - , m_alphaVariation(0.0) - , m_alpha(1.0) - , m_redVariation(0.0) - , m_greenVariation(0.0) - , m_blueVariation(0.0) -{ - setFlag(ItemHasContents); -} - -void ColoredParticle::setImage(const QUrl &image) -{ - if (image == m_image_name) - return; - m_image_name = image; - emit imageChanged(); - reset(); -} - - -void ColoredParticle::setColortable(const QUrl &table) -{ - if (table == m_colortable_name) - return; - m_colortable_name = table; - emit colortableChanged(); - reset(); -} - -void ColoredParticle::setSizetable(const QUrl &table) -{ - if (table == m_sizetable_name) - return; - m_sizetable_name = table; - emit sizetableChanged(); - reset(); -} - -void ColoredParticle::setOpacitytable(const QUrl &table) -{ - if (table == m_opacitytable_name) - return; - m_opacitytable_name = table; - emit opacitytableChanged(); - reset(); -} - -void ColoredParticle::setColor(const QColor &color) -{ - if (color == m_color) - return; - m_color = color; - emit colorChanged(); - //m_system->pleaseReset();//XXX -} - -void ColoredParticle::setColorVariation(qreal var) -{ - if (var == m_color_variation) - return; - m_color_variation = var; - emit colorVariationChanged(); - //m_system->pleaseReset();//XXX -} - -void ColoredParticle::setCount(int c) -{ - ParticleType::setCount(c); - m_pleaseReset = true; -} - -void ColoredParticle::reset() -{ - ParticleType::reset(); - m_pleaseReset = true; -} - -static QSGGeometry::Attribute ColoredParticle_Attributes[] = { - { 0, 2, GL_FLOAT }, // Position - { 1, 2, GL_FLOAT }, // TexCoord - { 2, 4, GL_FLOAT }, // Data - { 3, 4, GL_FLOAT }, // Vectors - { 4, 4, GL_UNSIGNED_BYTE } // Colors -}; - -static QSGGeometry::AttributeSet ColoredParticle_AttributeSet = -{ - 5, // Attribute Count - (2 + 2 + 4 + 4) * sizeof(float) + 4 * sizeof(uchar), - ColoredParticle_Attributes -}; - -QSGGeometryNode* ColoredParticle::buildParticleNode() -{ - if (m_count * 4 > 0xffff) { - printf("ColoredParticle: Too many particles... \n"); - return 0; - } - - if(m_count <= 0) { - printf("ColoredParticle: Too few particles... \n"); - return 0; - } - - QImage image(m_image_name.toLocalFile()); - if (image.isNull()) { - printf("ParticleTrails: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile())); - return 0; - } - - int vCount = m_count * 4; - int iCount = m_count * 6; - - QSGGeometry *g = new QSGGeometry(ColoredParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - ColoredParticleVertex *vertices = (ColoredParticleVertex *) g->vertexData(); - for (int p=0; pindexDataAsUShort(); - for (int i=0; i(m_material); - ct_material->colortable = sceneGraphEngine()->createTextureFromImage(colortable); - ct_material->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable); - ct_material->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable); - } - - if (!m_material) - m_material = new ParticleTrailsMaterial(); - - - m_material->texture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - - m_last_particle = 0; - - return m_node; -} - -QSGNode *ColoredParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if(m_pleaseReset){ - if(m_node) - delete m_node; - if(m_material) - delete m_material; - - m_node = 0; - m_material = 0; - m_pleaseReset = false; - } - - if(m_system && m_system->isRunning()) - prepareNextFrame(); - if (m_node){ - update(); - m_node->markDirty(QSGNode::DirtyMaterial); - } - - return m_node; -} - -void ColoredParticle::prepareNextFrame() -{ - if (m_node == 0){ //TODO: Staggered loading (as emitted) - m_node = buildParticleNode(); - if(m_node == 0) - return; - } - qint64 timeStamp = m_system->systemSync(this); - - qreal time = timeStamp / 1000.; - m_material->timestamp = time; -} - -void ColoredParticle::reloadColor(const Color4ub &c, ParticleData* d) -{ - ColoredParticleVertices *particles = (ColoredParticleVertices *) m_node->geometry()->vertexData(); - int pos = particleTypeIndex(d); - ColoredParticleVertices &p = particles[pos]; - p.v1.color = p.v2.color = p.v3.color = p.v4.color = c; -} - -void ColoredParticle::vertexCopy(ColoredParticleVertex &b,const ParticleVertex& a) -{ - b.x = a.x - m_systemOffset.x(); - b.y = a.y - m_systemOffset.y(); - b.t = a.t; - b.lifeSpan = a.lifeSpan; - b.size = a.size; - b.endSize = a.endSize; - b.sx = a.sx; - b.sy = a.sy; - b.ax = a.ax; - b.ay = a.ay; -} - -void ColoredParticle::reload(ParticleData *d) -{ - if (m_node == 0) - return; - - ColoredParticleVertices *particles = (ColoredParticleVertices *) m_node->geometry()->vertexData(); - - int pos = particleTypeIndex(d); - - ColoredParticleVertices &p = particles[pos]; - - //Perhaps we could be more efficient? - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); -} - -void ColoredParticle::load(ParticleData *d) -{ - if (m_node == 0) - return; - - //Color initialization - // Particle color - Color4ub color; - qreal redVariation = m_color_variation + m_redVariation; - qreal greenVariation = m_color_variation + m_greenVariation; - qreal blueVariation = m_color_variation + m_blueVariation; - color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; - color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; - color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; - color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; - ColoredParticleVertices *particles = (ColoredParticleVertices *) m_node->geometry()->vertexData(); - ColoredParticleVertices &p = particles[particleTypeIndex(d)]; - p.v1.color = p.v2.color = p.v3.color = p.v4.color = color; - - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/coloredparticle.h b/src/imports/particles/coloredparticle.h deleted file mode 100644 index 446b764941..0000000000 --- a/src/imports/particles/coloredparticle.h +++ /dev/null @@ -1,254 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef COLOREDPARTICLE_H -#define COLOREDPARTICLE_H -#include "particle.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class ParticleTrailsMaterial; -class QSGGeometryNode; - -struct Color4ub { - uchar r; - uchar g; - uchar b; - uchar a; -}; - -struct ColoredParticleVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; - Color4ub color; -}; - -struct ColoredParticleVertices { - ColoredParticleVertex v1; - ColoredParticleVertex v2; - ColoredParticleVertex v3; - ColoredParticleVertex v4; -}; - -class ColoredParticle : public ParticleType -{ - Q_OBJECT - Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) - Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) - Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) - Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) - - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - //Stacks (added) with individual colorVariations - Q_PROPERTY(qreal colorVariation READ colorVariation WRITE setColorVariation NOTIFY colorVariationChanged) - Q_PROPERTY(qreal redVariation READ redVariation WRITE setRedVariation NOTIFY redVariationChanged) - Q_PROPERTY(qreal greenVariation READ greenVariation WRITE setGreenVariation NOTIFY greenVariationChanged) - Q_PROPERTY(qreal blueVariation READ blueVariation WRITE setBlueVariation NOTIFY blueVariationChanged) - //Stacks (multiplies) with the Alpha in the color, mostly here so you can use svg color names (which have full alpha) - Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged) - Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged) - -public: - explicit ColoredParticle(QSGItem *parent = 0); - virtual ~ColoredParticle(){} - - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - - QUrl image() const { return m_image_name; } - void setImage(const QUrl &image); - - QUrl colortable() const { return m_colortable_name; } - void setColortable(const QUrl &table); - - QUrl sizetable() const { return m_sizetable_name; } - void setSizetable (const QUrl &table); - - QUrl opacitytable() const { return m_opacitytable_name; } - void setOpacitytable(const QUrl &table); - - QColor color() const { return m_color; } - void setColor(const QColor &color); - - qreal colorVariation() const { return m_color_variation; } - void setColorVariation(qreal var); - - qreal renderOpacity() const { return m_render_opacity; } - - qreal alphaVariation() const - { - return m_alphaVariation; - } - - qreal alpha() const - { - return m_alpha; - } - - qreal redVariation() const - { - return m_redVariation; - } - - qreal greenVariation() const - { - return m_greenVariation; - } - - qreal blueVariation() const - { - return m_blueVariation; - } - -signals: - - void imageChanged(); - void colortableChanged(); - void sizetableChanged(); - void opacitytableChanged(); - - void colorChanged(); - void colorVariationChanged(); - - void particleDurationChanged(); - void alphaVariationChanged(qreal arg); - - void alphaChanged(qreal arg); - - void redVariationChanged(qreal arg); - - void greenVariationChanged(qreal arg); - - void blueVariationChanged(qreal arg); - -public slots: - void setAlphaVariation(qreal arg) - { - if (m_alphaVariation != arg) { - m_alphaVariation = arg; - emit alphaVariationChanged(arg); - } - } - - void setAlpha(qreal arg) - { - if (m_alpha != arg) { - m_alpha = arg; - emit alphaChanged(arg); - } - } - - void setRedVariation(qreal arg) - { - if (m_redVariation != arg) { - m_redVariation = arg; - emit redVariationChanged(arg); - } - } - - void setGreenVariation(qreal arg) - { - if (m_greenVariation != arg) { - m_greenVariation = arg; - emit greenVariationChanged(arg); - } - } - - void setBlueVariation(qreal arg) - { - if (m_blueVariation != arg) { - m_blueVariation = arg; - emit blueVariationChanged(arg); - } - } - - void reloadColor(const Color4ub &c, ParticleData* d); -protected: - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void reset(); - void prepareNextFrame(); - QSGGeometryNode* buildParticleNode(); -private: - void vertexCopy(ColoredParticleVertex &b,const ParticleVertex& a); - bool m_do_reset; - - QUrl m_image_name; - QUrl m_colortable_name; - QUrl m_sizetable_name; - QUrl m_opacitytable_name; - - - QColor m_color; - qreal m_color_variation; - qreal m_particleDuration; - - QSGGeometryNode *m_node; - ParticleTrailsMaterial *m_material; - - // derived values... - int m_last_particle; - - qreal m_render_opacity; - qreal m_alphaVariation; - qreal m_alpha; - qreal m_redVariation; - qreal m_greenVariation; - qreal m_blueVariation; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // COLOREDPARTICLE_H diff --git a/src/imports/particles/dataparticle.cpp b/src/imports/particles/dataparticle.cpp deleted file mode 100644 index a2965e8c71..0000000000 --- a/src/imports/particles/dataparticle.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "dataparticle.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -DataParticle::DataParticle(QSGItem *parent) : - ParticleType(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true), m_modelCount(0) -{ - setFlag(QSGItem::ItemHasContents); -} - -QVariant DataParticle::model() const -{ - return m_dataSource; -} - -void DataParticle::setModel(const QVariant &arg) -{ - if(arg == m_dataSource) - return; - m_dataSource = arg; - if(qobject_cast(arg.value())) { - if(m_ownModel && m_model) - delete m_model; - m_model = qobject_cast(arg.value()); - m_ownModel = false; - }else{ - if(!m_model || !m_ownModel) - m_model = new QSGVisualDataModel(qmlContext(this)); - m_model->setModel(m_dataSource); - m_ownModel = true; - } - if(m_comp) - m_model->setDelegate(m_comp); - emit modelChanged(); - emit modelCountChanged(); - connect(m_model, SIGNAL(countChanged()), - this, SIGNAL(modelCountChanged())); - connect(m_model, SIGNAL(countChanged()), - this, SLOT(updateCount())); - updateCount(); -} - -void DataParticle::updateCount() -{ - int newCount = 0; - if(m_model) - newCount = m_model->count(); - if(newCount < 0) - return;//WTF? - if(m_modelCount == 0 || newCount == 0){ - m_available.clear(); - for(int i=0; i m_modelCount){ - for(int i=m_modelCount; idelegate(); - return 0; -} - -void DataParticle::setDelegate(QDeclarativeComponent *comp) -{ - if (QSGVisualDataModel *dataModel = qobject_cast(m_model)) - if (comp == dataModel->delegate()) - return; - m_comp = comp; - if(m_model) - m_model->setDelegate(comp); - emit delegateChanged(); -} - -int DataParticle::modelCount() const -{ - if(m_model) - const_cast(this)->updateCount();//TODO: Investigate why this doesn't get called properly - return m_modelCount; -} - - -void DataParticle::freeze(QSGItem* item) -{ - m_stasis << item; -} - - -void DataParticle::unfreeze(QSGItem* item) -{ - m_stasis.remove(item); -} - -void DataParticle::load(ParticleData* d) -{ - if(!m_model || !m_model->count()) - return; - int pos = particleTypeIndex(d); - if(m_available.isEmpty()) - return; - if(m_items[pos]){ - if(m_stasis.contains(m_items[pos])) - qWarning() << "Current model particles prefers overwrite:false"; - //remove old item from the particle that is dying to make room for this one - m_items[pos]->setOpacity(0.); - m_available << m_idx[pos]; - m_model->release(m_items[pos]); - m_idx[pos] = -1; - m_items[pos] = 0; - m_data[pos] = 0; - m_activeCount--; - } - m_items[pos] = m_model->item(m_available.first()); - m_idx[pos] = m_available.first(); - m_available.pop_front(); - DataParticleAttached* mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[pos])); - if(mpa){ - mpa->m_mp = this; - mpa->attach(); - } - m_items[pos]->setParentItem(this); - m_data[pos] = d; - m_activeCount++; -} - -void DataParticle::reload(ParticleData* d) -{ - //No-op unless we start copying the data. -} - -void DataParticle::setCount(int c) -{ - ParticleType::setCount(c);//###Do we need our own? - m_particleCount = c; - reset(); -} - -int DataParticle::count() -{ - return m_particleCount; -} - -void DataParticle::reset() -{ - ParticleType::reset(); - //TODO: Cleanup items? - m_items.resize(m_particleCount); - m_data.resize(m_particleCount); - m_idx.resize(m_particleCount); - m_items.fill(0); - m_data.fill(0); - m_idx.fill(-1); - //m_available.clear();//Should this be reset too? - //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal? -} - - -QSGNode* DataParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d) -{ - //Dummy update just to get painting tick - if(m_pleaseReset){ - m_pleaseReset = false; - reset(); - } - prepareNextFrame(); - - update();//Get called again - if(n) - n->markDirty(QSGNode::DirtyMaterial); - return QSGItem::updatePaintNode(n,d); -} - -void DataParticle::prepareNextFrame() -{ - qint64 timeStamp = m_system->systemSync(this); - qreal curT = timeStamp/1000.0; - qreal dt = curT - m_lastT; - m_lastT = curT; - if(!m_activeCount) - return; - - //TODO: Size, better fade? - for(int i=0; ipv.t) / data->pv.lifeSpan; - if(m_stasis.contains(item)) { - m_data[i]->pv.t += dt;//Stasis effect - continue; - } - if(t >= 1.0){//Usually happens from load - item->setOpacity(0.); - m_available << m_idx[i]; - m_model->release(m_items[i]); - m_idx[i] = -1; - m_items[i] = 0; - m_data[i] = 0; - m_activeCount--; - }else{//Fade - if(m_fade){ - qreal o = 1.; - if(t<0.2) - o = t*5; - if(t>0.8) - o = (1-t)*5; - item->setOpacity(o); - }else{ - item->setOpacity(1.);//###Without fade, it's just a binary toggle - if we turn it off we have to turn it back on - } - } - item->setX(data->curX() - item->width()/2); - item->setY(data->curY() - item->height()/2); - } -} - -DataParticleAttached *DataParticle::qmlAttachedProperties(QObject *object) -{ - return new DataParticleAttached(object); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/dataparticle.h b/src/imports/particles/dataparticle.h deleted file mode 100644 index 84422e70c3..0000000000 --- a/src/imports/particles/dataparticle.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DATAPARTICLE_H -#define DATAPARTICLE_H -#include "particle.h" -#include -#include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) -class QSGVisualDataModel; -class DataParticleAttached; - -class DataParticle : public ParticleType -{ - Q_OBJECT - - Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) - Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) - Q_PROPERTY(int modelCount READ modelCount NOTIFY modelCountChanged) - Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) - Q_CLASSINFO("DefaultProperty", "delegate") -public: - explicit DataParticle(QSGItem *parent = 0); - QVariant model() const; - void setModel(const QVariant &); - - QDeclarativeComponent *delegate() const; - void setDelegate(QDeclarativeComponent *); - - int modelCount() const; - - bool fade() const { return m_fade; } - - virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - virtual int count(); - - static DataParticleAttached *qmlAttachedProperties(QObject *object); -signals: - void modelChanged(); - void delegateChanged(); - void modelCountChanged(); - void fadeChanged(); - -public slots: - void freeze(QSGItem* item); - void unfreeze(QSGItem* item); - - void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();} -protected: - virtual void reset(); - void prepareNextFrame(); -private slots: - void updateCount(); -private: - bool m_ownModel; - QDeclarativeComponent* m_comp; - QSGVisualDataModel *m_model; - QVariant m_dataSource; - QList > m_deletables; - int m_particleCount; - bool m_fade; - - QList m_pendingItems; - QVector m_items; - QVector m_data; - QVector m_idx; - QList m_available; - QSet m_stasis; - qreal m_lastT; - int m_activeCount; - int m_modelCount; -}; - -class DataParticleAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(DataParticle* particle READ particle CONSTANT); -public: - DataParticleAttached(QObject* parent) - : QObject(parent), m_mp(0) - {;} - DataParticle* particle() {return m_mp;} - void detach(){emit detached();} - void attach(){emit attached();} -private: - DataParticle* m_mp; - friend class DataParticle; -Q_SIGNALS: - void detached(); - void attached(); -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPEINFO(DataParticle, QML_HAS_ATTACHED_PROPERTIES) - -QT_END_HEADER -#endif // DATAPARTICLE_H diff --git a/src/imports/particles/deformableparticle.cpp b/src/imports/particles/deformableparticle.cpp deleted file mode 100644 index 768e4eb4b5..0000000000 --- a/src/imports/particles/deformableparticle.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "deformableparticle.h" -#include -#include - -QT_BEGIN_NAMESPACE - -const float CONV = 0.017453292519943295; -class DeformableParticleMaterial : public QSGMaterial -{ -public: - DeformableParticleMaterial() - : timestamp(0) - { - setFlag(Blending, true); - } - - ~DeformableParticleMaterial() - { - delete texture; - } - - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const - { - return this - static_cast(other); - } - - QSGTexture *texture; - - qreal timestamp; -}; - - -class DeformableParticleMaterialData : public QSGMaterialShader -{ -public: - DeformableParticleMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/deformablevertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/deformablefragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - DeformableParticleMaterial *m = static_cast(newEffect); - state.context()->functions()->glActiveTexture(GL_TEXTURE0); - m->texture->bind(); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vPos", - "vTex", - "vData", - "vVec", - "vDeformVec", - "vRotation", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float DeformableParticleMaterialData::chunkOfBytes[1024]; - - -QSGMaterialShader *DeformableParticleMaterial::createShader() const -{ - return new DeformableParticleMaterialData; -} - -struct DeformableParticleVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; - float xx; - float xy; - float yx; - float yy; - float rotation; - float rotationSpeed; - float autoRotate;//Assume that GPUs prefer floats to bools -}; - -struct DeformableParticleVertices { - DeformableParticleVertex v1; - DeformableParticleVertex v2; - DeformableParticleVertex v3; - DeformableParticleVertex v4; -}; - - -DeformableParticle::DeformableParticle(QSGItem* parent) - : ParticleType(parent) - , m_do_reset(false) - , m_rotation(0) - , m_autoRotation(false) - , m_xVector(0) - , m_yVector(0) - , m_rotationVariation(0) - , m_rotationSpeed(0) - , m_rotationSpeedVariation(0) -{ - setFlag(ItemHasContents); -} - -void DeformableParticle::setImage(const QUrl &image) -{ - if (image == m_image) - return; - m_image = image; - emit imageChanged(); - reset(); -} - -void DeformableParticle::setCount(int c) -{ - ParticleType::setCount(c); - m_pleaseReset = true; -} - -void DeformableParticle::reset() -{ - ParticleType::reset(); - m_pleaseReset = true; -} - -static QSGGeometry::Attribute DeformableParticle_Attributes[] = { - { 0, 2, GL_FLOAT }, // Position - { 1, 2, GL_FLOAT }, // TexCoord - { 2, 4, GL_FLOAT }, // Data - { 3, 4, GL_FLOAT }, // Vectors - { 4, 4, GL_FLOAT }, // DeformationVectors - { 5, 3, GL_FLOAT } // Rotation -}; - -static QSGGeometry::AttributeSet DeformableParticle_AttributeSet = -{ - 6, // Attribute Count - (2 + 2 + 4 + 4 + 4 + 3) * sizeof(float), - DeformableParticle_Attributes -}; - -QSGGeometryNode* DeformableParticle::buildParticleNode() -{ - if (m_count * 4 > 0xffff) { - printf("DeformableParticle: Too many particles... \n"); - return 0; - } - - if(m_count <= 0) { - printf("DeformableParticle: Too few particles... \n"); - return 0; - } - - QImage image(m_image.toLocalFile()); - if (image.isNull()) { - printf("DeformableParticle: loading image failed... '%s'\n", qPrintable(m_image.toLocalFile())); - return 0; - } - - int vCount = m_count * 4; - int iCount = m_count * 6; - - QSGGeometry *g = new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - DeformableParticleVertex *vertices = (DeformableParticleVertex *) g->vertexData(); - for (int p=0; pindexDataAsUShort(); - for (int i=0; itexture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - - m_last_particle = 0; - - return m_node; -} - -QSGNode *DeformableParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if(m_pleaseReset){ - if(m_node) - delete m_node; - if(m_material) - delete m_material; - - m_node = 0; - m_material = 0; - m_pleaseReset = false; - } - - if(m_system && m_system->isRunning()) - prepareNextFrame(); - if (m_node){ - update(); - m_node->markDirty(QSGNode::DirtyMaterial); - } - - return m_node; -} - -void DeformableParticle::prepareNextFrame() -{ - if (m_node == 0){ //TODO: Staggered loading (as emitted) - m_node = buildParticleNode(); - if(m_node == 0) - return; - } - qint64 timeStamp = m_system->systemSync(this); - - qreal time = timeStamp / 1000.; - m_material->timestamp = time; - -} - - -void DeformableParticle::vertexCopy(DeformableParticleVertex &b,const ParticleVertex& a) -{ - b.x = a.x - m_systemOffset.x(); - b.y = a.y - m_systemOffset.y(); - b.t = a.t; - b.lifeSpan = a.lifeSpan; - b.size = a.size; - b.endSize = a.endSize; - b.sx = a.sx; - b.sy = a.sy; - b.ax = a.ax; - b.ay = a.ay; -} - -void DeformableParticle::reload(ParticleData *d) -{ - if (m_node == 0) - return; - - DeformableParticleVertices *particles = (DeformableParticleVertices *) m_node->geometry()->vertexData(); - - int pos = particleTypeIndex(d); - - DeformableParticleVertices &p = particles[pos]; - - //Perhaps we could be more efficient? - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); - //TODO: Allow for change of deformation data? -} - -void DeformableParticle::load(ParticleData *d) -{ - if (m_node == 0) - return; - - //Deformation Initialization - DeformableParticleVertices *particles = (DeformableParticleVertices *) m_node->geometry()->vertexData(); - DeformableParticleVertices &p = particles[particleTypeIndex(d)]; - if(m_xVector){ - const QPointF &ret = m_xVector->sample(QPointF(d->pv.x, d->pv.y)); - p.v1.xx = p.v2.xx = p.v3.xx = p.v4.xx = ret.x(); - p.v1.xy = p.v2.xy = p.v3.xy = p.v4.xy = ret.y(); - } - if(m_yVector){ - const QPointF &ret = m_yVector->sample(QPointF(d->pv.x, d->pv.y)); - p.v1.yx = p.v2.yx = p.v3.yx = p.v4.yx = ret.x(); - p.v1.yy = p.v2.yy = p.v3.yy = p.v4.yy = ret.y(); - } - p.v1.rotation = p.v2.rotation = p.v3.rotation = p.v4.rotation = - (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; - p.v1.rotationSpeed = p.v2.rotationSpeed = p.v3.rotationSpeed = p.v4.rotationSpeed = - (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; - p.v1.autoRotate = p.v2.autoRotate = p.v3.autoRotate = p.v4.autoRotate = m_autoRotation?1.0:0.0; - - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/deformableparticle.h b/src/imports/particles/deformableparticle.h deleted file mode 100644 index 0de6d8228a..0000000000 --- a/src/imports/particles/deformableparticle.h +++ /dev/null @@ -1,235 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEFORMABLEPARTICLE_H -#define DEFORMABLEPARTICLE_H -#include "particle.h" -#include "varyingvector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class DeformableParticleMaterial; -class QSGGeometryNode; -struct DeformableParticleVertex; - -class DeformableParticle : public ParticleType -{ - Q_OBJECT - //Note that the particle centering can be less accurate with this one - Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) - - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) - Q_PROPERTY(qreal rotationVariation READ rotationVariation WRITE setRotationVariation NOTIFY rotationVariationChanged) - Q_PROPERTY(qreal rotationSpeed READ rotationSpeed WRITE setRotationSpeed NOTIFY rotationSpeedChanged) - Q_PROPERTY(qreal rotationSpeedVariation READ rotationSpeedVariation WRITE setRotationSpeedVariation NOTIFY rotationSpeedVariationChanged) - //If true, then will face the direction of motion. Stacks with rotation, e.g. setting rotation - //to 180 will lead to facing away from the direction of motion - Q_PROPERTY(bool autoRotation READ autoRotation WRITE autoRotation NOTIFY autoRotationChanged) - - //###Call i/j? Makes more sense to those with vector calculus experience, and I could even add the cirumflex in QML? - //xVector is the vector from the top-left point to the top-right point, and is multiplied by current size - Q_PROPERTY(VaryingVector* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged) - //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram. - Q_PROPERTY(VaryingVector* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged) - - //Do we want to add the tables? - //Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) - //Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) - //Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) - - //Does it need alpha? For convenience only, as images probably don't have it - //Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged) - //Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged) - -public: - explicit DeformableParticle(QSGItem *parent = 0); - virtual ~DeformableParticle(){} - - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - - QUrl image() const { return m_image; } - void setImage(const QUrl &image); - - qreal rotation() const - { - return m_rotation; - } - - bool autoRotation() const - { - return m_autoRotation; - } - - VaryingVector* xVector() const - { - return m_xVector; - } - - VaryingVector* yVector() const - { - return m_yVector; - } - - qreal rotationVariation() const - { - return m_rotationVariation; - } - - qreal rotationSpeed() const - { - return m_rotationSpeed; - } - - qreal rotationSpeedVariation() const - { - return m_rotationSpeedVariation; - } - -signals: - - void imageChanged(); - void rotationChanged(qreal arg); - - void autoRotationChanged(bool arg); - - void xVectorChanged(VaryingVector* arg); - - void yVectorChanged(VaryingVector* arg); - - void rotationVariationChanged(qreal arg); - - void rotationSpeedChanged(qreal arg); - - void rotationSpeedVariationChanged(qreal arg); - -public slots: -void setRotation(qreal arg) -{ - if (m_rotation != arg) { - m_rotation = arg; - emit rotationChanged(arg); - } -} - -void autoRotation(bool arg) -{ - if (m_autoRotation != arg) { - m_autoRotation = arg; - emit autoRotationChanged(arg); - } -} - -void setXVector(VaryingVector* arg) -{ - if (m_xVector != arg) { - m_xVector = arg; - emit xVectorChanged(arg); - } -} - -void setYVector(VaryingVector* arg) -{ - if (m_yVector != arg) { - m_yVector = arg; - emit yVectorChanged(arg); - } -} - -void setRotationVariation(qreal arg) -{ - if (m_rotationVariation != arg) { - m_rotationVariation = arg; - emit rotationVariationChanged(arg); - } -} - -void setRotationSpeed(qreal arg) -{ - if (m_rotationSpeed != arg) { - m_rotationSpeed = arg; - emit rotationSpeedChanged(arg); - } -} - -void setRotationSpeedVariation(qreal arg) -{ - if (m_rotationSpeedVariation != arg) { - m_rotationSpeedVariation = arg; - emit rotationSpeedVariationChanged(arg); - } -} - -protected: - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void reset(); - void prepareNextFrame(); - QSGGeometryNode* buildParticleNode(); -private: - void vertexCopy(DeformableParticleVertex &b,const ParticleVertex& a); - bool m_do_reset; - - QUrl m_image; - QSGGeometryNode *m_node; - DeformableParticleMaterial *m_material; - - // derived values... - int m_last_particle; - - qreal m_render_opacity; - // generated vars - qreal m_rotation; - bool m_autoRotation; - VaryingVector* m_xVector; - VaryingVector* m_yVector; - qreal m_rotationVariation; - qreal m_rotationSpeed; - qreal m_rotationSpeedVariation; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // DEFORMABLEPARTICLE_H diff --git a/src/imports/particles/directedvector.cpp b/src/imports/particles/directedvector.cpp deleted file mode 100644 index c1aeba3ad2..0000000000 --- a/src/imports/particles/directedvector.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directedvector.h" -#include "particleemitter.h" -#include -#include - -QT_BEGIN_NAMESPACE -DirectedVector::DirectedVector(QObject *parent) : - VaryingVector(parent) - , m_targetX(0) - , m_targetY(0) - , m_targetVariation(0) - , m_proportionalMagnitude(false) - , m_magnitude(0) - , m_magnitudeVariation(0) - , m_targetItem(0) -{ -} - -const QPointF &DirectedVector::sample(const QPointF &from) -{ - //###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile? - qreal targetX; - qreal targetY; - if(m_targetItem){ - ParticleEmitter* parentEmitter = qobject_cast(parent()); - targetX = m_targetItem->width()/2; - targetY = m_targetItem->height()/2; - if(!parentEmitter){ - qWarning() << "Directed vector is not a child of the emitter. Mapping of target item coordinates may fail."; - targetX += m_targetItem->x(); - targetY += m_targetItem->y(); - }else{ - m_ret = parentEmitter->mapFromItem(m_targetItem, QPointF(targetX, targetY)); - targetX = m_ret.x(); - targetY = m_ret.y(); - } - }else{ - targetX = m_targetX; - targetY = m_targetY; - } - targetX += 0 - from.x() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; - targetY += 0 - from.y() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; - qreal theta = atan2(targetY, targetX); - qreal mag = m_magnitude + rand()/(float)RAND_MAX * m_magnitudeVariation * 2 - m_magnitudeVariation; - if(m_proportionalMagnitude) - mag *= sqrt(targetX * targetX + targetY * targetY); - m_ret.setX(mag * cos(theta)); - m_ret.setY(mag * sin(theta)); - return m_ret; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/directedvector.h b/src/imports/particles/directedvector.h deleted file mode 100644 index f1d0919bc3..0000000000 --- a/src/imports/particles/directedvector.h +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTEDVECTOR_H -#define DIRECTEDVECTOR_H -#include "varyingvector.h" -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGItem; -class DirectedVector : public VaryingVector -{ - Q_OBJECT - Q_PROPERTY(qreal targetX READ targetX WRITE setTargetX NOTIFY targetXChanged) - Q_PROPERTY(qreal targetY READ targetY WRITE setTargetY NOTIFY targetYChanged) - //If targetItem is set, X/Y are ignored. Aims at middle of item, use variation for variation - Q_PROPERTY(QSGItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged) - - Q_PROPERTY(qreal targetVariation READ targetVariation WRITE setTargetVariation NOTIFY targetVariationChanged) - - Q_PROPERTY(bool proportionalMagnitude READ proportionalMagnitude WRITE setProportionalMagnitude NOTIFY proprotionalMagnitudeChanged) - Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) - Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) - -public: - explicit DirectedVector(QObject *parent = 0); - virtual const QPointF &sample(const QPointF &from); - - qreal targetX() const - { - return m_targetX; - } - - qreal targetY() const - { - return m_targetY; - } - - qreal targetVariation() const - { - return m_targetVariation; - } - - qreal magnitude() const - { - return m_magnitude; - } - - bool proportionalMagnitude() const - { - return m_proportionalMagnitude; - } - - qreal magnitudeVariation() const - { - return m_magnitudeVariation; - } - - QSGItem* targetItem() const - { - return m_targetItem; - } - -signals: - - void targetXChanged(qreal arg); - - void targetYChanged(qreal arg); - - void targetVariationChanged(qreal arg); - - void magnitudeChanged(qreal arg); - - void proprotionalMagnitudeChanged(bool arg); - - void magnitudeVariationChanged(qreal arg); - - void targetItemChanged(QSGItem* arg); - -public slots: - void setTargetX(qreal arg) - { - if (m_targetX != arg) { - m_targetX = arg; - emit targetXChanged(arg); - } - } - - void setTargetY(qreal arg) - { - if (m_targetY != arg) { - m_targetY = arg; - emit targetYChanged(arg); - } - } - - void setTargetVariation(qreal arg) - { - if (m_targetVariation != arg) { - m_targetVariation = arg; - emit targetVariationChanged(arg); - } - } - - void setMagnitude(qreal arg) - { - if (m_magnitude != arg) { - m_magnitude = arg; - emit magnitudeChanged(arg); - } - } - - void setProportionalMagnitude(bool arg) - { - if (m_proportionalMagnitude != arg) { - m_proportionalMagnitude = arg; - emit proprotionalMagnitudeChanged(arg); - } - } - - void setMagnitudeVariation(qreal arg) - { - if (m_magnitudeVariation != arg) { - m_magnitudeVariation = arg; - emit magnitudeVariationChanged(arg); - } - } - - void setTargetItem(QSGItem* arg) - { - if (m_targetItem != arg) { - m_targetItem = arg; - emit targetItemChanged(arg); - } - } - -private: - qreal m_targetX; - qreal m_targetY; - qreal m_targetVariation; - bool m_proportionalMagnitude; - qreal m_magnitude; - qreal m_magnitudeVariation; - QSGItem *m_targetItem; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // DIRECTEDVECTOR_H diff --git a/src/imports/particles/driftaffector.cpp b/src/imports/particles/driftaffector.cpp deleted file mode 100644 index f88e29936a..0000000000 --- a/src/imports/particles/driftaffector.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "driftaffector.h" -#include "particlesystem.h" -QT_BEGIN_NAMESPACE -DriftAffector::DriftAffector(QSGItem *parent) : - ParticleAffector(parent) -{ -} - -DriftAffector::~DriftAffector() -{ -} - -bool DriftAffector::affectParticle(ParticleData *data, qreal dt) -{ - if(!m_xDrift && !m_yDrift) - return false; - qreal dx = (((qreal)qrand() / (qreal)RAND_MAX) - 0.5) * 2 * m_xDrift * dt; - qreal dy = (((qreal)qrand() / (qreal)RAND_MAX) - 0.5) * 2 * m_yDrift * dt; - if(dx) - data->setInstantaneousSX(data->curSX() + dx); - if(dy) - data->setInstantaneousSY(data->curSY() + dy); - - return true; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/driftaffector.h b/src/imports/particles/driftaffector.h deleted file mode 100644 index 91ef0fbd34..0000000000 --- a/src/imports/particles/driftaffector.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DRIFTAFFECTOR_H -#define DRIFTAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class DriftAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal xDrift READ xDrift WRITE setXDrift NOTIFY xDriftChanged) - Q_PROPERTY(qreal yDrift READ yDrift WRITE setYDrift NOTIFY yDriftChanged) -public: - explicit DriftAffector(QSGItem *parent = 0); - ~DriftAffector(); - qreal yDrift() const - { - return m_yDrift; - } - - qreal xDrift() const - { - return m_xDrift; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); - -signals: - - void yDriftChanged(qreal arg); - - void xDriftChanged(qreal arg); - -public slots: - -void setYDrift(qreal arg) -{ - if (m_yDrift != arg) { - m_yDrift = arg; - emit yDriftChanged(arg); - } -} - -void setXDrift(qreal arg) -{ - if (m_xDrift != arg) { - m_xDrift = arg; - emit xDriftChanged(arg); - } -} - -private: - qreal m_yDrift; - qreal m_xDrift; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // DRIFTAFFECTOR_H diff --git a/src/imports/particles/ellipseextruder.cpp b/src/imports/particles/ellipseextruder.cpp deleted file mode 100644 index 1a0d70594b..0000000000 --- a/src/imports/particles/ellipseextruder.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "ellipseextruder.h" -#include -QT_BEGIN_NAMESPACE -EllipseExtruder::EllipseExtruder(QObject *parent) : - ParticleExtruder(parent) - , m_fill(true) -{ -} - -QPointF EllipseExtruder::extrude(const QRectF & r) -{ - qreal theta = ((qreal)rand()/RAND_MAX) * 6.2831853071795862; - qreal mag = m_fill ? ((qreal)rand()/RAND_MAX) : 1; - return QPointF(r.x() + r.width()/2 + mag * (r.width()/2) * cos(theta), - r.y() + r.height()/2 + mag * (r.height()/2) * sin(theta)); -} - -bool EllipseExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - return bounds.contains(point);//TODO: Ellipse -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/ellipseextruder.h b/src/imports/particles/ellipseextruder.h deleted file mode 100644 index 25cc9bc16a..0000000000 --- a/src/imports/particles/ellipseextruder.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ELLIPSEEXTRUDER_H -#define ELLIPSEEXTRUDER_H -#include "particleextruder.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class EllipseExtruder : public ParticleExtruder -{ - Q_OBJECT - Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box -public: - explicit EllipseExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point); - - bool fill() const - { - return m_fill; - } - -signals: - - void fillChanged(bool arg); - -public slots: - - void setFill(bool arg) - { - if (m_fill != arg) { - m_fill = arg; - emit fillChanged(arg); - } - } -private: - bool m_fill; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ELLIPSEEXTRUDER_H diff --git a/src/imports/particles/eternalaffector.cpp b/src/imports/particles/eternalaffector.cpp deleted file mode 100644 index c946709170..0000000000 --- a/src/imports/particles/eternalaffector.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "eternalaffector.h" -#include - -QT_BEGIN_NAMESPACE - -EternalAffector::EternalAffector(QSGItem *parent) : - ParticleAffector(parent) -{ -} - -bool EternalAffector::affectParticle(ParticleData *d, qreal dt) -{ - qreal target = (m_system->m_timeInt - m_targetLife)/1000.0; - if(d->pv.t < target) - d->pv.t = target; - return true; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/eternalaffector.h b/src/imports/particles/eternalaffector.h deleted file mode 100644 index 834106b53d..0000000000 --- a/src/imports/particles/eternalaffector.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ETERNALAFFECTOR_H -#define ETERNALAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class EternalAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(int targetLife READ targetLife WRITE setTargetLife NOTIFY targetLifeChanged) - -public: - explicit EternalAffector(QSGItem *parent = 0); - int targetLife() const - { - return m_targetLife; - } - -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); - -signals: - - void targetLifeChanged(int arg); - -public slots: - - void setTargetLife(int arg) - { - if (m_targetLife != arg) { - m_targetLife = arg; - emit targetLifeChanged(arg); - } - } -private: - int m_targetLife; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // ETERNALAFFECTOR_H diff --git a/src/imports/particles/followemitter.cpp b/src/imports/particles/followemitter.cpp deleted file mode 100644 index 17a544f62d..0000000000 --- a/src/imports/particles/followemitter.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "followemitter.h" -#include "particle.h" -#include -QT_BEGIN_NAMESPACE - -FollowEmitter::FollowEmitter(QSGItem *parent) : - ParticleEmitter(parent) - , m_particlesPerParticlePerSecond(0) - , m_lastTimeStamp(0) - , m_emitterXVariation(0) - , m_emitterYVariation(0) - , m_followCount(0) - , m_emissionExtruder(0) - , m_defaultEmissionExtruder(new ParticleExtruder(this)) -{ - connect(this, SIGNAL(followChanged(QString)), - this, SLOT(recalcParticlesPerSecond())); - connect(this, SIGNAL(particleDurationChanged(int)), - this, SLOT(recalcParticlesPerSecond())); - connect(this, SIGNAL(particlesPerParticlePerSecondChanged(int)), - this, SLOT(recalcParticlesPerSecond())); -} - -void FollowEmitter::recalcParticlesPerSecond(){ - if(!m_system) - return; - m_followCount = m_system->m_groupData[m_system->m_groupIds[m_follow]]->size; - if(!m_followCount){ - setParticlesPerSecond(1000);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS) - }else{ - setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount); - m_lastEmission.resize(m_followCount); - m_lastEmission.fill(0); - } -} - -void FollowEmitter::reset() -{ - m_followCount = 0; -} - -void FollowEmitter::emitWindow(int timeStamp) -{ - if (m_system == 0) - return; - if(!m_emitting && !m_burstLeft && m_burstQueue.isEmpty()) - return; - if(m_followCount != m_system->m_groupData[m_system->m_groupIds[m_follow]]->size){ - qreal oldPPS = m_particlesPerSecond; - recalcParticlesPerSecond(); - if(m_particlesPerSecond != oldPPS) - return;//system may need to update - } - - if(m_burstLeft){ - m_burstLeft -= timeStamp - m_lastTimeStamp * 1000.; - if(m_burstLeft < 0){ - timeStamp += m_burstLeft; - m_burstLeft = 0; - } - } - - qreal time = timeStamp / 1000.; - qreal particleRatio = 1. / m_particlesPerParticlePerSecond; - qreal pt; - - //Have to map it into this system, because particlesystem automaps it back - QPointF offset = m_system->mapFromItem(this, QPointF(0, 0)); - qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; - - int gId = m_system->m_groupIds[m_follow]; - int gId2 = m_system->m_groupIds[m_particle]; - for(int i=0; im_groupData[gId]->size; i++){ - pt = m_lastEmission[i]; - ParticleData* d = m_system->m_data[i + m_system->m_groupData[gId]->start]; - if(!d || !d->stillAlive()) - continue; - if(pt < d->pv.t) - pt = d->pv.t; - - if(!effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),QPointF(d->curX(), d->curY()))){ - m_lastEmission[i] = time;//jump over this time period without emitting, because it's outside - continue; - } - while(pt < time || !m_burstQueue.isEmpty()){ - ParticleData* datum = m_system->newDatum(gId2); - if(datum){//else, skip this emission - datum->e = this;//###useful? - ParticleVertex &p = datum->pv; - - // Particle timestamp - p.t = pt; - p.lifeSpan = - (m_particleDuration - + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) - / 1000.0; - - // Particle position - // Note that burst location doesn't get used for follow emitter - qreal followT = pt - d->pv.t; - qreal followT2 = followT * followT * 0.5; - qreal sizeOffset = d->pv.size/2;//TODO: Current size? As an option - //TODO: Set variations - //Subtract offset, because PS expects this in emitter coordinates - QRectF boundsRect(d->pv.x - offset.x() + d->pv.sx * followT + d->pv.ax * followT2 - m_emitterXVariation/2, - d->pv.y - offset.y() + d->pv.sy * followT + d->pv.ay * followT2 - m_emitterYVariation/2, - m_emitterXVariation, - m_emitterYVariation); - // QRectF boundsRect(d->pv.x + d->pv.sx * followT + d->pv.ax * followT2 + offset.x() - sizeOffset, - // d->pv.y + d->pv.sy * followT + d->pv.ay * followT2 + offset.y() - sizeOffset, - // sizeOffset*2, - // sizeOffset*2); - - ParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder; - const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect); - p.x = newPos.x(); - p.y = newPos.y(); - - // Particle speed - const QPointF &speed = m_speed->sample(newPos); - p.sx = speed.x(); - p.sy = speed.y(); - - // Particle acceleration - const QPointF &accel = m_acceleration->sample(newPos); - p.ax = accel.x(); - p.ay = accel.y(); - - // Particle size - float sizeVariation = -m_particleSizeVariation - + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; - - float size = qMax((qreal)0.0, m_particleSize + sizeVariation); - float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation); - - p.size = size * float(m_emitting); - p.endSize = endSize * float(m_emitting); - - m_system->emitParticle(datum); - } - if(!m_burstQueue.isEmpty()){ - m_burstQueue.first().first--; - if(m_burstQueue.first().first <= 0) - m_burstQueue.pop_front(); - }else{ - pt += particleRatio; - } - } - m_lastEmission[i] = pt; - } - - m_lastTimeStamp = time; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/followemitter.h b/src/imports/particles/followemitter.h deleted file mode 100644 index 6df293e2e1..0000000000 --- a/src/imports/particles/followemitter.h +++ /dev/null @@ -1,168 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FOLLOWEMITTER_H -#define FOLLOWEMITTER_H -#include "particleemitter.h" -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class FollowEmitter : public ParticleEmitter -{ - Q_OBJECT - Q_PROPERTY(QString follow READ follow WRITE setFollow NOTIFY followChanged) - //### Remove, and just document that particles per second is per particle? But has count issues - Q_PROPERTY(int particlesPerParticlePerSecond READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged) - - //TODO: Document that FollowEmitter's box is where it follows. It emits in a rect centered on the followed particle - //TODO: A set of properties that can involve the particle size of the followed - Q_PROPERTY(ParticleExtruder* emissionShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged) - Q_PROPERTY(qreal emissionHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) - Q_PROPERTY(qreal emissionWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) - -public: - explicit FollowEmitter(QSGItem *parent = 0); - virtual void emitWindow(int timeStamp); - virtual void reset(); - - int particlesPerParticlePerSecond() const - { - return m_particlesPerParticlePerSecond; - } - - qreal emitterXVariation() const - { - return m_emitterXVariation; - } - - qreal emitterYVariation() const - { - return m_emitterYVariation; - } - - QString follow() const - { - return m_follow; - } - - ParticleExtruder* emissonShape() const - { - return m_emissionExtruder; - } - -signals: - - void particlesPerParticlePerSecondChanged(int arg); - - void emitterXVariationChanged(qreal arg); - - void emitterYVariationChanged(qreal arg); - - void followChanged(QString arg); - - void emissionShapeChanged(ParticleExtruder* arg); - -public slots: - - void setParticlesPerParticlePerSecond(int arg) - { - if (m_particlesPerParticlePerSecond != arg) { - m_particlesPerParticlePerSecond = arg; - emit particlesPerParticlePerSecondChanged(arg); - } - } - void setEmitterXVariation(qreal arg) - { - if (m_emitterXVariation != arg) { - m_emitterXVariation = arg; - emit emitterXVariationChanged(arg); - } - } - - void setEmitterYVariation(qreal arg) - { - if (m_emitterYVariation != arg) { - m_emitterYVariation = arg; - emit emitterYVariationChanged(arg); - } - } - - void setFollow(QString arg) - { - if (m_follow != arg) { - m_follow = arg; - emit followChanged(arg); - } - } - - void setEmissionShape(ParticleExtruder* arg) - { - if (m_emissionExtruder != arg) { - m_emissionExtruder = arg; - emit emissionShapeChanged(arg); - } - } - -private slots: - void recalcParticlesPerSecond(); - -private: - QSet m_pending; - QVector m_lastEmission; - int m_particlesPerParticlePerSecond; - qreal m_lastTimeStamp; - qreal m_emitterXVariation; - qreal m_emitterYVariation; - QString m_follow; - int m_followCount; - ParticleExtruder* m_emissionExtruder; - ParticleExtruder* m_defaultEmissionExtruder; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // FOLLOWEMITTER_H diff --git a/src/imports/particles/frictionaffector.cpp b/src/imports/particles/frictionaffector.cpp deleted file mode 100644 index 057bb20958..0000000000 --- a/src/imports/particles/frictionaffector.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "frictionaffector.h" -QT_BEGIN_NAMESPACE -FrictionAffector::FrictionAffector(QSGItem *parent) : - ParticleAffector(parent), m_factor(0.0) -{ -} - -bool FrictionAffector::affectParticle(ParticleData *d, qreal dt) -{ - if(!m_factor) - return false; - qreal curSX = d->curSX(); - qreal curSY = d->curSY(); - d->setInstantaneousSX(curSX + (curSX * m_factor * -1 * dt)); - d->setInstantaneousSY(curSY + (curSY * m_factor * -1 * dt)); - return true; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/frictionaffector.h b/src/imports/particles/frictionaffector.h deleted file mode 100644 index 67b5f1029c..0000000000 --- a/src/imports/particles/frictionaffector.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FRICTIONAFFECTOR_H -#define FRICTIONAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class FrictionAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged) -public: - explicit FrictionAffector(QSGItem *parent = 0); - - qreal factor() const - { - return m_factor; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void factorChanged(qreal arg); - -public slots: - -void setFactor(qreal arg) -{ - if (m_factor != arg) { - m_factor = arg; - emit factorChanged(arg); - } -} - -private: -qreal m_factor; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // FRICTIONAFFECTOR_H diff --git a/src/imports/particles/gravitationalsingularityaffector.cpp b/src/imports/particles/gravitationalsingularityaffector.cpp deleted file mode 100644 index 4dd7d94b7b..0000000000 --- a/src/imports/particles/gravitationalsingularityaffector.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gravitationalsingularityaffector.h" -#include -#include -QT_BEGIN_NAMESPACE -GravitationalSingularityAffector::GravitationalSingularityAffector(QSGItem *parent) : - ParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) -{ -} - -const qreal LIMIT = 200; -qreal limit(qreal val){ - if(qAbs(val) > LIMIT){ - return val < 0 ? LIMIT * -1 : LIMIT; - }else{ - return val; - } -} - -bool GravitationalSingularityAffector::affectParticle(ParticleData *d, qreal dt) -{ - if(!m_strength) - return false; - qreal dx = m_x - d->curX(); - qreal dy = m_y - d->curY(); - qreal r = sqrt((dx*dx) + (dy*dy)); - if(r < 0.1 ){//Simulated event horizion - It's right on top of it, and will never escape again. just stick it here. - d->pv.ax = 0; - d->pv.ay = 0; - d->pv.sx = 0; - d->pv.sy = 0; - d->pv.x = m_x; - d->pv.y = m_y; - return true; - }else if(r < 50.0){//Too close, typical dt values are far too coarse for simulation. This may kill perf though - int parts = floor(100.0/r); - ParticleData* f = new ParticleData;//Fake, where it's all in real time for convenience - f->pv.x = d->curX(); - f->pv.y = d->curY(); - f->pv.sx = limit(d->curSX()); - f->pv.sy = limit(d->curSY()); - f->pv.ax = d->pv.ax; - f->pv.ay = d->pv.ay; - subaffect(f, dt/parts, true); - for(int i=1; im_timeInt/1000.) - d->pv.t; - qreal sy = limit(f->pv.sy) - t*f->pv.ay; - qreal y = f->pv.y - t*sy - 0.5 * t*t*f->pv.ay; - qreal sx = limit(f->pv.sx) - t*f->pv.ax; - qreal x = f->pv.x - t*sx - 0.5 * t*t*f->pv.ax; - - d->pv.ay = f->pv.ay; - d->pv.sy = sy; - d->pv.y = y; - d->pv.ax = f->pv.ax; - d->pv.sx = sx; - d->pv.x = x; - return true; - } - qreal theta = atan2(dy,dx); - qreal ds = (m_strength / (r*r)) * dt; - dx = ds * cos(theta); - dy = ds * sin(theta); - d->setInstantaneousSX(limit(d->pv.sx + dx)); - d->setInstantaneousSY(limit(d->pv.sy + dy)); - return true; -} - -const qreal EPSILON = 0.1; -bool fuzzyCompare(qreal a, qreal b) -{ - //Not using qFuzzyCompare because I want control of epsilon - return (a >= b - EPSILON && a <= b + EPSILON); -} - -bool fuzzyLess(qreal a, qreal b) -{ - //Not using qFuzzyCompare because I want control of epsilon - return a <= b + EPSILON; -} - -bool fuzzyMore(qreal a, qreal b) -{ - //Not using qFuzzyCompare because I want control of epsilon - return a >= b - EPSILON; -} - -bool lineIntersect(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3) -{ - if(x3 < qMin(x1,x2) || x3 > qMax(x1,x2) || y3 < qMin(y1,y2) || y3 > qMax(y1,y2)) - return false; - qreal m,c; - m = (y2-y1) / (x2-x1); - c = y1 - m*x1; - return (fuzzyCompare(y3, m*x3 + c)); -} - -void GravitationalSingularityAffector::subaffect(ParticleData *d, qreal dt, bool first) -{ - if(!first){ - qreal nextX = d->pv.x + d->pv.sx * dt + d->pv.ax * dt * dt * 0.5; - qreal nextY = d->pv.y + d->pv.sy * dt + d->pv.ay * dt * dt * 0.5; - if(lineIntersect(d->pv.x, d->pv.y, nextX, nextY, m_x, m_y)){ - d->pv.ax = 0; - d->pv.ay = 0; - d->pv.sx = 0; - d->pv.sy = 0; - d->pv.x = m_x; - d->pv.y = m_y; - return; - //Passed center - the near infinite forces cancel out -// d->pv.x = m_x + m_x - d->pv.x; -// d->pv.y = m_y + m_y - d->pv.y; -// d->pv.sx *= -1; -// d->pv.sy *= -1; -// return; - } - //Simulate advancing a dt - d->pv.x = nextX; - d->pv.y = nextY; - d->pv.sx += d->pv.ax * dt; - d->pv.sy += d->pv.ay * dt; - } - qreal dx = m_x - d->pv.x; - qreal dy = m_y - d->pv.y; - qreal r = sqrt((dx*dx) + (dy*dy)); - if(!r) - return; - qreal theta = atan2(dy,dx); - qreal ds = (m_strength / (r*r)) * dt; - dx = ds * cos(theta); - dy = ds * sin(theta); - d->pv.sx = d->pv.sx + dx; - d->pv.sy = d->pv.sy + dy; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/gravitationalsingularityaffector.h b/src/imports/particles/gravitationalsingularityaffector.h deleted file mode 100644 index 7ac5e93e0e..0000000000 --- a/src/imports/particles/gravitationalsingularityaffector.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GRAVITATIONALSINGULARITYAFFECTOR_H -#define GRAVITATIONALSINGULARITYAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class GravitationalSingularityAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) -public: - explicit GravitationalSingularityAffector(QSGItem *parent = 0); - - qreal strength() const - { - return m_strength; - } - - qreal x() const - { - return m_x; - } - - qreal y() const - { - return m_y; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); - void subaffect(ParticleData *d, qreal dt, bool first); -signals: - - void strengthChanged(qreal arg); - - void xChanged(qreal arg); - - void yChanged(qreal arg); - -public slots: - -void setStrength(qreal arg) -{ - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); - } -} - -void setX(qreal arg) -{ - if (m_x != arg) { - m_x = arg; - emit xChanged(arg); - } -} - -void setY(qreal arg) -{ - if (m_y != arg) { - m_y = arg; - emit yChanged(arg); - } -} - -private: -qreal m_strength; -qreal m_x; -qreal m_y; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // GRAVITATIONALSINGULARITYAFFECTOR_H diff --git a/src/imports/particles/gravityaffector.cpp b/src/imports/particles/gravityaffector.cpp deleted file mode 100644 index 02edbacd68..0000000000 --- a/src/imports/particles/gravityaffector.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gravityaffector.h" -#include -QT_BEGIN_NAMESPACE -const qreal CONV = 0.017453292520444443; -GravityAffector::GravityAffector(QSGItem *parent) : - ParticleAffector(parent), m_acceleration(-10), m_angle(90), m_xAcc(0), m_yAcc(0) -{ - connect(this, SIGNAL(accelerationChanged(qreal)), - this, SLOT(recalc())); - connect(this, SIGNAL(angleChanged(qreal)), - this, SLOT(recalc())); - recalc(); -} - -void GravityAffector::recalc() -{ - qreal theta = m_angle * CONV; - m_xAcc = m_acceleration * cos(theta); - m_yAcc = m_acceleration * sin(theta); -} - -bool GravityAffector::affectParticle(ParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - bool changed = false; - if(d->pv.ax != m_xAcc){ - d->setInstantaneousAX(m_xAcc); - changed = true; - } - if(d->pv.ay != m_yAcc){ - d->setInstantaneousAY(m_yAcc); - changed = true; - } - return changed; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/gravityaffector.h b/src/imports/particles/gravityaffector.h deleted file mode 100644 index 004b59e182..0000000000 --- a/src/imports/particles/gravityaffector.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GRAVITYAFFECTOR_H -#define GRAVITYAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class GravityAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) - Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) -public: - explicit GravityAffector(QSGItem *parent = 0); - qreal acceleration() const - { - return m_acceleration; - } - - qreal angle() const - { - return m_angle; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void accelerationChanged(qreal arg); - - void angleChanged(qreal arg); - -public slots: -void setAcceleration(qreal arg) -{ - if (m_acceleration != arg) { - m_acceleration = arg; - emit accelerationChanged(arg); - } -} - -void setAngle(qreal arg) -{ - if (m_angle != arg) { - m_angle = arg; - emit angleChanged(arg); - } -} - -private slots: - void recalc(); -private: - qreal m_acceleration; - qreal m_angle; - - qreal m_xAcc; - qreal m_yAcc; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // GRAVITYAFFECTOR_H diff --git a/src/imports/particles/itemparticle.cpp b/src/imports/particles/itemparticle.cpp deleted file mode 100644 index e31309cf21..0000000000 --- a/src/imports/particles/itemparticle.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "itemparticle.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -ItemParticle::ItemParticle(QSGItem *parent) : - ParticleType(parent), m_fade(true) -{ - setFlag(QSGItem::ItemHasContents); -} - - -void ItemParticle::freeze(QSGItem* item) -{ - m_stasis << item; -} - - -void ItemParticle::unfreeze(QSGItem* item) -{ - m_stasis.remove(item); -} - -void ItemParticle::take(QSGItem *item, bool prioritize) -{ - if(prioritize) - m_pendingItems.push_front(item); - else - m_pendingItems.push_back(item); -} - -void ItemParticle::give(QSGItem *item) -{ - //TODO: This -} - -void ItemParticle::load(ParticleData* d) -{ - if(m_pendingItems.isEmpty()) - return; - int pos = particleTypeIndex(d); - if(m_items[pos]){ - if(m_stasis.contains(m_items[pos])) - qWarning() << "Current model particles prefers overwrite:false"; - //remove old item from the particle that is dying to make room for this one - m_items[pos]->setOpacity(0.); - ItemParticleAttached* mpa; - if((mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[pos], false)))) - mpa->detach();//reparent as well? - m_items[pos] = 0; - m_data[pos] = 0; - m_activeCount--; - } - m_items[pos] = m_pendingItems.front(); - m_pendingItems.pop_front(); - m_items[pos]->setX(d->curX() - m_items[pos]->width()/2); - m_items[pos]->setY(d->curY() - m_items[pos]->height()/2); - ItemParticleAttached* mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[pos])); - if(mpa){ - mpa->m_mp = this; - mpa->attach(); - } - m_items[pos]->setParentItem(this); - m_data[pos] = d; - m_activeCount++; -} - -void ItemParticle::reload(ParticleData* d) -{ - //No-op unless we start copying the data. -} - -void ItemParticle::setCount(int c) -{ - ParticleType::setCount(c);//###Do we need our own? - m_particleCount = c; - reset(); -} - -int ItemParticle::count() -{ - return m_particleCount; -} - -void ItemParticle::reset() -{ - ParticleType::reset(); - //TODO: Cleanup items? - m_items.resize(m_particleCount); - m_data.resize(m_particleCount); - m_items.fill(0); - m_data.fill(0); - //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal? -} - - -QSGNode* ItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d) -{ - //Dummy update just to get painting tick - if(m_pleaseReset){ - m_pleaseReset = false; - reset(); - } - prepareNextFrame(); - - update();//Get called again - if(n) - n->markDirty(QSGNode::DirtyMaterial); - return QSGItem::updatePaintNode(n,d); -} - -void ItemParticle::prepareNextFrame() -{ - qint64 timeStamp = m_system->systemSync(this); - qreal curT = timeStamp/1000.0; - qreal dt = curT - m_lastT; - m_lastT = curT; - if(!m_activeCount) - return; - - //TODO: Size, better fade? - for(int i=0; ipv.t) / data->pv.lifeSpan; - if(m_stasis.contains(item)) { - m_data[i]->pv.t += dt;//Stasis effect - continue; - } - if(t >= 1.0){//Usually happens from load - item->setOpacity(0.); - ItemParticleAttached* mpa; - if((mpa = qobject_cast(qmlAttachedPropertiesObject(m_items[i])))) - mpa->detach();//reparent as well? - m_items[i] = 0; - m_data[i] = 0; - m_activeCount--; - }else{//Fade - if(m_fade){ - qreal o = 1.; - if(t<0.2) - o = t*5; - if(t>0.8) - o = (1-t)*5; - item->setOpacity(o); - }else{ - item->setOpacity(1.);//###Without fade, it's just a binary toggle - if we turn it off we have to turn it back on - } - } - item->setX(data->curX() - item->width()/2); - item->setY(data->curY() - item->height()/2); - } -} - -ItemParticleAttached *ItemParticle::qmlAttachedProperties(QObject *object) -{ - return new ItemParticleAttached(object); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/itemparticle.h b/src/imports/particles/itemparticle.h deleted file mode 100644 index 50414c77b6..0000000000 --- a/src/imports/particles/itemparticle.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ITEMPARTICLE_H -#define ITEMPARTICLE_H -#include "particle.h" -#include -#include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) -class QSGVisualDataModel; -class ItemParticleAttached; - -class ItemParticle : public ParticleType -{ - Q_OBJECT - - Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) -public: - explicit ItemParticle(QSGItem *parent = 0); - - bool fade() const { return m_fade; } - - virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - virtual int count(); - - static ItemParticleAttached *qmlAttachedProperties(QObject *object); -signals: - void fadeChanged(); - -public slots: - //TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it? - void freeze(QSGItem* item); - void unfreeze(QSGItem* item); - void take(QSGItem* item,bool prioritize=false);//take by modelparticle - void give(QSGItem* item);//give from modelparticle - - void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();} -protected: - virtual void reset(); - void prepareNextFrame(); -private: - QList > m_deletables; - int m_particleCount; - bool m_fade; - - QList m_pendingItems; - QVector m_items; - QVector m_data; - QVector m_idx; - QList m_available; - QSet m_stasis; - qreal m_lastT; - int m_activeCount; -}; - -class ItemParticleAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(ItemParticle* particle READ particle CONSTANT); -public: - ItemParticleAttached(QObject* parent) - : QObject(parent), m_mp(0) - {;} - ItemParticle* particle() {return m_mp;} - void detach(){emit detached();} - void attach(){emit attached();} -private: - ItemParticle* m_mp; - friend class ItemParticle; -Q_SIGNALS: - void detached(); - void attached(); -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPEINFO(ItemParticle, QML_HAS_ATTACHED_PROPERTIES) - -QT_END_HEADER -#endif // ITEMPARTICLE_H diff --git a/src/imports/particles/killaffector.cpp b/src/imports/particles/killaffector.cpp deleted file mode 100644 index c98a2f44e2..0000000000 --- a/src/imports/particles/killaffector.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "killaffector.h" -#include "particleemitter.h" -QT_BEGIN_NAMESPACE -KillAffector::KillAffector(QSGItem *parent) : - ParticleAffector(parent) -{ -} - - -bool KillAffector::affectParticle(ParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - if(d->stillAlive()){ - d->pv.t -= d->pv.lifeSpan + 1; - return true; - } -} -QT_END_NAMESPACE diff --git a/src/imports/particles/killaffector.h b/src/imports/particles/killaffector.h deleted file mode 100644 index 937ef321a3..0000000000 --- a/src/imports/particles/killaffector.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef KILLAFFECTOR_H -#define KILLAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class KillAffector : public ParticleAffector -{ - Q_OBJECT -public: - explicit KillAffector(QSGItem *parent = 0); -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - -public slots: - -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // KILLAFFECTOR_H diff --git a/src/imports/particles/lineextruder.cpp b/src/imports/particles/lineextruder.cpp deleted file mode 100644 index 399bdae046..0000000000 --- a/src/imports/particles/lineextruder.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "lineextruder.h" -#include - -LineExtruder::LineExtruder(QObject *parent) : - ParticleExtruder(parent), m_mirrored(false) -{ -} - -QPointF LineExtruder::extrude(const QRectF &r) -{ - qreal x,y; - if(!r.height()){ - x = r.width() * ((qreal)rand())/RAND_MAX; - y = 0; - }else{ - y = r.height() * ((qreal)rand())/RAND_MAX; - if(!r.width()){ - x = 0; - }else{ - x = r.width()/r.height() * y; - if(m_mirrored) - x = r.width() - x; - } - } - return QPointF(x,y); -} diff --git a/src/imports/particles/lineextruder.h b/src/imports/particles/lineextruder.h deleted file mode 100644 index 925f1b3361..0000000000 --- a/src/imports/particles/lineextruder.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LINEEXTRUDER_H -#define LINEEXTRUDER_H -#include "particleextruder.h" - -class LineExtruder : public ParticleExtruder -{ - Q_OBJECT - //Default is topleft to bottom right. Flipped makes it topright to bottom left - Q_PROPERTY(bool mirrored READ mirrored WRITE setmirrored NOTIFY mirroredChanged) - -public: - explicit LineExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - bool mirrored() const - { - return m_mirrored; - } - -signals: - - void mirroredChanged(bool arg); - -public slots: - - void setmirrored(bool arg) - { - if (m_mirrored != arg) { - m_mirrored = arg; - emit mirroredChanged(arg); - } - } -private: - bool m_mirrored; -}; - -#endif // LINEEXTRUDER_H diff --git a/src/imports/particles/main.cpp b/src/imports/particles/main.cpp deleted file mode 100644 index 072025d6bc..0000000000 --- a/src/imports/particles/main.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "V1/qdeclarativeparticles_p.h" -#include "pluginmain.h" -#include "spritestate.h" -#include "spriteengine.h" -#include "particleaffector.h" -#include "wanderaffector.h" -//#include "rockingaffector.h" -//#include "scalingaffector.h" -#include "resetaffector.h" -#include "gravityaffector.h" -#include "driftaffector.h" -#include "gravitationalsingularityaffector.h" -#include "frictionaffector.h" -#include "meanderaffector.h" -#include "attractoraffector.h" -#include "speedlimitaffector.h" -#include "killaffector.h" -//#include "zoneaffector.h" -//#include "toggleaffector.h" -#include "spritegoalaffector.h" -#include "swarmaffector.h" -#include "turbulenceaffector.h" -#include "eternalaffector.h" -#include "particlesystem.h" -#include "particleemitter.h" -//#include "spriteemitter.h" -#include "trailsemitter.h" -#include "burstemitter.h" -#include "particle.h" -#include "coloredparticle.h" -#include "spriteparticle.h" -//#include "modelparticle.h" -#include "dataparticle.h" -#include "itemparticle.h" -#include "superparticle.h" -#include "ultraparticle.h" -//#include "pairedparticle.h" -#include "spriteimage.h" -#include "followemitter.h" -#include "particleextruder.h" -#include "ellipseextruder.h" -#include "lineextruder.h" -#include "maskextruder.h" -#include "varyingvector.h" -#include "pointvector.h" -#include "angledvector.h" -#include "directedvector.h" -//#include "followaffector.h" -#include "deformableparticle.h" -#include "pictureaffector.h" - -QT_BEGIN_NAMESPACE - -void ParticlesPlugin::registerTypes(const char *uri) -{ - Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.particles")); - - qmlRegisterType(uri, 1, 0, "Particles"); - qmlRegisterType(uri,1,0,"ParticleMotion"); - qmlRegisterType(uri,1,0,"ParticleMotionGravity"); - qmlRegisterType(uri,1,0,"ParticleMotionLinear"); - qmlRegisterType(uri,1,0,"ParticleMotionWander"); - qmlRegisterType(uri, 2, 0, "Sprite"); - qmlRegisterType(uri, 2, 0, "SpriteEngine"); - qmlRegisterType(uri, 2, 0, "SpriteImage"); - - qmlRegisterType(uri, 2, 0, "ParticleSystem"); - - qmlRegisterType(uri, 2, 0, "Particle"); - qmlRegisterType(uri, 2, 0, "ColoredParticle"); - qmlRegisterType(uri, 2, 0, "SpriteParticle"); - //qmlRegisterType(uri, 2, 0, "ModelParticle"); - qmlRegisterType(uri, 2, 0, "DataParticle"); - qmlRegisterType(uri, 2, 0, "ItemParticle"); - //qmlRegisterType(uri, 2, 0, "PairedParticle"); - qmlRegisterType(uri, 2, 0, "DeformableParticle"); - qmlRegisterType(uri, 2, 0, "SuperParticle"); - qmlRegisterType(uri, 2, 0, "UltraParticle"); - - qmlRegisterType(uri, 2, 0, "ParticleEmitter"); - qmlRegisterType(uri, 2, 0, "TrailEmitter"); - qmlRegisterType(uri, 2, 0, "BurstEmitter"); - - qmlRegisterType(uri, 2, 0, "FollowEmitter"); - qmlRegisterType(uri, 2, 0, "Box"); - qmlRegisterType(uri, 2, 0, "Ellipse"); - qmlRegisterType(uri, 2, 0, "Line"); - qmlRegisterType(uri, 2, 0, "Mask"); - - qmlRegisterType(uri, 2, 0, "NullVector"); - qmlRegisterType(uri, 2, 0, "PointVector"); - qmlRegisterType(uri, 2, 0, "AngleVector"); - qmlRegisterType(uri, 2, 0, "DirectedVector"); - - qmlRegisterType(uri, 2, 0, "ParticleAffector"); - qmlRegisterType(uri, 2, 0, "Wander"); - //qmlRegisterType(uri, 2, 0, "Scale"); - //qmlRegisterType(uri, 2, 0, "Rocking"); - qmlRegisterType(uri, 2, 0, "Drift"); - qmlRegisterType(uri, 2, 0, "Friction"); - qmlRegisterType(uri, 2, 0, "GravitationalSingularity"); - qmlRegisterType(uri, 2, 0, "Attractor"); - qmlRegisterType(uri, 2, 0, "Meander"); - qmlRegisterType(uri, 2, 0, "SpeedLimit"); - qmlRegisterType(uri, 2, 0, "Gravity"); - qmlRegisterType(uri, 2, 0, "Stasis"); - qmlRegisterType(uri, 2, 0, "Reset"); - //qmlRegisterType(uri, 2, 0, "Zone"); - //qmlRegisterType(uri, 2, 0, "Toggle"); - qmlRegisterType(uri, 2, 0, "Kill"); - qmlRegisterType(uri, 2, 0, "SpriteGoal"); - qmlRegisterType(uri, 2, 0 , "Swarm"); - qmlRegisterType(uri, 2, 0 , "Turbulence"); - qmlRegisterType(uri, 2, 0, "Picture"); -} - -QT_END_NAMESPACE - -Q_EXPORT_PLUGIN2(Particles, QT_PREPEND_NAMESPACE(ParticlesPlugin)) diff --git a/src/imports/particles/maskextruder.cpp b/src/imports/particles/maskextruder.cpp deleted file mode 100644 index 53dacf4214..0000000000 --- a/src/imports/particles/maskextruder.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "maskextruder.h" -#include -#include -QT_BEGIN_NAMESPACE -MaskExtruder::MaskExtruder(QObject *parent) : - ParticleExtruder(parent) - , m_lastWidth(-1) - , m_lastHeight(-1) -{ -} - -QPointF MaskExtruder::extrude(const QRectF &r) -{ - ensureInitialized(r); - if(!m_mask.count()) - return r.topLeft(); - const QPointF p = m_mask[rand() % m_mask.count()]; - //### Should random sub-pixel positioning be added? - return p + r.topLeft(); -} - -bool MaskExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? - QPoint p = point.toPoint() - bounds.topLeft().toPoint(); - return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); -} - -void MaskExtruder::ensureInitialized(const QRectF &r) -{ - if(m_lastWidth == r.width() && m_lastHeight == r.height()) - return; - m_lastWidth = r.width(); - m_lastHeight = r.height(); - - m_mask.clear(); - if(m_source.isEmpty()) - return; - m_img = QImage(m_source.toLocalFile()); - m_img = m_img.createAlphaMask(); - m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier - m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? - for(int i=0; i -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class MaskExtruder : public ParticleExtruder -{ - Q_OBJECT - Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) -public: - explicit MaskExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point); - - QUrl source() const - { - return m_source; - } - -signals: - - void sourceChanged(QUrl arg); - -public slots: - - void setSource(QUrl arg) - { - if (m_source != arg) { - m_source = arg; - m_lastHeight = -1;//Trigger reset - m_lastWidth = -1; - emit sourceChanged(arg); - } - } -private: - QUrl m_source; - - void ensureInitialized(const QRectF &r); - int m_lastWidth; - int m_lastHeight; - QImage m_img; - QList m_mask;//TODO: More memory efficient datastructures -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // MASKEXTRUDER_H diff --git a/src/imports/particles/meanderaffector.cpp b/src/imports/particles/meanderaffector.cpp deleted file mode 100644 index 8e03cd07fb..0000000000 --- a/src/imports/particles/meanderaffector.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "meanderaffector.h" - -QT_BEGIN_NAMESPACE - -MeanderAffector::MeanderAffector(QSGItem *parent) : - ParticleAffector(parent) -{ -} - -bool MeanderAffector::affectParticle(ParticleData *data, qreal dt) -{ - if(!m_xDrift && !m_yDrift) - return false; - qreal dx = (((qreal)qrand() / (qreal)RAND_MAX) - 0.5) * 2 * m_xDrift * dt; - qreal dy = (((qreal)qrand() / (qreal)RAND_MAX) - 0.5) * 2 * m_yDrift * dt; - if(dx) - data->setInstantaneousAX(data->pv.ax + dx); - if(dy) - data->setInstantaneousAY(data->pv.ay + dy); - - return true; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/meanderaffector.h b/src/imports/particles/meanderaffector.h deleted file mode 100644 index 203d20430d..0000000000 --- a/src/imports/particles/meanderaffector.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MEANDERAFFECTOR_H -#define MEANDERAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class MeanderAffector : public ParticleAffector -{ - Q_OBJECT - //Like drift, but affects da/dt instead of ds/dt - Q_PROPERTY(qreal xDrift READ xDrift WRITE setXDrift NOTIFY xDriftChanged) - Q_PROPERTY(qreal yDrift READ yDrift WRITE setYDrift NOTIFY yDriftChanged) -public: - explicit MeanderAffector(QSGItem *parent = 0); - - qreal xDrift() const - { - return m_xDrift; - } - - qreal yDrift() const - { - return m_yDrift; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void xDriftChanged(qreal arg); - - void yDriftChanged(qreal arg); - -public slots: - - void setXDrift(qreal arg) - { - if (m_xDrift != arg) { - m_xDrift = arg; - emit xDriftChanged(arg); - } - } - void setYDrift(qreal arg) - { - if (m_yDrift != arg) { - m_yDrift = arg; - emit yDriftChanged(arg); - } - } - -private: - qreal m_xDrift; - qreal m_yDrift; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // MEANDERAFFECTOR_H diff --git a/src/imports/particles/particle.cpp b/src/imports/particles/particle.cpp deleted file mode 100644 index 8f4ecbf733..0000000000 --- a/src/imports/particles/particle.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "particle.h" -#include -QT_BEGIN_NAMESPACE -ParticleType::ParticleType(QSGItem *parent) : - QSGItem(parent), - m_system(0) -{ - connect(this, SIGNAL(xChanged()), - this, SLOT(calcSystemOffset())); - connect(this, SIGNAL(yChanged()), - this, SLOT(calcSystemOffset())); -} - -void ParticleType::componentComplete() -{ - if(!m_system) - qWarning() << "Particle created without a particle system specified";//TODO: useful QML warnings, like line number? - QSGItem::componentComplete(); -} - - -void ParticleType::setSystem(ParticleSystem *arg) -{ - if (m_system != arg) { - m_system = arg; - if(m_system){ - m_system->registerParticleType(this); - connect(m_system, SIGNAL(xChanged()), - this, SLOT(calcSystemOffset())); - connect(m_system, SIGNAL(yChanged()), - this, SLOT(calcSystemOffset())); - calcSystemOffset(); - } - emit systemChanged(arg); - } -} - -void ParticleType::load(ParticleData*) -{ -} - -void ParticleType::reload(ParticleData*) -{ -} - -void ParticleType::reset() -{ - //Have to every time because what it's emitting may have changed and that affects particleTypeIndex - m_particleStarts.clear(); - m_lastStart = 0; -} - -void ParticleType::setCount(int c) -{ - if(c == m_count) - return; - m_count = c; - emit countChanged(); -} - -int ParticleType::count() -{ - return m_count; -} - - -int ParticleType::particleTypeIndex(ParticleData* d) -{ - if(!m_particleStarts.contains(d->group)){ - m_particleStarts.insert(d->group, m_lastStart); - m_lastStart += m_system->m_groupData[d->group]->size; - } - int ret = m_particleStarts[d->group] + d->particleIndex; - Q_ASSERT(ret >=0 && ret < m_count);//XXX: Possibly shouldn't assert, but bugs here were hard to find in the past - return ret; -} - - -void ParticleType::calcSystemOffset() -{ - if(!m_system) - return; - QPointF lastOffset = m_systemOffset; - m_systemOffset = this->mapFromItem(m_system, QPointF()); - if(lastOffset != m_systemOffset){ - //Reload all particles - foreach(const QString &g, m_particles){ - int gId = m_system->m_groupIds[g]; - for(int i=0; im_groupData[gId]->size; i++) - reload(m_system->m_data[m_system->m_groupData[gId]->start + i]); - } - } -} -QT_END_NAMESPACE diff --git a/src/imports/particles/particle.h b/src/imports/particles/particle.h deleted file mode 100644 index fbb9665a64..0000000000 --- a/src/imports/particles/particle.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLE_H -#define PARTICLE_H - -#include -#include -#include "particlesystem.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class ParticleType : public QSGItem -{ - Q_OBJECT - Q_PROPERTY(ParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) - -public: - explicit ParticleType(QSGItem *parent = 0); - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - virtual int count(); - ParticleSystem* system() const - { - return m_system; - } - - - QStringList particles() const - { - return m_particles; - } - - int particleTypeIndex(ParticleData*); - virtual void componentComplete(); -signals: - void countChanged(); - void systemChanged(ParticleSystem* arg); - - void particlesChanged(QStringList arg); - -public slots: -void setSystem(ParticleSystem* arg); - -void setParticles(QStringList arg) -{ - if (m_particles != arg) { - m_particles = arg; - emit particlesChanged(arg); - } -} -private slots: - void calcSystemOffset(); -protected: - virtual void reset(); - -// virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *){ -// qDebug() << "Shouldn't be here..." << this; -// return 0; -// } - - ParticleSystem* m_system; - friend class ParticleSystem; - int m_count; - bool m_pleaseReset; - QStringList m_particles; - QHash m_particleStarts; - int m_lastStart; - QPointF m_systemOffset; - - template - void vertexCopy(VertexStruct &b, const ParticleVertex& a) - { - b.x = a.x - m_systemOffset.x(); - b.y = a.y - m_systemOffset.y(); - b.t = a.t; - b.lifeSpan = a.lifeSpan; - b.size = a.size; - b.endSize = a.endSize; - b.sx = a.sx; - b.sy = a.sy; - b.ax = a.ax; - b.ay = a.ay; - } - -private: -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // PARTICLE_H diff --git a/src/imports/particles/particleaffector.cpp b/src/imports/particles/particleaffector.cpp deleted file mode 100644 index 73564a940a..0000000000 --- a/src/imports/particles/particleaffector.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "particleaffector.h" -#include -QT_BEGIN_NAMESPACE -ParticleAffector::ParticleAffector(QSGItem *parent) : - QSGItem(parent), m_needsReset(false), m_system(0), m_active(true) - , m_updateIntSet(false), m_shape(new ParticleExtruder(this)), m_signal(false) -{ - connect(this, SIGNAL(systemChanged(ParticleSystem*)), - this, SLOT(updateOffsets())); - connect(this, SIGNAL(xChanged()), - this, SLOT(updateOffsets())); - connect(this, SIGNAL(yChanged()), - this, SLOT(updateOffsets()));//TODO: in componentComplete and all relevant signals -} - -void ParticleAffector::componentComplete() -{ - if(!m_system) - qWarning() << "Affector created without a particle system specified";//TODO: useful QML warnings, like line number? - QSGItem::componentComplete(); -} - -void ParticleAffector::affectSystem(qreal dt) -{ - if(!m_active) - return; - if(!m_system){ - qDebug() << "No system" << this; - return; - } - //If not reimplemented, calls affect particle per particle - //But only on particles in targeted system/area - if(m_updateIntSet){ - m_groups.clear(); - foreach(const QString &p, m_particles) - m_groups << m_system->m_groupIds[p];//###Can this occur before group ids are properly assigned? - m_updateIntSet = false; - } - //foreach(ParticleData* d, m_system->m_data){ - for(int i=0; im_particle_count; i++){ - ParticleData* d = m_system->m_data[i]; - if(!d || (m_onceOff && m_onceOffed.contains(d->systemIndex))) - continue; - if(m_groups.isEmpty() || m_groups.contains(d->group)){ - //Need to have previous location for affected. if signal || shape might be faster? - QPointF curPos = QPointF(d->curX(), d->curY()); - if(width() == 0 || height() == 0 - || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()),curPos)){ - if(affectParticle(d, dt)){ - m_system->m_needsReset << d; - if(m_onceOff) - m_onceOffed << d->systemIndex; - if(m_signal) - emit affected(curPos.x(), curPos.y()); - } - } - } - } -} - -bool ParticleAffector::affectParticle(ParticleData *d, qreal dt) -{ - Q_UNUSED(d); - Q_UNUSED(dt); - return false; -} - -void ParticleAffector::reset(int idx) -{//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass - if(m_onceOff) - m_onceOffed.remove(idx); -} - -void ParticleAffector::updateOffsets() -{ - if(m_system) - m_offset = m_system->mapFromItem(this, QPointF(0, 0)); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/particleaffector.h b/src/imports/particles/particleaffector.h deleted file mode 100644 index 3a92263092..0000000000 --- a/src/imports/particles/particleaffector.h +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLEAFFECTOR_H -#define PARTICLEAFFECTOR_H - -#include -#include "particlesystem.h" -#include "particleextruder.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class ParticleAffector : public QSGItem -{ - Q_OBJECT - Q_PROPERTY(ParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) - Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) - Q_PROPERTY(bool onceOff READ onceOff WRITE setOnceOff NOTIFY onceOffChanged) - Q_PROPERTY(ParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) - Q_PROPERTY(bool signal READ signal WRITE setSignal NOTIFY signalChanged) - -public: - explicit ParticleAffector(QSGItem *parent = 0); - virtual void affectSystem(qreal dt); - virtual void reset(int systemIdx);//As some store their own data per idx? - ParticleSystem* system() const - { - return m_system; - } - - QStringList particles() const - { - return m_particles; - } - - bool active() const - { - return m_active; - } - - bool onceOff() const - { - return m_onceOff; - } - - ParticleExtruder* shape() const - { - return m_shape; - } - - bool signal() const - { - return m_signal; - } - -signals: - - void systemChanged(ParticleSystem* arg); - - void particlesChanged(QStringList arg); - - void activeChanged(bool arg); - - void onceOffChanged(bool arg); - - void shapeChanged(ParticleExtruder* arg); - - void affected(qreal x, qreal y);//###Idx too? - void signalChanged(bool arg); - -public slots: -void setSystem(ParticleSystem* arg) -{ - if (m_system != arg) { - m_system = arg; - m_system->registerParticleAffector(this); - emit systemChanged(arg); - } -} - -void setParticles(QStringList arg) -{ - if (m_particles != arg) { - m_particles = arg; - m_updateIntSet = true; - emit particlesChanged(arg); - } -} - -void setActive(bool arg) -{ - if (m_active != arg) { - m_active = arg; - emit activeChanged(arg); - } -} - -void setOnceOff(bool arg) -{ - if (m_onceOff != arg) { - m_onceOff = arg; - emit onceOffChanged(arg); - } -} - -void setShape(ParticleExtruder* arg) -{ - if (m_shape != arg) { - m_shape = arg; - emit shapeChanged(arg); - } -} - -void setSignal(bool arg) -{ - if (m_signal != arg) { - m_signal = arg; - emit signalChanged(arg); - } -} - -protected: - friend class ParticleSystem; - virtual bool affectParticle(ParticleData *d, qreal dt); - bool m_needsReset;//### What is this really saving? - ParticleSystem* m_system; - QStringList m_particles; - bool activeGroup(int g) {return m_groups.isEmpty() || m_groups.contains(g);} - bool m_active; - virtual void componentComplete(); - QPointF m_offset; -private: - QSet m_groups; - QSet m_onceOffed; - bool m_updateIntSet; - - bool m_onceOff; - - ParticleExtruder* m_shape; - - bool m_signal; - -private slots: - void updateOffsets(); -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // PARTICLEAFFECTOR_H diff --git a/src/imports/particles/particleemitter.cpp b/src/imports/particles/particleemitter.cpp deleted file mode 100644 index dd7d73749b..0000000000 --- a/src/imports/particles/particleemitter.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "particleemitter.h" -QT_BEGIN_NAMESPACE -ParticleEmitter::ParticleEmitter(QSGItem *parent) : - QSGItem(parent) - , m_particlesPerSecond(10) - , m_particleDuration(1000) - , m_particleDurationVariation(0) - , m_emitting(true) - , m_system(0) - , m_extruder(0) - , m_defaultExtruder(0) - , m_speed(&m_nullVector) - , m_acceleration(&m_nullVector) - , m_particleSize(16) - , m_particleEndSize(-1) - , m_particleSizeVariation(0) - , m_maxParticleCount(-1) - , m_burstLeft(0) - -{ - //TODO: Reset speed/acc back to null vector? Or allow null pointer? - connect(this, SIGNAL(maxParticleCountChanged(int)), - this, SIGNAL(particleCountChanged())); - connect(this, SIGNAL(particlesPerSecondChanged(qreal)), - this, SIGNAL(particleCountChanged())); - connect(this, SIGNAL(particleDurationChanged(int)), - this, SIGNAL(particleCountChanged())); -} - -ParticleEmitter::~ParticleEmitter() -{ - if(m_defaultExtruder) - delete m_defaultExtruder; -} - -void ParticleEmitter::componentComplete() -{ - if(!m_system) - qWarning() << "Emitter created without a particle system specified";//TODO: useful QML warnings, like line number? - QSGItem::componentComplete(); -} -void ParticleEmitter::emitWindow(int timeStamp) -{ - Q_UNUSED(timeStamp); -} - - -void ParticleEmitter::setEmitting(bool arg) -{ - if (m_emitting != arg) { - m_emitting = arg; - emit emittingChanged(arg); - } -} - - -ParticleExtruder* ParticleEmitter::effectiveExtruder() -{ - if(m_extruder) - return m_extruder; - if(!m_defaultExtruder) - m_defaultExtruder = new ParticleExtruder; - return m_defaultExtruder; -} - -void ParticleEmitter::pulse(qreal seconds) -{ - if(!particleCount()) - qWarning() << "pulse called on an emitter with a particle count of zero"; - if(!m_emitting) - m_burstLeft = seconds*1000.0;//TODO: Change name to match -} - -void ParticleEmitter::burst(int num) -{ - if(!particleCount()) - qWarning() << "burst called on an emitter with a particle count of zero"; - m_burstQueue << qMakePair(num, QPointF(x(), y())); -} - -void ParticleEmitter::setMaxParticleCount(int arg) -{ - if (m_maxParticleCount != arg) { - if(arg < 0 && m_maxParticleCount >= 0){ - connect(this, SIGNAL(particlesPerSecondChanged(qreal)), - this, SIGNAL(particleCountChanged())); - connect(this, SIGNAL(particleDurationChanged(int)), - this, SIGNAL(particleCountChanged())); - }else if(arg >= 0 && m_maxParticleCount < 0){ - disconnect(this, SIGNAL(particlesPerSecondChanged(qreal)), - this, SIGNAL(particleCountChanged())); - disconnect(this, SIGNAL(particleDurationChanged(int)), - this, SIGNAL(particleCountChanged())); - } - m_maxParticleCount = arg; - emit maxParticleCountChanged(arg); - } -} - -int ParticleEmitter::particleCount() const -{ - if(m_maxParticleCount >= 0) - return m_maxParticleCount; - return m_particlesPerSecond*((m_particleDuration+m_particleDurationVariation)/1000.0); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/particleemitter.h b/src/imports/particles/particleemitter.h deleted file mode 100644 index e272ae51ab..0000000000 --- a/src/imports/particles/particleemitter.h +++ /dev/null @@ -1,304 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLEEMITTER_H -#define PARTICLEEMITTER_H - -#include -#include -#include "particlesystem.h" -#include "particleextruder.h" -#include "varyingvector.h" - -#include -#include -#include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class ParticleEmitter : public QSGItem -{ - Q_OBJECT - //###currently goes in emitters OR sets system. Pick one? - Q_PROPERTY(ParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QString particle READ particle WRITE setParticle NOTIFY particleChanged) - Q_PROPERTY(ParticleExtruder* shape READ extruder WRITE setExtruder NOTIFY extruderChanged) - Q_PROPERTY(bool emitting READ emitting WRITE setEmitting NOTIFY emittingChanged) - - Q_PROPERTY(qreal particlesPerSecond READ particlesPerSecond WRITE setParticlesPerSecond NOTIFY particlesPerSecondChanged) - Q_PROPERTY(int particleDuration READ particleDuration WRITE setParticleDuration NOTIFY particleDurationChanged) - Q_PROPERTY(int particleDurationVariation READ particleDurationVariation WRITE setParticleDurationVariation NOTIFY particleDurationVariationChanged) - Q_PROPERTY(int maxParticles READ maxParticleCount WRITE setMaxParticleCount NOTIFY maxParticleCountChanged) - - Q_PROPERTY(qreal particleSize READ particleSize WRITE setParticleSize NOTIFY particleSizeChanged) - Q_PROPERTY(qreal particleEndSize READ particleEndSize WRITE setParticleEndSize NOTIFY particleEndSizeChanged) - Q_PROPERTY(qreal particleSizeVariation READ particleSizeVariation WRITE setParticleSizeVariation NOTIFY particleSizeVariationChanged) - - Q_PROPERTY(VaryingVector *speed READ speed WRITE setSpeed NOTIFY speedChanged) - Q_PROPERTY(VaryingVector *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) -public: - explicit ParticleEmitter(QSGItem *parent = 0); - virtual ~ParticleEmitter(); - virtual void emitWindow(int timeStamp); - - bool emitting() const - { - return m_emitting; - } - - qreal particlesPerSecond() const - { - return m_particlesPerSecond; - } - - int particleDuration() const - { - return m_particleDuration; - } - - ParticleSystem* system() const - { - return m_system; - } - - QString particle() const - { - return m_particle; - } - - int particleDurationVariation() const - { - return m_particleDurationVariation; - } - - virtual void componentComplete(); -signals: - void particlesPerSecondChanged(qreal); - void particleDurationChanged(int); - void emittingChanged(bool); - - void systemChanged(ParticleSystem* arg); - - void particleChanged(QString arg); - - void particleDurationVariationChanged(int arg); - - void extruderChanged(ParticleExtruder* arg); - - void particleSizeChanged(qreal arg); - - void particleEndSizeChanged(qreal arg); - - void particleSizeVariationChanged(qreal arg); - - void speedChanged(VaryingVector * arg); - - void accelerationChanged(VaryingVector * arg); - - void maxParticleCountChanged(int arg); - void particleCountChanged(); - -public slots: - void pulse(qreal seconds); - void burst(int num); - - void setEmitting(bool arg); - - void setParticlesPerSecond(qreal arg) - { - if (m_particlesPerSecond != arg) { - m_particlesPerSecond = arg; - emit particlesPerSecondChanged(arg); - } - } - - void setParticleDuration(int arg) - { - if (m_particleDuration != arg) { - m_particleDuration = arg; - emit particleDurationChanged(arg); - } - } - - void setSystem(ParticleSystem* arg) - { - if (m_system != arg) { - m_system = arg; - m_system->registerParticleEmitter(this); - emit systemChanged(arg); - } - } - - void setParticle(QString arg) - { - if (m_particle != arg) { - m_particle = arg; - emit particleChanged(arg); - } - } - - void setParticleDurationVariation(int arg) - { - if (m_particleDurationVariation != arg) { - m_particleDurationVariation = arg; - emit particleDurationVariationChanged(arg); - } - } - void setExtruder(ParticleExtruder* arg) - { - if (m_extruder != arg) { - m_extruder = arg; - emit extruderChanged(arg); - } - } - - void setParticleSize(qreal arg) - { - if (m_particleSize != arg) { - m_particleSize = arg; - emit particleSizeChanged(arg); - } - } - - void setParticleEndSize(qreal arg) - { - if (m_particleEndSize != arg) { - m_particleEndSize = arg; - emit particleEndSizeChanged(arg); - } - } - - void setParticleSizeVariation(qreal arg) - { - if (m_particleSizeVariation != arg) { - m_particleSizeVariation = arg; - emit particleSizeVariationChanged(arg); - } - } - - void setSpeed(VaryingVector * arg) - { - if (m_speed != arg) { - m_speed = arg; - emit speedChanged(arg); - } - } - - void setAcceleration(VaryingVector * arg) - { - if (m_acceleration != arg) { - m_acceleration = arg; - emit accelerationChanged(arg); - } - } - - void setMaxParticleCount(int arg); - -public: - int particleCount() const; - - virtual void reset(){;} - ParticleExtruder* extruder() const - { - return m_extruder; - } - - qreal particleSize() const - { - return m_particleSize; - } - - qreal particleEndSize() const - { - return m_particleEndSize; - } - - qreal particleSizeVariation() const - { - return m_particleSizeVariation; - } - - VaryingVector * speed() const - { - return m_speed; - } - - VaryingVector * acceleration() const - { - return m_acceleration; - } - - int maxParticleCount() const - { - return m_maxParticleCount; - } - -protected: - qreal m_particlesPerSecond; - int m_particleDuration; - int m_particleDurationVariation; - bool m_emitting; - ParticleSystem* m_system; - QString m_particle; - ParticleExtruder* m_extruder; - ParticleExtruder* m_defaultExtruder; - ParticleExtruder* effectiveExtruder(); - VaryingVector * m_speed; - VaryingVector * m_acceleration; - qreal m_particleSize; - qreal m_particleEndSize; - qreal m_particleSizeVariation; - - int m_burstLeft;//TODO: Rename to pulse - QList > m_burstQueue; - int m_maxParticleCount; -private: - VaryingVector m_nullVector; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PARTICLEEMITTER_H diff --git a/src/imports/particles/particleextruder.cpp b/src/imports/particles/particleextruder.cpp deleted file mode 100644 index 3ff5abf996..0000000000 --- a/src/imports/particles/particleextruder.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "particleextruder.h" - -QT_BEGIN_NAMESPACE - -ParticleExtruder::ParticleExtruder(QObject *parent) : - QObject(parent), m_fill(true) -{ -} - -QPointF ParticleExtruder::extrude(const QRectF &rect) -{ - if(m_fill) - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); - int side = rand() % 4; - switch(side){//TODO: Doesn't this overlap the corners? - case 0: - return QPointF(rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); - case 1: - return QPointF(rect.width() + rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); - case 2: - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - rect.y()); - default: - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - rect.height() + rect.y()); - } -} - -bool ParticleExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - return bounds.contains(point); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/particleextruder.h b/src/imports/particles/particleextruder.h deleted file mode 100644 index 2c417d3f92..0000000000 --- a/src/imports/particles/particleextruder.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLEEXTRUDER_H -#define PARTICLEEXTRUDER_H - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class ParticleExtruder : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Should this be base class, or a BoxExtruder? - -public: - explicit ParticleExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point);//###Needed for follow emitter, but does it belong? Only marginally conceptually valid, and that's from user's perspective - bool fill() const - { - return m_fill; - } - -signals: - - void fillChanged(bool arg); - -public slots: - - void setFill(bool arg) - { - if (m_fill != arg) { - m_fill = arg; - emit fillChanged(arg); - } - } -protected: - bool m_fill; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PARTICLEEXTRUDER_H diff --git a/src/imports/particles/particles.cpp b/src/imports/particles/particles.cpp new file mode 100644 index 0000000000..b30beb5c74 --- /dev/null +++ b/src/imports/particles/particles.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "V1/qdeclarativeparticles_p.h" + +QT_BEGIN_NAMESPACE + +class QParticlesQmlModule : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + virtual void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.particles")); + qmlRegisterType(uri,1,0,"ParticleMotion"); + qmlRegisterType(uri,1,0,"ParticleMotionGravity"); + qmlRegisterType(uri,1,0,"ParticleMotionLinear"); + qmlRegisterType(uri,1,0,"ParticleMotionWander"); + qmlRegisterType(uri,1,0,"Particles"); + } +}; + +QT_END_NAMESPACE + +#include "particles.moc" + +Q_EXPORT_PLUGIN2(qmlparticlesplugin, QT_PREPEND_NAMESPACE(QParticlesQmlModule)); + diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro index a6930fe95c..56f663f328 100644 --- a/src/imports/particles/particles.pro +++ b/src/imports/particles/particles.pro @@ -3,118 +3,17 @@ TARGETPATH = Qt/labs/particles include(../qimportbase.pri) HEADERS += \ - V1/qdeclarativeparticles_p.h \ - spritestate.h \ - pluginmain.h \ - particleaffector.h \ - wanderaffector.h \ - #rockingaffector.h \ - #scalingaffector.h \ - driftaffector.h \ - particleemitter.h \ - particlesystem.h \ - trailsemitter.h \ - #spriteemitter.h \ - particle.h \ - coloredparticle.h \ - spriteparticle.h \ - spritegoalaffector.h \ - #zoneaffector.h \ - frictionaffector.h \ - gravitationalsingularityaffector.h \ - killaffector.h \ - speedlimitaffector.h \ - spriteengine.h \ - gravityaffector.h \ - attractoraffector.h \ - meanderaffector.h \ - #toggleaffector.h \ - spriteimage.h \ - #pairedparticle.h \ - followemitter.h \ - swarmaffector.h \ - turbulenceaffector.h \ - particleextruder.h \ - ellipseextruder.h \ - maskextruder.h \ - varyingvector.h \ - pointvector.h \ - angledvector.h \ - directedvector.h \ - #modelparticle.h \ - eternalaffector.h \ - lineextruder.h \ - resetaffector.h \ - deformableparticle.h \ - pictureaffector.h \ - superparticle.h \ - ultraparticle.h \ - burstemitter.h \ - dataparticle.h \ - itemparticle.h + V1/qdeclarativeparticles_p.h SOURCES += \ - V1/qdeclarativeparticles.cpp \ - spritestate.cpp \ - main.cpp \ - particleaffector.cpp \ - wanderaffector.cpp \ - #rockingaffector.cpp \ - #scalingaffector.cpp \ - driftaffector.cpp \ - particleemitter.cpp \ - particlesystem.cpp \ - trailsemitter.cpp \ - #spriteemitter.cpp \ - particle.cpp \ - coloredparticle.cpp \ - spriteparticle.cpp \ - spritegoalaffector.cpp \ - #zoneaffector.cpp \ - frictionaffector.cpp \ - gravitationalsingularityaffector.cpp \ - killaffector.cpp \ - speedlimitaffector.cpp \ - spriteengine.cpp \ - gravityaffector.cpp \ - attractoraffector.cpp \ - meanderaffector.cpp \ - #toggleaffector.cpp \ - spriteimage.cpp \ - #pairedparticle.cpp \ - followemitter.cpp \ - swarmaffector.cpp \ - turbulenceaffector.cpp \ - particleextruder.cpp \ - ellipseextruder.cpp \ - maskextruder.cpp \ - varyingvector.cpp \ - pointvector.cpp \ - angledvector.cpp \ - directedvector.cpp \ - #modelparticle.cpp \ - eternalaffector.cpp \ - lineextruder.cpp \ - resetaffector.cpp \ - deformableparticle.cpp \ - pictureaffector.cpp \ - superparticle.cpp \ - ultraparticle.cpp \ - burstemitter.cpp \ - dataparticle.cpp \ - itemparticle.cpp - -QT += declarative opengl -#Because we use QDeclarativePixmapCache once... -QT += core-private gui-private declarative-private script-private + particles.cpp \ + V1/qdeclarativeparticles.cpp +QT += declarative opengl core gui declarative-private core-private gui-private OTHER_FILES += \ qmldir -RESOURCES += \ - spriteparticles.qrc - DESTDIR = $$QT.declarative.imports/$$TARGETPATH target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH diff --git a/src/imports/particles/particlesystem.cpp b/src/imports/particles/particlesystem.cpp deleted file mode 100644 index 0c9180c2d8..0000000000 --- a/src/imports/particles/particlesystem.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "particlesystem.h" -#include -#include "particleemitter.h" -#include "particleaffector.h" -#include "particle.h" -#include -#include - -QT_BEGIN_NAMESPACE - -ParticleData::ParticleData() - : group(0) - , e(0) - , particleIndex(0) - , systemIndex(0) -{ - pv.x = 0; - pv.y = 0; - pv.t = -1; - pv.size = 0; - pv.endSize = 0; - pv.sx = 0; - pv.sy = 0; - pv.ax = 0; - pv.ay = 0; -} - -ParticleSystem::ParticleSystem(QSGItem *parent) : - QSGItem(parent), m_particle_count(0), m_running(true) , m_startTime(0), m_overwrite(false) -{ - m_groupIds = QHash(); -} - -void ParticleSystem::registerParticleType(ParticleType* p) -{ - m_particles << QPointer(p);//###Set or uniqueness checking? - reset(); -} - -void ParticleSystem::registerParticleEmitter(ParticleEmitter* e) -{ - m_emitters << QPointer(e);//###How to get them out? - connect(e, SIGNAL(particleCountChanged()), - this, SLOT(countChanged())); - connect(e, SIGNAL(particleChanged(QString)), - this, SLOT(countChanged())); - reset(); -} - -void ParticleSystem::registerParticleAffector(ParticleAffector* a) -{ - m_affectors << QPointer(a); - //reset();//TODO: Slim down the huge batch of resets at the start -} - -void ParticleSystem::countChanged() -{ - reset();//Need to give Particles new Count -} - -void ParticleSystem::setRunning(bool arg) -{ - if (m_running != arg) { - m_running = arg; - emit runningChanged(arg); - reset(); - } -} - -void ParticleSystem::componentComplete() -{ - QSGItem::componentComplete(); - reset(); -} - -void ParticleSystem::initializeSystem() -{ - int oldCount = m_particle_count; - m_particle_count = 0;//TODO: Only when changed? - - //### Reset the data too? - for(int i=0; i::iterator iter = m_groupData.begin(); iter != m_groupData.end(); iter++) - delete (*iter); - m_groupData.clear(); - m_groupIds.clear(); - - GroupData* gd = new GroupData;//Default group - gd->size = 0; - gd->start = -1; - gd->nextIdx = 0; - m_groupData.insert(0,gd); - m_groupIds.insert("",0); - m_nextGroupId = 1; - - if(!m_emitters.count() || !m_particles.count()) - return; - - foreach(ParticleEmitter* e, m_emitters){ - if(!m_groupIds.contains(e->particle()) - || (!e->particle().isEmpty() && !m_groupIds[e->particle()])){//or it was accidentally inserted by a failed lookup earlier - GroupData* gd = new GroupData; - gd->size = 0; - gd->start = -1; - gd->nextIdx = 0; - int id = m_nextGroupId++; - m_groupIds.insert(e->particle(), id); - m_groupData.insert(id, gd); - } - m_groupData[m_groupIds[e->particle()]]->size += e->particleCount(); - } - - for(QHash::iterator iter = m_groupData.begin(); iter != m_groupData.end(); iter++){ - (*iter)->start = m_particle_count; - m_particle_count += (*iter)->size; - } - m_data.resize(m_particle_count); - for(int i=oldCount; i 16000) - qWarning() << "Particle system contains a vast number of particles (>16000). Expect poor performance"; - - foreach(ParticleType* particle, m_particles){ - int particleCount = 0; - if(particle->particles().isEmpty()){//Uses default particle - particleCount += m_groupData[0]->size; - m_groupData[0]->types << particle; - }else{ - foreach(const QString &group, particle->particles()){ - particleCount += m_groupData[m_groupIds[group]]->size; - m_groupData[m_groupIds[group]]->types << particle; - } - } - particle->setCount(particleCount); - particle->m_pleaseReset = true; - } - - m_timestamp.start(); - m_initialized = true; - emit systemInitialized(); - qDebug() << "System Initialized. Size:" << m_particle_count; -} - -void ParticleSystem::reset() -{ - //Clear guarded pointers which have been deleted - int cleared = 0; - cleared += m_emitters.removeAll(0); - cleared += m_particles.removeAll(0); - cleared += m_affectors.removeAll(0); - //qDebug() << "Reset" << m_emitters.count() << m_particles.count() << "Cleared" << cleared; - foreach(ParticleType* p, m_particles) - p->reset(); - foreach(ParticleEmitter* e, m_emitters) - e->reset(); - if(!m_running) - return; - initializeSystem(); - foreach(ParticleType* p, m_particles) - p->update(); - foreach(ParticleEmitter* e, m_emitters) - e->emitWindow(0);//Start, so that starttime factors appropriately -} - -ParticleData* ParticleSystem::newDatum(int groupId) -{ - Q_ASSERT(groupId < m_groupData.count());//XXX shouldn't really be an assert - Q_ASSERT(m_groupData[groupId]->size); - int nextIdx = m_groupData[groupId]->start + m_groupData[groupId]->nextIdx++; - if( m_groupData[groupId]->nextIdx >= m_groupData[groupId]->size) - m_groupData[groupId]->nextIdx = 0; - - Q_ASSERT(nextIdx < m_data.size()); - ParticleData* ret; - if(m_data[nextIdx]){//Recycle, it's faster. - ret = m_data[nextIdx]; - if(!m_overwrite && ret->stillAlive()){ - return 0;//Artificial longevity (or too fast emission) means this guy hasn't died. To maintain count, don't emit a new one - }//###Reset? - }else{ - ret = new ParticleData; - m_data[nextIdx] = ret; - } - - ret->system = this; - ret->systemIndex = nextIdx; - ret->particleIndex = nextIdx - m_groupData[groupId]->start; - ret->group = groupId; - return ret; -} - -void ParticleSystem::emitParticle(ParticleData* pd) -{// called from prepareNextFrame()->emitWindow - enforce? - //Account for relative emitter position - QPointF offset = this->mapFromItem(pd->e, QPointF(0, 0)); - if(!offset.isNull()){ - pd->pv.x += offset.x(); - pd->pv.y += offset.y(); - } - - foreach(ParticleAffector *a, m_affectors) - if(a && a->m_needsReset) - a->reset(pd->systemIndex); - foreach(ParticleType* p, m_groupData[pd->group]->types) - if(p) - p->load(pd); -} - - - -qint64 ParticleSystem::systemSync(ParticleType* p) -{ - if (!m_running) - return 0; - if (!m_initialized) - return 0;//error in initialization - - if(m_syncList.isEmpty() || m_syncList.contains(p)){//Need to advance the simulation - m_syncList.clear(); - - //### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time. - qreal dt = m_timeInt / 1000.; - m_timeInt = m_timestamp.elapsed() + m_startTime; - qreal time = m_timeInt / 1000.; - dt = time - dt; - m_needsReset.clear(); - foreach(ParticleEmitter* emitter, m_emitters) - if(emitter) - emitter->emitWindow(m_timeInt); - foreach(ParticleAffector* a, m_affectors) - if(a) - a->affectSystem(dt); - foreach(ParticleData* d, m_needsReset) - foreach(ParticleType* p, m_groupData[d->group]->types) - if(p && d) - p->reload(d); - } - m_syncList << p; - return m_timeInt; -} - -//sets the x accleration without affecting the instantaneous x velocity or position -void ParticleData::setInstantaneousAX(qreal ax) -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - qreal sx = (pv.sx + t*pv.ax) - t*ax; - qreal ex = pv.x + pv.sx * t + 0.5 * pv.ax * t * t; - qreal x = ex - t*sx - 0.5 * t*t*ax; - - pv.ax = ax; - pv.sx = sx; - pv.x = x; -} - -//sets the x velocity without affecting the instantaneous x postion -void ParticleData::setInstantaneousSX(qreal vx) -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - qreal sx = vx - t*pv.ax; - qreal ex = pv.x + pv.sx * t + 0.5 * pv.ax * t * t; - qreal x = ex - t*sx - 0.5 * t*t*pv.ax; - - pv.sx = sx; - pv.x = x; -} - -//sets the instantaneous x postion -void ParticleData::setInstantaneousX(qreal x) -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - pv.x = x - t*pv.sx - 0.5 * t*t*pv.ax; -} - -//sets the y accleration without affecting the instantaneous y velocity or position -void ParticleData::setInstantaneousAY(qreal ay) -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - qreal sy = (pv.sy + t*pv.ay) - t*ay; - qreal ey = pv.y + pv.sy * t + 0.5 * pv.ay * t * t; - qreal y = ey - t*sy - 0.5 * t*t*ay; - - pv.ay = ay; - pv.sy = sy; - pv.y = y; -} - -//sets the y velocity without affecting the instantaneous y position -void ParticleData::setInstantaneousSY(qreal vy) -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - //qDebug() << t << (system->m_timeInt/1000.0) << pv.x << pv.sx << pv.ax << pv.x + pv.sx * t + 0.5 * pv.ax * t * t; - qreal sy = vy - t*pv.ay; - qreal ey = pv.y + pv.sy * t + 0.5 * pv.ay * t * t; - qreal y = ey - t*sy - 0.5 * t*t*pv.ay; - - pv.sy = sy; - pv.y = y; -} - -//sets the instantaneous Y position -void ParticleData::setInstantaneousY(qreal y) -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - pv.y = y - t*pv.sy - 0.5 * t*t*pv.ay; -} - -qreal ParticleData::curX() const -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - return pv.x + pv.sx * t + 0.5 * pv.ax * t * t; -} - -qreal ParticleData::curSX() const -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - return pv.sx + t*pv.ax; -} - -qreal ParticleData::curY() const -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - return pv.y + pv.sy * t + 0.5 * pv.ay * t * t; -} - -qreal ParticleData::curSY() const -{ - qreal t = (system->m_timeInt / 1000.0) - pv.t; - return pv.sy + t*pv.ay; -} - -void ParticleData::debugDump() -{ - qDebug() << "Particle" << group - << "Pos: " << pv.x << "," << pv.y - << "Vel: " << pv.sx << "," << pv.sy - << "Acc: " << pv.ax << "," << pv.ay - << "Size: " << pv.size << "," << pv.endSize - << "Time: " << pv.t << "," < (system->m_timeInt/1000.0); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/particlesystem.h b/src/imports/particles/particlesystem.h deleted file mode 100644 index fbb0e7424f..0000000000 --- a/src/imports/particles/particlesystem.h +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLESYSTEM_H -#define PARTICLESYSTEM_H - -#include -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class ParticleAffector; -class ParticleEmitter; -class ParticleType; -class ParticleData; - - -struct GroupData{ - int size; - int start; - int nextIdx; - QList types; -}; - -class ParticleSystem : public QSGItem -{ - Q_OBJECT - Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) - Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) - Q_PROPERTY(bool overwrite READ overwrite WRITE setOverwrite NOTIFY overwriteChanged)//XXX: Should just be an implementation detail, but I can't decide which way - /* The problem is that it ought to be false (usually) for stasis effects like model particles, - but it ought to be true (usually) for burst effects where you want it to burst, and forget the old stuff - Ideally burst never overflows? But that leads to crappy behaviour from crappy users... - */ - -public: - explicit ParticleSystem(QSGItem *parent = 0); - -bool isRunning() const -{ - return m_running; -} - -int startTime() const -{ - return m_startTime; -} - -int count(){ return m_particle_count; } - -signals: - -void systemInitialized(); -void runningChanged(bool arg); - -void startTimeChanged(int arg); - - -void overwriteChanged(bool arg); - -public slots: -void reset(); -void setRunning(bool arg); - - -void setStartTime(int arg) -{ - m_startTime = arg; -} - -void setOverwrite(bool arg) -{ - if (m_overwrite != arg) { - m_overwrite = arg; -emit overwriteChanged(arg); -} -} - -void fastForward(int ms) -{ - m_startTime += ms; -} - -protected: - void componentComplete(); - -private slots: - void countChanged(); -public://but only really for related class usage. Perhaps we should all be friends? - void emitParticle(ParticleData* p); - ParticleData* newDatum(int groupId); - qint64 systemSync(ParticleType* p); - QElapsedTimer m_timestamp; - QVector m_data; - QSet m_needsReset; - QHash m_groupIds; - QHash m_groupData;//id, size, start - qint64 m_timeInt; - bool m_initialized; - - void registerParticleType(ParticleType* p); - void registerParticleEmitter(ParticleEmitter* e); - void registerParticleAffector(ParticleAffector* a); - bool overwrite() const - { - return m_overwrite; - } - - int m_particle_count; -private: - void initializeSystem(); - bool m_running; - QList > m_emitters; - QList > m_affectors; - QList > m_particles; - QList > m_syncList; - qint64 m_startTime; - int m_nextGroupId; - bool m_overwrite; -}; - -//TODO: Clean up all this into ParticleData - -struct ParticleVertex { - float x; - float y; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; - //TODO: Need opacity over life control. More variable size over life? -}; - -class ParticleData{ -public: - ParticleData(); - - ParticleVertex pv; - - //Convenience functions for working backwards, because parameters are from the start of particle life - //If setting multiple parameters at once, doing the conversion yourself will be faster. - - //sets the x accleration without affecting the instantaneous x velocity or position - void setInstantaneousAX(qreal ax); - //sets the x velocity without affecting the instantaneous x postion - void setInstantaneousSX(qreal vx); - //sets the instantaneous x postion - void setInstantaneousX(qreal x); - //sets the y accleration without affecting the instantaneous y velocity or position - void setInstantaneousAY(qreal ay); - //sets the y velocity without affecting the instantaneous y postion - void setInstantaneousSY(qreal vy); - //sets the instantaneous Y postion - void setInstantaneousY(qreal y); - - //TODO: Slight caching? - qreal curX() const; - qreal curSX() const; - qreal curY() const; - qreal curSY() const; - - int group; - ParticleEmitter* e; - ParticleSystem* system; - int particleIndex; - int systemIndex; - - void debugDump(); - bool stillAlive(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PARTICLESYSTEM_H - - diff --git a/src/imports/particles/pictureaffector.cpp b/src/imports/particles/pictureaffector.cpp deleted file mode 100644 index 636e26b830..0000000000 --- a/src/imports/particles/pictureaffector.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "pictureaffector.h" -#include "coloredparticle.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -PictureAffector::PictureAffector(QSGItem *parent) : - ParticleAffector(parent), m_pix(0) -{ - m_needsReset = true; -} - -void PictureAffector::reset(int systemIdx) -{ - ParticleAffector::reset(systemIdx); -} - -void PictureAffector::startLoadImage() -{ - if(m_pix) - m_pix->clear(); - else - m_pix = new QDeclarativePixmap(); - m_pix->load(qmlEngine(this), m_image, QDeclarativePixmap::Cache); - if(m_pix->isReady()) - loadImage(); - else - m_pix->connectFinished(this, SLOT(loadImage())); -} -void PictureAffector::loadImage() -{ - m_loadedImage = m_pix->pixmap().toImage(); - if(m_loadedImage.isNull()) - qWarning() << "PictureAffector could not load picture " << m_image; -} - -bool PictureAffector::affectParticle(ParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - if(!width() || !height()){ - qWarning() << "PictureAffector needs a size"; - return false; - } - - if(m_loadedImage.isNull()) - return false; - - if(m_loadedImage.size()!=QSize(width(), height())) - m_loadedImage = m_loadedImage.scaled(width(), height());//TODO: Aspect Ratio Control? - - bool affected = false; - QPoint pos = QPoint(d->curX() - m_offset.x(), d->curY() - m_offset.y()); - if(!QRect(0,0,width(),height()).contains(pos)){ - //XXX: Just a debugging helper, as I don't think it can get here. - qWarning() << "PictureAffector gives up."; - return false; - } - Color4ub c; - QRgb col = m_loadedImage.pixel(pos); - c.a = qAlpha(col); - c.b = qBlue(col); - c.g = qGreen(col); - c.r = qRed(col); - foreach(ParticleType *p, m_system->m_groupData[d->group]->types){ - if(qobject_cast(p)){ - ColoredParticle* cp = qobject_cast(p); - cp->reloadColor(c, d); - affected = true; - } - } - - return affected;//Doesn't affect particle data, but necessary for onceOff -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/pictureaffector.h b/src/imports/particles/pictureaffector.h deleted file mode 100644 index 4e0141d00a..0000000000 --- a/src/imports/particles/pictureaffector.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PICTUREAFFECTOR_H -#define PICTUREAFFECTOR_H -#include "particleaffector.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QDeclarativePixmap; -class PictureAffector : public ParticleAffector -{ - Q_OBJECT - //Usually want to use "particles" to target just colored stuff, and save performance - //Use onceOff (inherited) to determine if this is an emitter modification or a more constant enforcer - Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) - //TODO: Bool smooth, where it interpolates -public: - explicit PictureAffector(QSGItem *parent = 0); - - QUrl image() const - { - return m_image; - } - -protected: - virtual void reset(int systemIdx); - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void imageChanged(QUrl arg); - -public slots: - void setImage(QUrl arg) - { - if (m_image != arg) { - m_image = arg; - startLoadImage(); - emit imageChanged(arg); - } - } - -private slots: - void loadImage(); -private: - void startLoadImage(); - QUrl m_image; - QDeclarativePixmap* m_pix; - QImage m_loadedImage; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PICTUREAFFECTOR_H diff --git a/src/imports/particles/pluginmain.h b/src/imports/particles/pluginmain.h deleted file mode 100644 index cd8760d1a0..0000000000 --- a/src/imports/particles/pluginmain.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PLUGINMAIN_H -#define PLUGINMAIN_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class ParticlesPlugin : public QDeclarativeExtensionPlugin -{ - Q_OBJECT -public: - virtual void registerTypes(const char *uri); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PLUGINMAIN_H diff --git a/src/imports/particles/pointvector.cpp b/src/imports/particles/pointvector.cpp deleted file mode 100644 index e222965943..0000000000 --- a/src/imports/particles/pointvector.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "pointvector.h" - -QT_BEGIN_NAMESPACE - -PointVector::PointVector(QObject *parent) : - VaryingVector(parent) - , m_x(0) - , m_y(0) - , m_xVariation(0) - , m_yVariation(0) -{ -} - -const QPointF &PointVector::sample(const QPointF &) -{ - m_ret.setX(m_x - m_xVariation + rand() / float(RAND_MAX) * m_xVariation * 2); - m_ret.setY(m_y - m_yVariation + rand() / float(RAND_MAX) * m_yVariation * 2); - return m_ret; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/pointvector.h b/src/imports/particles/pointvector.h deleted file mode 100644 index 5ffa896680..0000000000 --- a/src/imports/particles/pointvector.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef POINTVECTOR_H -#define POINTVECTOR_H -#include "varyingvector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class PointVector : public VaryingVector -{ - Q_OBJECT - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) - Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged) - Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged) -public: - explicit PointVector(QObject *parent = 0); - virtual const QPointF &sample(const QPointF &from); - qreal x() const - { - return m_x; - } - - qreal y() const - { - return m_y; - } - - qreal xVariation() const - { - return m_xVariation; - } - - qreal yVariation() const - { - return m_yVariation; - } - -signals: - - void xChanged(qreal arg); - - void yChanged(qreal arg); - - void xVariationChanged(qreal arg); - - void yVariationChanged(qreal arg); - -public slots: - void setX(qreal arg) - { - if (m_x != arg) { - m_x = arg; - emit xChanged(arg); - } - } - - void setY(qreal arg) - { - if (m_y != arg) { - m_y = arg; - emit yChanged(arg); - } - } - - void setXVariation(qreal arg) - { - if (m_xVariation != arg) { - m_xVariation = arg; - emit xVariationChanged(arg); - } - } - - void setYVariation(qreal arg) - { - if (m_yVariation != arg) { - m_yVariation = arg; - emit yVariationChanged(arg); - } - } - -private: - - qreal m_x; - qreal m_y; - qreal m_xVariation; - qreal m_yVariation; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // POINTVECTOR_H diff --git a/src/imports/particles/resetaffector.cpp b/src/imports/particles/resetaffector.cpp deleted file mode 100644 index 0598298f27..0000000000 --- a/src/imports/particles/resetaffector.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "resetaffector.h" -#include -QT_BEGIN_NAMESPACE -ResetAffector::ResetAffector(QSGItem *parent) : - ParticleAffector(parent) -{ -} - -void ResetAffector::reset(int idx) -{ - ParticleAffector::reset(idx); - if(m_data[idx]) - delete m_data[idx]; - m_data.insert(idx, 0);//TODO: Either load with data now, or get data next tick whether active or not -} - -bool ResetAffector::affectParticle(ParticleData *d, qreal dt) -{ - TrajectoryData* trajectory; - if(m_data[d->systemIndex]){ - trajectory = m_data[d->systemIndex]; - //TODO: Faster to calculate once (not 4 times) - d->setInstantaneousSX(trajectory->sx); - d->setInstantaneousSY(trajectory->sy); - d->setInstantaneousAX(trajectory->ax); - d->setInstantaneousAY(trajectory->ay); - }else{ - trajectory = new TrajectoryData; - } - trajectory->sx = d->pv.sx; - trajectory->sy = d->pv.sy; - trajectory->ax = d->pv.ax; - trajectory->ay = d->pv.ay; - m_data.insert(d->systemIndex, trajectory);//overwrites - return true; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/resetaffector.h b/src/imports/particles/resetaffector.h deleted file mode 100644 index 6a4e2b7983..0000000000 --- a/src/imports/particles/resetaffector.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RESETAFFECTOR_H -#define RESETAFFECTOR_H -#include "particleaffector.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -struct TrajectoryData{ - qreal sx,sy,ax,ay; -}; - -class ResetAffector : public ParticleAffector -{ - Q_OBJECT -public: - explicit ResetAffector(QSGItem *parent = 0); - virtual void reset(int systemIdx); - -signals: - -public slots: -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -private: - QHash m_data; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // RESETAFFECTOR_H diff --git a/src/imports/particles/resources/ctfragment.shader b/src/imports/particles/resources/ctfragment.shader deleted file mode 100644 index a17f5841ca..0000000000 --- a/src/imports/particles/resources/ctfragment.shader +++ /dev/null @@ -1,11 +0,0 @@ -uniform sampler2D texture; -uniform sampler2D colortable; -uniform sampler2D opacitytable; - -varying highp vec2 fTex; -varying lowp vec4 fColor; -varying lowp float tt; - -void main() { - gl_FragColor = (texture2D(texture, fTex).w) * fColor * texture2D(colortable, vec2(tt, 0.5)) *( texture2D(opacitytable, vec2(tt, 0.5)).w); -} diff --git a/src/imports/particles/resources/ctvertex.shader b/src/imports/particles/resources/ctvertex.shader deleted file mode 100644 index b20676cc49..0000000000 --- a/src/imports/particles/resources/ctvertex.shader +++ /dev/null @@ -1,38 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration -attribute lowp vec4 vColor; - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform sampler2D sizetable; -uniform sampler2D opacitytable; - -varying highp vec2 fTex; -varying lowp vec4 fColor; -varying lowp float tt; - -void main() { - fTex = vTex; - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - highp float currentSize = mix(size, endSize, t * t) * texture2D(sizetable, vec2(t,0.5)).w; - - if (t < 0. || t > 1.) - currentSize = 0.; - - highp vec2 pos = vPos - - currentSize / 2. + currentSize * vTex // adjust size - + vVec.xy * t * vData.y // apply speed vector.. - + 0.5 * vVec.zw * pow(t * vData.y, 2.); - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - fColor = vColor; - tt = t; - -} diff --git a/src/imports/particles/resources/defaultFadeInOut.png b/src/imports/particles/resources/defaultFadeInOut.png deleted file mode 100644 index 89c04eaefe..0000000000 Binary files a/src/imports/particles/resources/defaultFadeInOut.png and /dev/null differ diff --git a/src/imports/particles/resources/deformablefragment.shader b/src/imports/particles/resources/deformablefragment.shader deleted file mode 100644 index 494053e319..0000000000 --- a/src/imports/particles/resources/deformablefragment.shader +++ /dev/null @@ -1,8 +0,0 @@ -uniform sampler2D texture; - -varying highp vec2 fTex; -varying lowp float fFade; - -void main() { - gl_FragColor = (texture2D(texture, fTex)) * fFade; -} diff --git a/src/imports/particles/resources/deformablevertex.shader b/src/imports/particles/resources/deformablevertex.shader deleted file mode 100644 index 01570950b1..0000000000 --- a/src/imports/particles/resources/deformablevertex.shader +++ /dev/null @@ -1,57 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration -attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector -attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform lowp float opacity; - -varying highp vec2 fTex; -varying lowp float fFade; - -void main() { - fTex = vTex; - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - highp float currentSize = mix(size, endSize, t * t); - - highp vec2 pos; - if (t < 0. || t > 1.){ - currentSize = 0.; - pos = vPos; - }else{ - highp float rotation = vRotation.x + vRotation.y * t * vData.y; - if(vRotation.z == 1.0){ - highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy; - rotation += atan(curVel.y, curVel.x); - } - highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); - highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); - highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); - highp vec2 xRotatedDeform; - xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; - xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; - highp vec2 yRotatedDeform; - yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; - yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; - pos = vPos - + xRotatedDeform - + yRotatedDeform - //- vec2(1,1) * currentSize * 0.5 // 'center' - + vVec.xy * t * vData.y // apply speed - + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration - } - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - highp float fadeIn = min(t * 10., 1.); - highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); - - fFade = fadeIn * fadeOut * opacity; -} diff --git a/src/imports/particles/resources/identitytable.png b/src/imports/particles/resources/identitytable.png deleted file mode 100644 index 2cada1bfad..0000000000 Binary files a/src/imports/particles/resources/identitytable.png and /dev/null differ diff --git a/src/imports/particles/resources/simplefragment.shader b/src/imports/particles/resources/simplefragment.shader deleted file mode 100644 index 494053e319..0000000000 --- a/src/imports/particles/resources/simplefragment.shader +++ /dev/null @@ -1,8 +0,0 @@ -uniform sampler2D texture; - -varying highp vec2 fTex; -varying lowp float fFade; - -void main() { - gl_FragColor = (texture2D(texture, fTex)) * fFade; -} diff --git a/src/imports/particles/resources/simplevertex.shader b/src/imports/particles/resources/simplevertex.shader deleted file mode 100644 index f185ef0700..0000000000 --- a/src/imports/particles/resources/simplevertex.shader +++ /dev/null @@ -1,36 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform lowp float opacity; - -varying highp vec2 fTex; -varying lowp float fFade; - -void main() { - fTex = vTex; - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - highp float currentSize = mix(size, endSize, t * t); - - if (t < 0. || t > 1.) - currentSize = 0.; - - highp vec2 pos = vPos - - currentSize / 2. + currentSize * vTex // adjust size - + vVec.xy * t * vData.y // apply speed vector.. - + 0.5 * vVec.zw * pow(t * vData.y, 2.); - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - highp float fadeIn = min(t * 10., 1.); - highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); - - fFade = fadeIn * fadeOut * opacity; -} diff --git a/src/imports/particles/resources/spritefragment.shader b/src/imports/particles/resources/spritefragment.shader deleted file mode 100644 index 4d89d69c6a..0000000000 --- a/src/imports/particles/resources/spritefragment.shader +++ /dev/null @@ -1,10 +0,0 @@ -uniform sampler2D texture; - -varying highp vec2 fTexA; -varying highp vec2 fTexB; -varying lowp float progress; -varying lowp vec4 fColor; - -void main() { - gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress) * fColor.w; -} diff --git a/src/imports/particles/resources/spriteimagefragment.shader b/src/imports/particles/resources/spriteimagefragment.shader deleted file mode 100644 index ecd62cf390..0000000000 --- a/src/imports/particles/resources/spriteimagefragment.shader +++ /dev/null @@ -1,9 +0,0 @@ -uniform sampler2D texture; - -varying highp vec2 fTexA; -varying highp vec2 fTexB; -varying lowp float progress; - -void main() { - gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress); -} diff --git a/src/imports/particles/resources/spriteimagevertex.shader b/src/imports/particles/resources/spriteimagevertex.shader deleted file mode 100644 index 27de2ada6a..0000000000 --- a/src/imports/particles/resources/spriteimagevertex.shader +++ /dev/null @@ -1,52 +0,0 @@ -attribute highp vec2 vTex; -attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim) - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform lowp float opacity; -uniform highp float framecount; //maximum of all anims -uniform highp float animcount; -uniform highp float width; -uniform highp float height; - -varying highp vec2 fTexA; -varying highp vec2 fTexB; -varying lowp float progress; - - -void main() { - //Calculate frame location in texture - highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z); - progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y; - - frameIndex = floor(frameIndex); - highp vec2 frameTex; - if(vTex.x == 0.) - frameTex.x = (frameIndex/framecount); - else - frameTex.x = 1. * ((frameIndex + 1.)/framecount); - - if(vTex.y == 0.) - frameTex.y = (vAnimData.x/animcount); - else - frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); - - fTexA = frameTex; - //Next frame is also passed, for interpolation - if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop - frameIndex = mod(frameIndex+1., vAnimData.z); - - if(vTex.x == 0.) - frameTex.x = (frameIndex/framecount); - else - frameTex.x = 1. * ((frameIndex + 1.)/framecount); - - if(vTex.y == 0.) - frameTex.y = (vAnimData.x/animcount); - else - frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); - fTexB = frameTex; - - - gl_Position = matrix * vec4(width * vTex.x, height * vTex.y, 0, 1); -} diff --git a/src/imports/particles/resources/spritevertex.shader b/src/imports/particles/resources/spritevertex.shader deleted file mode 100644 index 78b8e36b3b..0000000000 --- a/src/imports/particles/resources/spritevertex.shader +++ /dev/null @@ -1,77 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration -attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim) - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform lowp float opacity; -uniform highp float framecount; //maximum of all anims -uniform highp float animcount; - -varying highp vec2 fTexA; -varying highp vec2 fTexB; -varying lowp float progress; -varying lowp vec4 fColor; - -void main() { - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - //Calculate frame location in texture - highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z); - progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y; - - frameIndex = floor(frameIndex); - highp vec2 frameTex = vTex; - if(vTex.x == 0.) - frameTex.x = (frameIndex/framecount); - else - frameTex.x = 1. * ((frameIndex + 1.)/framecount); - - if(vTex.y == 0.) - frameTex.y = (vAnimData.x/animcount); - else - frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); - - fTexA = frameTex; - //Next frame is also passed, for interpolation - //### Should the next anim be precalculated to allow for interpolation there? - if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop - frameIndex = mod(frameIndex+1., vAnimData.z); - - if(vTex.x == 0.) - frameTex.x = (frameIndex/framecount); - else - frameTex.x = 1. * ((frameIndex + 1.)/framecount); - - if(vTex.y == 0.) - frameTex.y = (vAnimData.x/animcount); - else - frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); - fTexB = frameTex; - - //Applying Size here seems to screw with RockingAffector? - highp float currentSize = mix(size, endSize, t * t); - - if (t < 0. || t > 1.) - currentSize = 0.; - - //If affector is mananging pos, they don't set speed? - highp vec2 pos = vPos - - currentSize / 2. + currentSize * vTex // adjust size - + vVec.xy * t * vData.y // apply speed vector.. - + 0.5 * vVec.zw * pow(t * vData.y, 2.); - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - // calculate opacity - highp float fadeIn = min(t * 10., 1.); - highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); - - lowp vec4 white = vec4(1.); - fColor = white * fadeIn * fadeOut * opacity; -} diff --git a/src/imports/particles/resources/superfragment.shader b/src/imports/particles/resources/superfragment.shader deleted file mode 100644 index a17f5841ca..0000000000 --- a/src/imports/particles/resources/superfragment.shader +++ /dev/null @@ -1,11 +0,0 @@ -uniform sampler2D texture; -uniform sampler2D colortable; -uniform sampler2D opacitytable; - -varying highp vec2 fTex; -varying lowp vec4 fColor; -varying lowp float tt; - -void main() { - gl_FragColor = (texture2D(texture, fTex).w) * fColor * texture2D(colortable, vec2(tt, 0.5)) *( texture2D(opacitytable, vec2(tt, 0.5)).w); -} diff --git a/src/imports/particles/resources/supervertex.shader b/src/imports/particles/resources/supervertex.shader deleted file mode 100644 index 432a23ce05..0000000000 --- a/src/imports/particles/resources/supervertex.shader +++ /dev/null @@ -1,57 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration -attribute lowp vec4 vColor; -attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector -attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform sampler2D sizetable; -uniform sampler2D opacitytable; - -varying highp vec2 fTex; -varying lowp vec4 fColor; -varying lowp float tt; - -void main() { - fTex = vTex; - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - highp float currentSize = mix(size, endSize, t * t) * texture2D(sizetable, vec2(t,0.5)).w; - - if (t < 0. || t > 1.) - currentSize = 0.; - - highp vec2 pos; - highp float rotation = vRotation.x + vRotation.y * t * vData.y; - if(vRotation.z == 1.0){ - highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy; - rotation += atan(curVel.y, curVel.x); - } - highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); - highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); - highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); - highp vec2 xRotatedDeform; - xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; - xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; - highp vec2 yRotatedDeform; - yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; - yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; - pos = vPos - + xRotatedDeform - + yRotatedDeform - //- vec2(1,1) * currentSize * 0.5 // 'center' - + vVec.xy * t * vData.y // apply speed - + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - fColor = vColor; - tt = t; - -} diff --git a/src/imports/particles/resources/trailsfragment.shader b/src/imports/particles/resources/trailsfragment.shader deleted file mode 100644 index d3db87fa30..0000000000 --- a/src/imports/particles/resources/trailsfragment.shader +++ /dev/null @@ -1,8 +0,0 @@ -uniform sampler2D texture; - -varying highp vec2 fTex; -varying lowp vec4 fColor; - -void main() { - gl_FragColor = (texture2D(texture, fTex).w) * fColor; -} diff --git a/src/imports/particles/resources/trailsvertex.shader b/src/imports/particles/resources/trailsvertex.shader deleted file mode 100644 index 7bc1d66b71..0000000000 --- a/src/imports/particles/resources/trailsvertex.shader +++ /dev/null @@ -1,37 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration -attribute lowp vec4 vColor; - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform lowp float opacity; - -varying highp vec2 fTex; -varying lowp vec4 fColor; - -void main() { - fTex = vTex; - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - highp float currentSize = mix(size, endSize, t * t); - - if (t < 0. || t > 1.) - currentSize = 0.; - - highp vec2 pos = vPos - - currentSize / 2. + currentSize * vTex // adjust size - + vVec.xy * t * vData.y // apply speed vector.. - + 0.5 * vVec.zw * pow(t * vData.y, 2.); - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - highp float fadeIn = min(t * 10., 1.); - highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); - - fColor = vColor * fadeIn * fadeOut * opacity; -} diff --git a/src/imports/particles/resources/ultrafragment.shader b/src/imports/particles/resources/ultrafragment.shader deleted file mode 100644 index 0627d0f1e8..0000000000 --- a/src/imports/particles/resources/ultrafragment.shader +++ /dev/null @@ -1,16 +0,0 @@ -uniform sampler2D texture; -uniform sampler2D colortable; -uniform sampler2D opacitytable; - -varying highp vec2 fTexA; -varying highp vec2 fTexB; -varying lowp float progress; -varying lowp vec4 fColor; -varying lowp float tt; - -void main() { - gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress) - * fColor - * texture2D(colortable, vec2(tt, 0.5)) - *( texture2D(opacitytable, vec2(tt, 0.5)).w); -} diff --git a/src/imports/particles/resources/ultravertex.shader b/src/imports/particles/resources/ultravertex.shader deleted file mode 100644 index 65a1a3077a..0000000000 --- a/src/imports/particles/resources/ultravertex.shader +++ /dev/null @@ -1,94 +0,0 @@ -attribute highp vec2 vPos; -attribute highp vec2 vTex; -attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize -attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration -attribute lowp vec4 vColor; -attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector -attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate -attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim) - -uniform highp mat4 matrix; -uniform highp float timestamp; -uniform highp float framecount; //maximum of all anims -uniform highp float animcount; -uniform sampler2D sizetable; - -varying lowp float tt; -varying highp vec2 fTexA; -varying highp vec2 fTexB; -varying lowp float progress; -varying lowp vec4 fColor; - - -void main() { - highp float size = vData.z; - highp float endSize = vData.w; - - highp float t = (timestamp - vData.x) / vData.y; - - //Calculate frame location in texture - highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z); - progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y; - - frameIndex = floor(frameIndex); - highp vec2 frameTex = vTex; - if(vTex.x == 0.) - frameTex.x = (frameIndex/framecount); - else - frameTex.x = 1. * ((frameIndex + 1.)/framecount); - - if(vTex.y == 0.) - frameTex.y = (vAnimData.x/animcount); - else - frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); - - fTexA = frameTex; - //Next frame is also passed, for interpolation - //### Should the next anim be precalculated to allow for interpolation there? - if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop - frameIndex = mod(frameIndex+1., vAnimData.z); - - if(vTex.x == 0.) - frameTex.x = (frameIndex/framecount); - else - frameTex.x = 1. * ((frameIndex + 1.)/framecount); - - if(vTex.y == 0.) - frameTex.y = (vAnimData.x/animcount); - else - frameTex.y = 1. * ((vAnimData.x + 1.)/animcount); - fTexB = frameTex; - - highp float currentSize = mix(size, endSize, t * t) * texture2D(sizetable, vec2(t,0.5)).w; - - if (t < 0. || t > 1.) - currentSize = 0.; - - highp vec2 pos; - highp float rotation = vRotation.x + vRotation.y * t * vData.y; - if(vRotation.z == 1.0){ - highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy; - rotation += atan(curVel.y, curVel.x); - } - highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); - highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); - highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); - highp vec2 xRotatedDeform; - xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; - xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; - highp vec2 yRotatedDeform; - yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; - yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; - pos = vPos - + xRotatedDeform - + yRotatedDeform - //- vec2(1,1) * currentSize * 0.5 // 'center' - + vVec.xy * t * vData.y // apply speed - + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration - - gl_Position = matrix * vec4(pos.x, pos.y, 0, 1); - - fColor = vColor; - tt = t; - -} diff --git a/src/imports/particles/speedlimitaffector.cpp b/src/imports/particles/speedlimitaffector.cpp deleted file mode 100644 index c226404b01..0000000000 --- a/src/imports/particles/speedlimitaffector.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "speedlimitaffector.h" -#include -#include - -QT_BEGIN_NAMESPACE - -SpeedLimitAffector::SpeedLimitAffector(QSGItem *parent) : - ParticleAffector(parent), m_speedLimit(-1) -{ -} - -bool SpeedLimitAffector::affectParticle(ParticleData *d, qreal dt){ - Q_UNUSED(dt); - if(m_speedLimit <= 0) - return false; - - qreal x = d->curSX(); - qreal y = d->curSY(); - qreal s = sqrt(x*x + y*y); - if(s <= m_speedLimit) - return false; - - - if(s >= m_speedLimit*1.01){ - qreal theta = atan2(y,x); - d->setInstantaneousSX(m_speedLimit * cos(theta)); - d->setInstantaneousSY(m_speedLimit * sin(theta)); - } - - d->setInstantaneousAY(0); - d->setInstantaneousAX(0); - - return true; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/speedlimitaffector.h b/src/imports/particles/speedlimitaffector.h deleted file mode 100644 index b3858a2a9d..0000000000 --- a/src/imports/particles/speedlimitaffector.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPEEDLIMITAFFECTOR_H -#define SPEEDLIMITAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class SpeedLimitAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal speedLimit READ speedLimit WRITE setSpeedLimit NOTIFY speedLimitChanged) - - -public: - explicit SpeedLimitAffector(QSGItem *parent = 0); - - qreal speedLimit() const - { - return m_speedLimit; - } - -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void speedLimitChanged(qreal arg); - -public slots: -void setSpeedLimit(qreal arg) -{ - if (m_speedLimit != arg) { - m_speedLimit = arg; - emit speedLimitChanged(arg); - } -} - -private: -qreal m_speedLimit; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SPEEDLIMITAFFECTOR_H diff --git a/src/imports/particles/spriteengine.cpp b/src/imports/particles/spriteengine.cpp deleted file mode 100644 index 7676d9ed46..0000000000 --- a/src/imports/particles/spriteengine.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spriteengine.h" -#include "spritestate.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -SpriteEngine::SpriteEngine(QObject *parent) : - QObject(parent), m_timeOffset(0) -{ - //Default size 1 - setCount(1); - m_advanceTime.start(); -} - -SpriteEngine::SpriteEngine(QList states, QObject *parent) : - QObject(parent), m_states(states), m_timeOffset(0) -{ - //Default size 1 - setCount(1); - m_advanceTime.start(); -} - -SpriteEngine::~SpriteEngine() -{ -} - -int SpriteEngine::maxFrames() -{ - return m_maxFrames; -} - -/* States too large to fit in one row are split into multiple rows - This is more efficient for the implementation, but should remain an implementation detail (invisible from QML) - Therefore the below functions abstract sprite from the viewpoint of classes that pass the details onto shaders - But States maintain their listed index for internal structures -TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost -*/ -int SpriteEngine::spriteState(int sprite) -{ - int state = m_sprites[sprite]; - if(!m_states[state]->m_generatedCount) - return state; - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; - int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; - return state + extra; -} - -int SpriteEngine::spriteStart(int sprite) -{ - int state = m_sprites[sprite]; - if(!m_states[state]->m_generatedCount) - return m_startTimes[sprite]; - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; - int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; - return state + extra*rowDuration; -} - -int SpriteEngine::spriteFrames(int sprite) -{ - int state = m_sprites[sprite]; - if(!m_states[state]->m_generatedCount) - return m_states[state]->frames(); - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; - int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; - if(extra == m_states[state]->m_generatedCount - 1)//last state - return m_states[state]->frames() % m_states[state]->m_framesPerRow; - else - return m_states[state]->m_framesPerRow; -} - -int SpriteEngine::spriteDuration(int sprite) -{ - int state = m_sprites[sprite]; - if(!m_states[state]->m_generatedCount) - return m_states[state]->duration(); - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; - int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; - if(extra == m_states[state]->m_generatedCount - 1)//last state - return (m_states[state]->duration() * m_states[state]->frames()) % rowDuration; - else - return rowDuration; -} - -int SpriteEngine::spriteCount()//TODO: Actually image state count, need to rename these things to make sense together -{ - return m_imageStateCount; -} - -void SpriteEngine::setGoal(int state, int sprite, bool jump) -{ - if(sprite >= m_sprites.count() || state >= m_states.count()) - return; - if(!jump){ - m_goals[sprite] = state; - return; - } - - if(m_sprites[sprite] == state) - return;//Already there - m_sprites[sprite] = state; - m_goals[sprite] = -1; - restartSprite(sprite); - return; -} - -QImage SpriteEngine::assembledImage() -{ - int frameHeight = 0; - int frameWidth = 0; - m_maxFrames = 0; - m_imageStateCount = 0; - - int maxSize; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); - - foreach(SpriteState* state, m_states){ - if(state->frames() > m_maxFrames) - m_maxFrames = state->frames(); - - QImage img(state->source().toLocalFile()); - if (img.isNull()) { - qWarning() << "SpriteEngine: loading image failed..." << state->source().toLocalFile(); - return QImage(); - } - - //Check that the frame sizes are the same within one engine - int imgWidth = state->frameWidth(); - if(!imgWidth) - imgWidth = img.width() / state->frames(); - if(frameWidth){ - if(imgWidth != frameWidth){ - qWarning() << "SpriteEngine: Irregular frame width..." << state->source().toLocalFile(); - return QImage(); - } - }else{ - frameWidth = imgWidth; - } - - int imgHeight = state->frameHeight(); - if(!imgHeight) - imgHeight = img.height(); - if(frameHeight){ - if(imgHeight!=frameHeight){ - qWarning() << "SpriteEngine: Irregular frame height..." << state->source().toLocalFile(); - return QImage(); - } - }else{ - frameHeight = imgHeight; - } - - if(state->frames() * frameWidth > maxSize){ - struct helper{ - static int divRoundUp(int a, int b){return (a+b-1)/b;} - }; - int rowsNeeded = helper::divRoundUp(state->frames(), helper::divRoundUp(maxSize, frameWidth)); - if(rowsNeeded * frameHeight > maxSize){ - qWarning() << "SpriteEngine: Animation too large to fit in one texture..." << state->source().toLocalFile(); - qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; - } - state->m_generatedCount = rowsNeeded; - m_imageStateCount += rowsNeeded; - }else{ - m_imageStateCount++; - } - } - - //maxFrames is max number in a line of the texture - if(m_maxFrames * frameWidth > maxSize) - m_maxFrames = maxSize/frameWidth; - QImage image(frameWidth * m_maxFrames, frameHeight * m_imageStateCount, QImage::Format_ARGB32); - image.fill(0); - QPainter p(&image); - int y = 0; - foreach(SpriteState* state, m_states){ - QImage img(state->source().toLocalFile()); - if(img.height() == frameHeight && img.width() < maxSize){//Simple case - p.drawImage(0,y,img); - y += frameHeight; - }else{ - state->m_framesPerRow = image.width()/frameWidth; - int x = 0; - int curX = 0; - int curY = 0; - int framesLeft = state->frames(); - while(framesLeft > 0){ - if(image.width() - x + curX <= img.width()){//finish a row in image (dest) - int copied = image.width() - x; - Q_ASSERT(!(copied % frameWidth));//XXX: Just checking - framesLeft -= copied/frameWidth; - p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight)); - y += frameHeight; - curX += copied; - x = 0; - if(curX == img.width()){ - curX = 0; - curY += frameHeight; - } - }else{//finish a row in img (src) - int copied = img.width() - curX; - Q_ASSERT(!(copied % frameWidth));//XXX: Just checking - framesLeft -= copied/frameWidth; - p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight)); - curY += frameHeight; - x += copied; - curX = 0; - } - } - if(x) - y += frameHeight; - } - } - - if(image.height() > maxSize){ - qWarning() << "SpriteEngine: Too many animations to fit in one texture..."; - qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; - return QImage(); - } - return image; -} - -void SpriteEngine::setCount(int c) -{ - m_sprites.resize(c); - m_goals.resize(c); - m_startTimes.resize(c); -} - -void SpriteEngine::startSprite(int index) -{ - if(index >= m_sprites.count()) - return; - m_sprites[index] = 0; - m_goals[index] = -1; - restartSprite(index); -} - -void SpriteEngine::restartSprite(int index) -{ - m_startTimes[index] = m_timeOffset + m_advanceTime.elapsed(); - int time = m_states[m_sprites[index]]->duration() * m_states[m_sprites[index]]->frames() + m_startTimes[index]; - for(int i=0; i= m_stateUpdates.first().first){ - foreach(int idx, m_stateUpdates.first().second){ - if(idx >= m_sprites.count()) - continue;//TODO: Proper fix(because this does happen and I'm just ignoring it) - int stateIdx = m_sprites[idx]; - int nextIdx = -1; - int goalPath = goalSeek(stateIdx, idx); - if(goalPath == -1){//Random - qreal r =(qreal) qrand() / (qreal) RAND_MAX; - qreal total = 0.0; - for(QVariantMap::const_iterator iter=m_states[stateIdx]->m_to.constBegin(); - iter!=m_states[stateIdx]->m_to.constEnd(); iter++) - total += (*iter).toReal(); - r*=total; - for(QVariantMap::const_iterator iter= m_states[stateIdx]->m_to.constBegin(); - iter!=m_states[stateIdx]->m_to.constEnd(); iter++){ - if(r < (*iter).toReal()){ - bool superBreak = false; - for(int i=0; iname() == iter.key()){ - nextIdx = i; - superBreak = true; - break; - } - } - if(superBreak) - break; - } - r -= (*iter).toReal(); - } - }else{//Random out of shortest paths to goal - nextIdx = goalPath; - } - if(nextIdx == -1)//No to states means stay here - nextIdx = stateIdx; - - m_sprites[idx] = nextIdx; - m_startTimes[idx] = time; - //TODO: emit something? Remember to emit this when a psuedostate changes too - addToUpdateList((m_states[nextIdx]->duration() * m_states[nextIdx]->frames()) + time, idx); - } - m_stateUpdates.pop_front(); - } - - m_timeOffset = time; - m_advanceTime.start(); - if(m_stateUpdates.isEmpty()) - return -1; - return m_stateUpdates.first().first; -} - -int SpriteEngine::goalSeek(int curIdx, int spriteIdx, int dist) -{ - QString goalName; - if(m_goals[spriteIdx] != -1) - goalName = m_states[m_goals[spriteIdx]]->name(); - else - goalName = m_globalGoal; - if(goalName.isEmpty()) - return -1; - //TODO: caching instead of excessively redoing iterative deepening (which was chosen arbitarily anyways) - // Paraphrased - implement in an *efficient* manner - for(int i=0; iname() == goalName) - return curIdx; - if(dist < 0) - dist = m_states.count(); - SpriteState* curState = m_states[curIdx]; - for(QVariantMap::const_iterator iter = curState->m_to.constBegin(); - iter!=curState->m_to.constEnd(); iter++){ - if(iter.key() == goalName) - for(int i=0; iname() == goalName) - return i; - } - QSet options; - for(int i=1; im_to.constBegin(); - iter!=curState->m_to.constEnd(); iter++){ - int option = -1; - for(int j=0; jname() == iter.key()) - if(goalSeek(j, spriteIdx, i) != -1) - option = j; - if(option != -1) - options << option; - } - if(!options.isEmpty()){ - if(options.count()==1) - return *(options.begin()); - int option = -1; - qreal r =(qreal) qrand() / (qreal) RAND_MAX; - qreal total; - for(QSet::const_iterator iter=options.constBegin(); - iter!=options.constEnd(); iter++) - total += curState->m_to.value(m_states[(*iter)]->name()).toReal(); - r *= total; - for(QVariantMap::const_iterator iter = curState->m_to.constBegin(); - iter!=curState->m_to.constEnd(); iter++){ - bool superContinue = true; - for(int j=0; jname() == iter.key()) - if(options.contains(j)) - superContinue = false; - if(superContinue) - continue; - if(r < (*iter).toReal()){ - bool superBreak = false; - for(int j=0; jname() == iter.key()){ - option = j; - superBreak = true; - break; - } - } - if(superBreak) - break; - } - r-=(*iter).toReal(); - } - return option; - } - } - return -1; -} - -void SpriteEngine::addToUpdateList(uint t, int idx) -{ - for(int i=0; i t){ - QList tmpList; - tmpList << idx; - m_stateUpdates.insert(i, qMakePair(t, tmpList)); - return; - } - } - QList tmpList; - tmpList << idx; - m_stateUpdates << qMakePair(t, tmpList); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/spriteengine.h b/src/imports/particles/spriteengine.h deleted file mode 100644 index 0180245685..0000000000 --- a/src/imports/particles/spriteengine.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPRITEENGINE_H -#define SPRITEENGINE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class SpriteState; - -class SpriteEngine : public QObject -{ - Q_OBJECT - //TODO: Optimize single sprite case - Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) - Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged) -public: - explicit SpriteEngine(QObject *parent = 0); - SpriteEngine(QList sprites, QObject *parent=0); - ~SpriteEngine(); - - QDeclarativeListProperty sprites() - { - return QDeclarativeListProperty(this, m_states); - } - QString globalGoal() const - { - return m_globalGoal; - } - - int count() const {return m_sprites.count();} - void setCount(int c); - - int spriteState(int sprite=0);// {return m_sprites[sprite];} - int spriteStart(int sprite=0);// {return m_startTimes[sprite];} - int spriteFrames(int sprite=0); - int spriteDuration(int sprite=0); - int spriteCount();//Like state count, but for the image states - int maxFrames(); - - void setGoal(int state, int sprite=0, bool jump=false); - QImage assembledImage(); - - void startSprite(int index=0); - -private://Nothing outside should use this? - friend class SpriteGoalAffector;//XXX: Fix interface - int stateCount() {return m_states.count();} - int stateIndex(SpriteState* s){return m_states.indexOf(s);}//TODO: Does this need to be hidden? - SpriteState* state(int idx){return m_states[idx];}//Used by spritegoal affector -signals: - - void globalGoalChanged(QString arg); - -public slots: - void setGlobalGoal(QString arg) - { - if (m_globalGoal != arg) { - m_globalGoal = arg; - emit globalGoalChanged(arg); - } - } - - uint updateSprites(uint time); - -private: - void restartSprite(int sprite); - void addToUpdateList(uint t, int idx); - int goalSeek(int curState, int spriteIdx, int dist=-1); - QList m_states; - QVector m_sprites;//int is the index in m_states of the current state - QVector m_goals; - QVector m_startTimes; - QList > > m_stateUpdates;//### This could be done faster - - QTime m_advanceTime; - uint m_timeOffset; - QString m_globalGoal; - int m_maxFrames; - int m_imageStateCount; -}; - -//Common use is to have your own list property which is transparently an engine -inline void spriteAppend(QDeclarativeListProperty *p, SpriteState* s) -{ - reinterpret_cast *>(p->data)->append(s); - p->object->metaObject()->invokeMethod(p->object, "createEngine"); -} - -inline SpriteState* spriteAt(QDeclarativeListProperty *p, int idx) -{ - return reinterpret_cast *>(p->data)->at(idx); -} - -inline void spriteClear(QDeclarativeListProperty *p) -{ - reinterpret_cast *>(p->data)->clear(); - p->object->metaObject()->invokeMethod(p->object, "createEngine"); -} - -inline int spriteCount(QDeclarativeListProperty *p) -{ - return reinterpret_cast *>(p->data)->count(); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SPRITEENGINE_H diff --git a/src/imports/particles/spritegoalaffector.cpp b/src/imports/particles/spritegoalaffector.cpp deleted file mode 100644 index 2bd56c4a07..0000000000 --- a/src/imports/particles/spritegoalaffector.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spritegoalaffector.h" -#include "spriteparticle.h" -#include "spriteengine.h" -#include "spritestate.h" -#include - -QT_BEGIN_NAMESPACE - -SpriteGoalAffector::SpriteGoalAffector(QSGItem *parent) : - ParticleAffector(parent), m_goalIdx(-1), m_jump(false) -{ -} - -void SpriteGoalAffector::updateStateIndex(SpriteEngine* e) -{ - m_lastEngine = e; - for(int i=0; istateCount(); i++){ - if(e->state(i)->name() == m_goalState){ - m_goalIdx = i; - return; - } - } - m_goalIdx = -1;//Can't find it -} - -void SpriteGoalAffector::setGoalState(QString arg) -{ - if (m_goalState != arg) { - m_goalState = arg; - emit goalStateChanged(arg); - if(m_goalState.isEmpty()) - m_goalIdx = -1; - else - m_goalIdx = -2; - } -} - -bool SpriteGoalAffector::affectParticle(ParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - //TODO: Affect all engines - SpriteEngine *engine = 0; - foreach(ParticleType *p, m_system->m_groupData[d->group]->types) - if(qobject_cast(p)) - engine = qobject_cast(p)->spriteEngine(); - if(!engine) - return false; - - if(m_goalIdx == -2 || engine != m_lastEngine) - updateStateIndex(engine); - if(engine->spriteState(d->particleIndex) != m_goalIdx){ - engine->setGoal(m_goalIdx, d->particleIndex, m_jump); - emit affected(QPointF(d->curX(), d->curY()));//###Expensive if unconnected? Move to Affector? - return true; //Doesn't affect particle data, but necessary for onceOff - } - return false; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/spritegoalaffector.h b/src/imports/particles/spritegoalaffector.h deleted file mode 100644 index 3a51562be2..0000000000 --- a/src/imports/particles/spritegoalaffector.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPRITEGOALAFFECTOR_H -#define SPRITEGOALAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class SpriteEngine; - -class SpriteGoalAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) - Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) -public: - explicit SpriteGoalAffector(QSGItem *parent = 0); - - QString goalState() const - { - return m_goalState; - } - - bool jump() const - { - return m_jump; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void goalStateChanged(QString arg); - - void jumpChanged(bool arg); - - void affected(const QPointF &pos); -public slots: - -void setGoalState(QString arg); - -void setJump(bool arg) -{ - if (m_jump != arg) { - m_jump = arg; - emit jumpChanged(arg); - } -} - -private: - void updateStateIndex(SpriteEngine* e); - QString m_goalState; - int m_goalIdx; - SpriteEngine* m_lastEngine; - bool m_jump; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SPRITEGOALAFFECTOR_H diff --git a/src/imports/particles/spriteimage.cpp b/src/imports/particles/spriteimage.cpp deleted file mode 100644 index ea08ae4ea0..0000000000 --- a/src/imports/particles/spriteimage.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spriteimage.h" -#include "spritestate.h" -#include "spriteengine.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class SpriteMaterial : public QSGMaterial -{ -public: - SpriteMaterial(); - virtual ~SpriteMaterial(); - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const - { - return this - static_cast(other); - } - - QSGTexture *texture; - - qreal timestamp; - qreal timelength; - int framecount; - int animcount; - int width; - int height; -}; - -SpriteMaterial::SpriteMaterial() - : timestamp(0) - , timelength(1) - , framecount(1) - , animcount(1) - , width(0) - , height(0) -{ - setFlag(Blending, true); -} - -SpriteMaterial::~SpriteMaterial() -{ - delete texture; -} - -class SpriteMaterialData : public QSGMaterialShader -{ -public: - SpriteMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/spriteimagevertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/spriteimagefragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - SpriteMaterial *m = static_cast(newEffect); - m->texture->bind(); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - program()->setUniformValue(m_framecount_id, (float) m->framecount); - program()->setUniformValue(m_animcount_id, (float) m->animcount); - program()->setUniformValue(m_width_id, (float) m->width); - program()->setUniformValue(m_height_id, (float) m->height); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_framecount_id = program()->uniformLocation("framecount"); - m_animcount_id = program()->uniformLocation("animcount"); - m_width_id = program()->uniformLocation("width"); - m_height_id = program()->uniformLocation("height"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vTex", - "vAnimData", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - int m_framecount_id; - int m_animcount_id; - int m_width_id; - int m_height_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float SpriteMaterialData::chunkOfBytes[1024]; - -QSGMaterialShader *SpriteMaterial::createShader() const -{ - return new SpriteMaterialData; -} - -struct SpriteVertex { - float tx; - float ty; - float animIdx; - float frameDuration; - float frameCount; - float animT; -}; - -struct SpriteVertices { - SpriteVertex v1; - SpriteVertex v2; - SpriteVertex v3; - SpriteVertex v4; -}; - -SpriteImage::SpriteImage(QSGItem *parent) : - QSGItem(parent) - , m_node(0) - , m_material(0) - , m_spriteEngine(0) - , m_pleaseReset(false) - , m_running(true) -{ - setFlag(ItemHasContents); - connect(this, SIGNAL(runningChanged(bool)), - this, SLOT(update())); -} - -QDeclarativeListProperty SpriteImage::sprites() -{ - return QDeclarativeListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); -} - -void SpriteImage::createEngine() -{ - //TODO: delay until component complete - if(m_spriteEngine) - delete m_spriteEngine; - if(m_sprites.count()) - m_spriteEngine = new SpriteEngine(m_sprites, this); - else - m_spriteEngine = 0; - reset(); -} - -static QSGGeometry::Attribute SpriteImage_Attributes[] = { - { 0, 2, GL_FLOAT }, // tex - { 1, 4, GL_FLOAT } // animData -}; - -static QSGGeometry::AttributeSet SpriteImage_AttributeSet = -{ - 2, // Attribute Count - (4 + 2) * sizeof(float), - SpriteImage_Attributes -}; - -QSGGeometryNode* SpriteImage::buildNode() -{ - if (!m_spriteEngine) { - qWarning() << "SpriteImage: No sprite engine..."; - return 0; - } - - if (m_material) { - delete m_material; - m_material = 0; - } - - m_material = new SpriteMaterial(); - - QImage image = m_spriteEngine->assembledImage(); - if(image.isNull()) - return 0; - m_material->texture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - m_material->framecount = m_spriteEngine->maxFrames(); - - int vCount = 4; - int iCount = 6; - QSGGeometry *g = new QSGGeometry(SpriteImage_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - SpriteVertices *p = (SpriteVertices *) g->vertexData(); - m_spriteEngine->startSprite(0); - p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = 0; - p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = 0; - p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames(); - p->v1.frameDuration = p->v2.frameDuration = p->v3.frameDuration = p->v4.frameDuration = m_spriteEngine->spriteDuration(); - - p->v1.tx = 0; - p->v1.ty = 0; - - p->v2.tx = 1.0; - p->v2.ty = 0; - - p->v3.tx = 0; - p->v3.ty = 1.0; - - p->v4.tx = 1.0; - p->v4.ty = 1.0; - - quint16 *indices = g->indexDataAsUShort(); - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 1; - indices[4] = 3; - indices[5] = 2; - - - m_timestamp.start(); - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - return m_node; -} - -void SpriteImage::reset() -{ - m_pleaseReset = true; -} - -QSGNode *SpriteImage::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if(m_pleaseReset){ - delete m_node; - delete m_material; - - m_node = 0; - m_material = 0; - m_pleaseReset = false; - } - - prepareNextFrame(); - - if(m_running){ - update(); - if (m_node) - m_node->markDirty(QSGNode::DirtyMaterial); - } - - return m_node; -} - -void SpriteImage::prepareNextFrame() -{ - if (m_node == 0) - m_node = buildNode(); - if (m_node == 0) //error creating node - return; - - uint timeInt = m_timestamp.elapsed(); - qreal time = timeInt / 1000.; - m_material->timestamp = time; - m_material->animcount = m_spriteEngine->spriteCount(); - m_material->height = height(); - m_material->width = width(); - - //Advance State - SpriteVertices *p = (SpriteVertices *) m_node->geometry()->vertexData(); - m_spriteEngine->updateSprites(timeInt); - int curIdx = m_spriteEngine->spriteState(); - if(curIdx != p->v1.animIdx){ - p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = curIdx; - p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = m_spriteEngine->spriteStart()/1000.0; - p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames(); - p->v1.frameDuration = p->v2.frameDuration = p->v3.frameDuration = p->v4.frameDuration = m_spriteEngine->spriteDuration(); - } -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/spriteimage.h b/src/imports/particles/spriteimage.h deleted file mode 100644 index cd73c97333..0000000000 --- a/src/imports/particles/spriteimage.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPRITEIMAGE_H -#define SPRITEIMAGE_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGContext; -class SpriteState; -class SpriteEngine; -class QSGGeometryNode; -class SpriteMaterial; -class SpriteImage : public QSGItem -{ - Q_OBJECT - Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged) - //###try to share similar spriteEngines for less overhead? - Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) - Q_CLASSINFO("DefaultProperty", "sprites") - -public: - explicit SpriteImage(QSGItem *parent = 0); - - QDeclarativeListProperty sprites(); - - bool running() const - { - return m_running; - } - -signals: - - - void runningChanged(bool arg); - -public slots: - -void setRunning(bool arg) -{ - if (m_running != arg) { - m_running = arg; - emit runningChanged(arg); - } -} - -private slots: - void createEngine(); -protected: - void reset(); - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); -private: - void prepareNextFrame(); - QSGGeometryNode* buildNode(); - QSGGeometryNode *m_node; - SpriteMaterial *m_material; - QList m_sprites; - SpriteEngine* m_spriteEngine; - QTime m_timestamp; - int m_maxFrames; - bool m_pleaseReset; - bool m_running; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SPRITEIMAGE_H diff --git a/src/imports/particles/spriteparticle.cpp b/src/imports/particles/spriteparticle.cpp deleted file mode 100644 index 6039d2819b..0000000000 --- a/src/imports/particles/spriteparticle.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spriteparticle.h" -#include "spritestate.h" -#include "spriteengine.h" -#include "particleemitter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class SpriteParticlesMaterial : public QSGMaterial -{ -public: - SpriteParticlesMaterial(); - virtual ~SpriteParticlesMaterial(); - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const - { - return this - static_cast(other); - } - - QSGTexture *texture; - - qreal timestamp; - int framecount; - int animcount; -}; - -SpriteParticlesMaterial::SpriteParticlesMaterial() - : timestamp(0) - , framecount(1) - , animcount(1) -{ - setFlag(Blending, true); -} - -SpriteParticlesMaterial::~SpriteParticlesMaterial() -{ - delete texture; -} - -class SpriteParticlesMaterialData : public QSGMaterialShader -{ -public: - SpriteParticlesMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/spritevertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/spritefragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - SpriteParticlesMaterial *m = static_cast(newEffect); - m->texture->bind(); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - program()->setUniformValue(m_framecount_id, (float) m->framecount); - program()->setUniformValue(m_animcount_id, (float) m->animcount); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_framecount_id = program()->uniformLocation("framecount"); - m_animcount_id = program()->uniformLocation("animcount"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vPos", - "vTex", - "vData", - "vVec", - "vAnimData", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - int m_framecount_id; - int m_animcount_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float SpriteParticlesMaterialData::chunkOfBytes[1024]; - -QSGMaterialShader *SpriteParticlesMaterial::createShader() const -{ - return new SpriteParticlesMaterialData; -} - -struct SpriteParticleVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; - float animIdx; - float frameDuration; - float frameCount; - float animT; -}; - -struct SpriteParticleVertices { - SpriteParticleVertex v1; - SpriteParticleVertex v2; - SpriteParticleVertex v3; - SpriteParticleVertex v4; -}; - -SpriteParticle::SpriteParticle(QSGItem *parent) : - ParticleType(parent) - , m_node(0) - , m_material(0) - , m_spriteEngine(0) -{ - setFlag(ItemHasContents); - } -QDeclarativeListProperty SpriteParticle::sprites() -{ - return QDeclarativeListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); -} - -void SpriteParticle::createEngine() -{ - if(m_spriteEngine) - delete m_spriteEngine; - if(m_sprites.count()) - m_spriteEngine = new SpriteEngine(m_sprites, this); - else - m_spriteEngine = 0; - reset();//###this is probably out of updatePaintNode and shouldn't be -} - -void SpriteParticle::setCount(int c) -{ - ParticleType::setCount(c); - m_pleaseReset = true; -} - -static QSGGeometry::Attribute SpriteParticle_Attributes[] = { - { 0, 2, GL_FLOAT }, // Position - { 1, 2, GL_FLOAT }, // TexCoord - { 2, 4, GL_FLOAT }, // Data - { 3, 4, GL_FLOAT }, // Vectors - { 4, 4, GL_FLOAT } // Colors -}; - -static QSGGeometry::AttributeSet SpriteParticle_AttributeSet = -{ - 5, // Attribute Count - (2 + 2 + 4 + 4 + 4) * sizeof(float), - SpriteParticle_Attributes -}; - - - -QSGGeometryNode* SpriteParticle::buildParticleNode() -{ - if (m_count * 4 > 0xffff) { - qWarning() << "SpriteParticle: too many particles..."; - return 0; - } - - if (m_count * 4 == 0) { - qWarning() << "SpriteParticle: No particles..."; - return 0; - } - - if (!m_spriteEngine) { - qWarning() << "SpriteParticle: No sprite engine..."; - return 0; - } - - if (m_material) { - delete m_material; - m_material = 0; - } - - m_material = new SpriteParticlesMaterial(); - - QImage image = m_spriteEngine->assembledImage(); - if(image.isNull()) - return 0; - m_material->texture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - m_material->framecount = m_spriteEngine->maxFrames(); - m_spriteEngine->setCount(m_count); - - int vCount = m_count * 4; - int iCount = m_count * 6; - QSGGeometry *g = new QSGGeometry(SpriteParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - SpriteParticleVertex *vertices = (SpriteParticleVertex *) g->vertexData(); - for (int p=0; pindexDataAsUShort(); - for (int i=0; isetGeometry(g); - m_node->setMaterial(m_material); - m_last_particle = 0; - return m_node; -} - -void SpriteParticle::vertexCopy(SpriteParticleVertex &b,const ParticleVertex& a) -{ - b.x = a.x + m_systemOffset.x(); - b.y = a.y + m_systemOffset.y(); - b.t = a.t; - b.lifeSpan = a.lifeSpan; - b.size = a.size; - b.endSize = a.endSize; - b.sx = a.sx; - b.sy = a.sy; - b.ax = a.ax; - b.ay = a.ay; -} - -void SpriteParticle::load(ParticleData *d) -{ - if (m_node == 0) //error creating node - return; - - SpriteParticleVertices *particles = (SpriteParticleVertices *) m_node->geometry()->vertexData(); - int pos = particleTypeIndex(d); - SpriteParticleVertices &p = particles[pos]; - - // Initial Sprite State - m_spriteEngine->startSprite(pos); - p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = p.v1.t; - p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = 0; - p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(pos); - p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(pos); - - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); - -} - -void SpriteParticle::reload(ParticleData *d) -{ - if (m_node == 0) //error creating node - return; - - SpriteParticleVertices *particles = (SpriteParticleVertices *) m_node->geometry()->vertexData(); - int pos = particleTypeIndex(d); - SpriteParticleVertices &p = particles[pos]; - - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); -} - - -QSGNode *SpriteParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if(m_pleaseReset){ - if(m_node) - delete m_node; - if(m_material) - delete m_material; - - m_node = 0; - m_material = 0; - m_pleaseReset = false; - } - if(m_system&& m_system->isRunning()) - prepareNextFrame(); - if (m_node){ - update(); - m_node->markDirty(QSGNode::DirtyMaterial); - } - - return m_node; -} - -void SpriteParticle::prepareNextFrame() -{ - if (m_node == 0){ //TODO: Staggered loading (as emitted) (is it just moving this check to load()?) - m_node = buildParticleNode(); - if(m_node == 0) - return; - } - qint64 timeStamp = m_system->systemSync(this); - - - qreal time = timeStamp / 1000.; - m_material->timestamp = time; - m_material->animcount = m_spriteEngine->spriteCount(); - - //Advance State - SpriteParticleVertices *particles = (SpriteParticleVertices *) m_node->geometry()->vertexData(); - m_spriteEngine->updateSprites(timeStamp); - for(int i=0; ispriteState(i); - if(curIdx != p.v1.animIdx){ - p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx; - p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(i)/1000.0; - p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(i); - p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(i); - } - } -} - -void SpriteParticle::reset() -{ - ParticleType::reset(); - m_pleaseReset = true; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/spriteparticle.h b/src/imports/particles/spriteparticle.h deleted file mode 100644 index f28d198600..0000000000 --- a/src/imports/particles/spriteparticle.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPRITEPARTICLE_H -#define SPRITEPARTICLE_H -#include "particle.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class SpriteState; -class SpriteEngine; -class QSGGeometryNode; -class SpriteParticlesMaterial; -class SpriteParticleVertex; - -class SpriteParticle : public ParticleType -{ - Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) - Q_CLASSINFO("DefaultProperty", "sprites") -public: - explicit SpriteParticle(QSGItem *parent = 0); - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - - QDeclarativeListProperty sprites(); - SpriteEngine* spriteEngine() {return m_spriteEngine;} -signals: - -public slots: -protected: - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void reset(); - void prepareNextFrame(); - QSGGeometryNode* buildParticleNode(); -private slots: - void createEngine(); -private: - QSGGeometryNode *m_node; - SpriteParticlesMaterial *m_material; - - int m_particle_duration; - int m_last_particle; - - QList m_sprites; - SpriteEngine* m_spriteEngine; - - void vertexCopy(SpriteParticleVertex &b,const ParticleVertex& a); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SPRITEPARTICLE_H diff --git a/src/imports/particles/spriteparticles.qrc b/src/imports/particles/spriteparticles.qrc deleted file mode 100644 index 0232c3c9f9..0000000000 --- a/src/imports/particles/spriteparticles.qrc +++ /dev/null @@ -1,22 +0,0 @@ - - - resources/spritefragment.shader - resources/spritevertex.shader - resources/ctfragment.shader - resources/ctvertex.shader - resources/trailsfragment.shader - resources/trailsvertex.shader - resources/spriteimagefragment.shader - resources/spriteimagevertex.shader - resources/identitytable.png - resources/defaultFadeInOut.png - resources/deformablefragment.shader - resources/deformablevertex.shader - resources/ultravertex.shader - resources/ultrafragment.shader - resources/supervertex.shader - resources/superfragment.shader - resources/simplevertex.shader - resources/simplefragment.shader - - diff --git a/src/imports/particles/spritestate.cpp b/src/imports/particles/spritestate.cpp deleted file mode 100644 index 72535c0e73..0000000000 --- a/src/imports/particles/spritestate.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spritestate.h" - -QT_BEGIN_NAMESPACE - -SpriteState::SpriteState(QObject *parent) : - QObject(parent) - , m_generatedCount(0) - , m_framesPerRow(0) - , m_frames(1) - , m_frameHeight(0) - , m_frameWidth(0) - , m_duration(1000) -{ -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/spritestate.h b/src/imports/particles/spritestate.h deleted file mode 100644 index 5157a8bb31..0000000000 --- a/src/imports/particles/spritestate.h +++ /dev/null @@ -1,231 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPRITESTATE_H -#define SPRITESTATE_H - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class SpriteState : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged) - //If frame height or width is not specified, it is assumed to be a single long row of frames. - //Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used. - Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged) - Q_PROPERTY(int frameWidth READ frameWidth WRITE setFrameWidth NOTIFY frameWidthChanged) - Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) - Q_PROPERTY(int durationVariance READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged) - Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged) - Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged) - -public: - explicit SpriteState(QObject *parent = 0); - - QUrl source() const - { - return m_source; - } - - int frames() const - { - return m_frames; - } - - int frameHeight() const - { - return m_frameHeight; - } - - int frameWidth() const - { - return m_frameWidth; - } - - int duration() const - { - return m_duration; - } - - QString name() const - { - return m_name; - } - - QVariantMap to() const - { - return m_to; - } - - qreal speedModifer() const - { - return m_speedModifier; - } - - int durationVariance() const - { - return m_durationVariance; - } - -signals: - - void sourceChanged(QUrl arg); - - void framesChanged(int arg); - - void frameHeightChanged(int arg); - - void frameWidthChanged(int arg); - - void durationChanged(int arg); - - void nameChanged(QString arg); - - void toChanged(QVariantMap arg); - - void speedModifierChanged(qreal arg); - - void durationVarianceChanged(int arg); - -public slots: - - void setSource(QUrl arg) - { - if (m_source != arg) { - m_source = arg; - emit sourceChanged(arg); - } - } - - void setFrames(int arg) - { - if (m_frames != arg) { - m_frames = arg; - emit framesChanged(arg); - } - } - - void setFrameHeight(int arg) - { - if (m_frameHeight != arg) { - m_frameHeight = arg; - emit frameHeightChanged(arg); - } - } - - void setFrameWidth(int arg) - { - if (m_frameWidth != arg) { - m_frameWidth = arg; - emit frameWidthChanged(arg); - } - } - - void setDuration(int arg) - { - if (m_duration != arg) { - m_duration = arg; - emit durationChanged(arg); - } - } - - void setName(QString arg) - { - if (m_name != arg) { - m_name = arg; - emit nameChanged(arg); - } - } - - void setTo(QVariantMap arg) - { - if (m_to != arg) { - m_to = arg; - emit toChanged(arg); - } - } - - void setSpeedModifier(qreal arg) - { - if (m_speedModifier != arg) { - m_speedModifier = arg; - emit speedModifierChanged(arg); - } - } - - void setDurationVariance(int arg) - { - if (m_durationVariance != arg) { - m_durationVariance = arg; - emit durationVarianceChanged(arg); - } - } - -private: - friend class SpriteParticle; - friend class SpriteEngine; - int m_generatedCount; - int m_framesPerRow; - QUrl m_source; - int m_frames; - int m_frameHeight; - int m_frameWidth; - int m_duration; - QString m_name; - QVariantMap m_to; - qreal m_speedModifier; - int m_durationVariance; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // SPRITESTATE_H diff --git a/src/imports/particles/superparticle.cpp b/src/imports/particles/superparticle.cpp deleted file mode 100644 index 811b6a4ba8..0000000000 --- a/src/imports/particles/superparticle.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "superparticle.h" -#include "particleemitter.h" -#include -#include - -QT_BEGIN_NAMESPACE - -const float CONV = 0.017453292519943295; -class SuperMaterial : public QSGMaterial -{ -public: - SuperMaterial() - : timestamp(0) - { - setFlag(Blending, true); - } - - ~SuperMaterial() - { - delete texture; - delete colortable; - delete sizetable; - delete opacitytable; - } - - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const - { - return this - static_cast(other); - } - - QSGTexture *texture; - QSGTexture *colortable; - QSGTexture *sizetable; - QSGTexture *opacitytable; - - qreal timestamp; -}; - - -class SuperMaterialData : public QSGMaterialShader -{ -public: - SuperMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/supervertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/superfragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - SuperMaterial *m = static_cast(newEffect); - state.context()->functions()->glActiveTexture(GL_TEXTURE0); - m->texture->bind(); - - state.context()->functions()->glActiveTexture(GL_TEXTURE1); - m->colortable->bind(); - program()->setUniformValue(m_colortable_id, 1); - - state.context()->functions()->glActiveTexture(GL_TEXTURE2); - m->sizetable->bind(); - program()->setUniformValue(m_sizetable_id, 2); - - state.context()->functions()->glActiveTexture(GL_TEXTURE3); - m->opacitytable->bind(); - program()->setUniformValue(m_opacitytable_id, 3); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_colortable_id = program()->uniformLocation("colortable"); - m_sizetable_id = program()->uniformLocation("sizetable"); - m_opacitytable_id = program()->uniformLocation("opacitytable"); - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vPos", - "vTex", - "vData", - "vVec", - "vColor", - "vDeformVec", - "vRotation", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - int m_colortable_id; - int m_sizetable_id; - int m_opacitytable_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float SuperMaterialData::chunkOfBytes[1024]; - - -QSGMaterialShader *SuperMaterial::createShader() const -{ - return new SuperMaterialData; -} - -SuperParticle::SuperParticle(QSGItem* parent) - : ParticleType(parent) - , m_do_reset(false) - , m_color(Qt::white) - , m_color_variation(0.5) - , m_node(0) - , m_material(0) - , m_alphaVariation(0.0) - , m_alpha(1.0) - , m_redVariation(0.0) - , m_greenVariation(0.0) - , m_blueVariation(0.0) -{ - setFlag(ItemHasContents); -} - -void SuperParticle::setImage(const QUrl &image) -{ - if (image == m_image_name) - return; - m_image_name = image; - emit imageChanged(); - reset(); -} - - -void SuperParticle::setColortable(const QUrl &table) -{ - if (table == m_colortable_name) - return; - m_colortable_name = table; - emit colortableChanged(); - reset(); -} - -void SuperParticle::setSizetable(const QUrl &table) -{ - if (table == m_sizetable_name) - return; - m_sizetable_name = table; - emit sizetableChanged(); - reset(); -} - -void SuperParticle::setOpacitytable(const QUrl &table) -{ - if (table == m_opacitytable_name) - return; - m_opacitytable_name = table; - emit opacitytableChanged(); - reset(); -} - -void SuperParticle::setColor(const QColor &color) -{ - if (color == m_color) - return; - m_color = color; - emit colorChanged(); - //m_system->pleaseReset();//XXX -} - -void SuperParticle::setColorVariation(qreal var) -{ - if (var == m_color_variation) - return; - m_color_variation = var; - emit colorVariationChanged(); - //m_system->pleaseReset();//XXX -} - -void SuperParticle::setCount(int c) -{ - ParticleType::setCount(c); - m_pleaseReset = true; -} - -void SuperParticle::reset() -{ - ParticleType::reset(); - m_pleaseReset = true; -} - -static QSGGeometry::Attribute SuperParticle_Attributes[] = { - { 0, 2, GL_FLOAT }, // Position - { 1, 2, GL_FLOAT }, // TexCoord - { 2, 4, GL_FLOAT }, // Data - { 3, 4, GL_FLOAT }, // Vectors - { 4, 4, GL_UNSIGNED_BYTE }, // Colors - { 5, 4, GL_FLOAT }, // DeformationVectors - { 6, 3, GL_FLOAT } // Rotation -}; - -static QSGGeometry::AttributeSet SuperParticle_AttributeSet = -{ - 7, // Attribute Count - (2 + 2 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar), - SuperParticle_Attributes -}; - -QSGGeometryNode* SuperParticle::buildParticleNode() -{ - if (m_count * 4 > 0xffff) { - printf("SuperParticle: Too many particles... \n"); - return 0; - } - - if(m_count <= 0) { - printf("SuperParticle: Too few particles... \n"); - return 0; - } - - QImage image(m_image_name.toLocalFile()); - if (image.isNull()) { - printf("SuperParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile())); - return 0; - } - - int vCount = m_count * 4; - int iCount = m_count * 6; - - QSGGeometry *g = new QSGGeometry(SuperParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - SuperVertex *vertices = (SuperVertex *) g->vertexData(); - for (int p=0; pindexDataAsUShort(); - for (int i=0; icolortable = sceneGraphEngine()->createTextureFromImage(colortable); - m_material->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable); - m_material->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable); - - m_material->texture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - - m_last_particle = 0; - - return m_node; -} - -QSGNode *SuperParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if(m_pleaseReset){ - if(m_node) - delete m_node; - if(m_material) - delete m_material; - - m_node = 0; - m_material = 0; - m_pleaseReset = false; - } - - if(m_system && m_system->isRunning()) - prepareNextFrame(); - if (m_node){ - update(); - m_node->markDirty(QSGNode::DirtyMaterial); - } - - return m_node; -} - -void SuperParticle::prepareNextFrame() -{ - if (m_node == 0){ //TODO: Staggered loading (as emitted) - m_node = buildParticleNode(); - if(m_node == 0) - return; - } - qint64 timeStamp = m_system->systemSync(this); - - qreal time = timeStamp / 1000.; - m_material->timestamp = time; -} - -void SuperParticle::reloadColor(const Color4ub &c, ParticleData* d) -{ - SuperVertices *particles = (SuperVertices *) m_node->geometry()->vertexData(); - int pos = particleTypeIndex(d); - SuperVertices &p = particles[pos]; - p.v1.color = p.v2.color = p.v3.color = p.v4.color = c; -} - -void SuperParticle::vertexCopy(SuperVertex &b,const ParticleVertex& a) -{ - b.x = a.x - m_systemOffset.x(); - b.y = a.y - m_systemOffset.y(); - b.t = a.t; - b.lifeSpan = a.lifeSpan; - b.size = a.size; - b.endSize = a.endSize; - b.sx = a.sx; - b.sy = a.sy; - b.ax = a.ax; - b.ay = a.ay; -} - -void SuperParticle::reload(ParticleData *d) -{ - if (m_node == 0) - return; - - SuperVertices *particles = (SuperVertices *) m_node->geometry()->vertexData(); - - int pos = particleTypeIndex(d); - - SuperVertices &p = particles[pos]; - - //Perhaps we could be more efficient? - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); -} - -void SuperParticle::load(ParticleData *d) -{ - if (m_node == 0) - return; - - //Color initialization - // Particle color - Color4ub color; - qreal redVariation = m_color_variation + m_redVariation; - qreal greenVariation = m_color_variation + m_greenVariation; - qreal blueVariation = m_color_variation + m_blueVariation; - color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; - color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; - color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; - color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; - SuperVertices *particles = (SuperVertices *) m_node->geometry()->vertexData(); - SuperVertices &p = particles[particleTypeIndex(d)]; - p.v1.color = p.v2.color = p.v3.color = p.v4.color = color; - if(m_xVector){ - const QPointF &ret = m_xVector->sample(QPointF(d->pv.x, d->pv.y)); - p.v1.xx = p.v2.xx = p.v3.xx = p.v4.xx = ret.x(); - p.v1.xy = p.v2.xy = p.v3.xy = p.v4.xy = ret.y(); - } - if(m_yVector){ - const QPointF &ret = m_yVector->sample(QPointF(d->pv.x, d->pv.y)); - p.v1.yx = p.v2.yx = p.v3.yx = p.v4.yx = ret.x(); - p.v1.yy = p.v2.yy = p.v3.yy = p.v4.yy = ret.y(); - } - p.v1.rotation = p.v2.rotation = p.v3.rotation = p.v4.rotation = - (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; - p.v1.rotationSpeed = p.v2.rotationSpeed = p.v3.rotationSpeed = p.v4.rotationSpeed = - (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; - p.v1.autoRotate = p.v2.autoRotate = p.v3.autoRotate = p.v4.autoRotate = m_autoRotation?1.0:0.0; - - vertexCopy(p.v1, d->pv); - vertexCopy(p.v2, d->pv); - vertexCopy(p.v3, d->pv); - vertexCopy(p.v4, d->pv); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/superparticle.h b/src/imports/particles/superparticle.h deleted file mode 100644 index ac2f9860ef..0000000000 --- a/src/imports/particles/superparticle.h +++ /dev/null @@ -1,389 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SUPERPARTICLE_H -#define SUPERPARTICLE_H -#include "particle.h" -#include "varyingvector.h" - -#include "coloredparticle.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class SuperMaterial; -class QSGGeometryNode; - -/*struct Color4ub {//in coloredparticle - uchar r; - uchar g; - uchar b; - uchar a; -};*/ - -struct SuperVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; - Color4ub color; - float xx; - float xy; - float yx; - float yy; - float rotation; - float rotationSpeed; - float autoRotate;//Assume that GPUs prefer floats to bools -}; - -struct SuperVertices { - SuperVertex v1; - SuperVertex v2; - SuperVertex v3; - SuperVertex v4; -}; - -class SuperParticle : public ParticleType -{ - Q_OBJECT - Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) - Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) - Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) - Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) - - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - //Stacks (added) with individual colorVariations - Q_PROPERTY(qreal colorVariation READ colorVariation WRITE setColorVariation NOTIFY colorVariationChanged) - Q_PROPERTY(qreal redVariation READ redVariation WRITE setRedVariation NOTIFY redVariationChanged) - Q_PROPERTY(qreal greenVariation READ greenVariation WRITE setGreenVariation NOTIFY greenVariationChanged) - Q_PROPERTY(qreal blueVariation READ blueVariation WRITE setBlueVariation NOTIFY blueVariationChanged) - //Stacks (multiplies) with the Alpha in the color, mostly here so you can use svg color names (which have full alpha) - Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged) - Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged) - - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) - Q_PROPERTY(qreal rotationVariation READ rotationVariation WRITE setRotationVariation NOTIFY rotationVariationChanged) - Q_PROPERTY(qreal rotationSpeed READ rotationSpeed WRITE setRotationSpeed NOTIFY rotationSpeedChanged) - Q_PROPERTY(qreal rotationSpeedVariation READ rotationSpeedVariation WRITE setRotationSpeedVariation NOTIFY rotationSpeedVariationChanged) - //If true, then will face the direction of motion. Stacks with rotation, e.g. setting rotation - //to 180 will lead to facing away from the direction of motion - Q_PROPERTY(bool autoRotation READ autoRotation WRITE autoRotation NOTIFY autoRotationChanged) - - //###Call i/j? Makes more sense to those with vector calculus experience, and I could even add the cirumflex in QML? - //xVector is the vector from the top-left point to the top-right point, and is multiplied by current size - Q_PROPERTY(VaryingVector* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged) - //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram. - Q_PROPERTY(VaryingVector* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged) -public: - explicit SuperParticle(QSGItem *parent = 0); - virtual ~SuperParticle(){} - - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - - QUrl image() const { return m_image_name; } - void setImage(const QUrl &image); - - QUrl colortable() const { return m_colortable_name; } - void setColortable(const QUrl &table); - - QUrl sizetable() const { return m_sizetable_name; } - void setSizetable (const QUrl &table); - - QUrl opacitytable() const { return m_opacitytable_name; } - void setOpacitytable(const QUrl &table); - - QColor color() const { return m_color; } - void setColor(const QColor &color); - - qreal colorVariation() const { return m_color_variation; } - void setColorVariation(qreal var); - - qreal renderOpacity() const { return m_render_opacity; } - - qreal alphaVariation() const - { - return m_alphaVariation; - } - - qreal alpha() const - { - return m_alpha; - } - - qreal redVariation() const - { - return m_redVariation; - } - - qreal greenVariation() const - { - return m_greenVariation; - } - - qreal blueVariation() const - { - return m_blueVariation; - } - - qreal rotation() const - { - return m_rotation; - } - - qreal rotationVariation() const - { - return m_rotationVariation; - } - - qreal rotationSpeed() const - { - return m_rotationSpeed; - } - - qreal rotationSpeedVariation() const - { - return m_rotationSpeedVariation; - } - - bool autoRotation() const - { - return m_autoRotation; - } - - VaryingVector* xVector() const - { - return m_xVector; - } - - VaryingVector* yVector() const - { - return m_yVector; - } - -signals: - - void imageChanged(); - void colortableChanged(); - void sizetableChanged(); - void opacitytableChanged(); - - void colorChanged(); - void colorVariationChanged(); - - void particleDurationChanged(); - void alphaVariationChanged(qreal arg); - - void alphaChanged(qreal arg); - - void redVariationChanged(qreal arg); - - void greenVariationChanged(qreal arg); - - void blueVariationChanged(qreal arg); - - void rotationChanged(qreal arg); - - void rotationVariationChanged(qreal arg); - - void rotationSpeedChanged(qreal arg); - - void rotationSpeedVariationChanged(qreal arg); - - void autoRotationChanged(bool arg); - - void xVectorChanged(VaryingVector* arg); - - void yVectorChanged(VaryingVector* arg); - -public slots: - void setAlphaVariation(qreal arg) - { - if (m_alphaVariation != arg) { - m_alphaVariation = arg; - emit alphaVariationChanged(arg); - } - } - - void setAlpha(qreal arg) - { - if (m_alpha != arg) { - m_alpha = arg; - emit alphaChanged(arg); - } - } - - void setRedVariation(qreal arg) - { - if (m_redVariation != arg) { - m_redVariation = arg; - emit redVariationChanged(arg); - } - } - - void setGreenVariation(qreal arg) - { - if (m_greenVariation != arg) { - m_greenVariation = arg; - emit greenVariationChanged(arg); - } - } - - void setBlueVariation(qreal arg) - { - if (m_blueVariation != arg) { - m_blueVariation = arg; - emit blueVariationChanged(arg); - } - } - - void reloadColor(const Color4ub &c, ParticleData* d); - void setRotation(qreal arg) - { - if (m_rotation != arg) { - m_rotation = arg; - emit rotationChanged(arg); - } - } - - void setRotationVariation(qreal arg) - { - if (m_rotationVariation != arg) { - m_rotationVariation = arg; - emit rotationVariationChanged(arg); - } - } - - void setRotationSpeed(qreal arg) - { - if (m_rotationSpeed != arg) { - m_rotationSpeed = arg; - emit rotationSpeedChanged(arg); - } - } - - void setRotationSpeedVariation(qreal arg) - { - if (m_rotationSpeedVariation != arg) { - m_rotationSpeedVariation = arg; - emit rotationSpeedVariationChanged(arg); - } - } - - void autoRotation(bool arg) - { - if (m_autoRotation != arg) { - m_autoRotation = arg; - emit autoRotationChanged(arg); - } - } - - void setXVector(VaryingVector* arg) - { - if (m_xVector != arg) { - m_xVector = arg; - emit xVectorChanged(arg); - } - } - - void setYVector(VaryingVector* arg) - { - if (m_yVector != arg) { - m_yVector = arg; - emit yVectorChanged(arg); - } - } - -protected: - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void reset(); - void prepareNextFrame(); - QSGGeometryNode* buildParticleNode(); -private: - void vertexCopy(SuperVertex &b,const ParticleVertex& a); - bool m_do_reset; - - QUrl m_image_name; - QUrl m_colortable_name; - QUrl m_sizetable_name; - QUrl m_opacitytable_name; - - - QColor m_color; - qreal m_color_variation; - qreal m_particleDuration; - - QSGGeometryNode *m_node; - SuperMaterial *m_material; - - // derived values... - int m_last_particle; - - qreal m_render_opacity; - qreal m_alphaVariation; - qreal m_alpha; - qreal m_redVariation; - qreal m_greenVariation; - qreal m_blueVariation; - qreal m_rotation; - qreal m_rotationVariation; - qreal m_rotationSpeed; - qreal m_rotationSpeedVariation; - bool m_autoRotation; - VaryingVector* m_xVector; - VaryingVector* m_yVector; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // SUPERPARTICLE_H diff --git a/src/imports/particles/swarmaffector.cpp b/src/imports/particles/swarmaffector.cpp deleted file mode 100644 index 513e8a17a7..0000000000 --- a/src/imports/particles/swarmaffector.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "swarmaffector.h" -#include "particle.h" -#include -#include -QT_BEGIN_NAMESPACE - -SwarmAffector::SwarmAffector(QSGItem *parent) : - ParticleAffector(parent), m_strength(1), m_inited(false) -{ - connect(this, SIGNAL(leadersChanged(QStringList)), - this, SLOT(updateGroupList())); -} - -void SwarmAffector::ensureInit() -{ - if(m_inited) - return; - m_inited = true; - updateGroupList(); - m_lastPos.resize(m_system->count()); -} - -const qreal epsilon = 0.0000001; -bool SwarmAffector::affectParticle(ParticleData *d, qreal dt) -{ - ensureInit(); - QPointF curPos(d->curX(), d->curY()); - if(m_leaders.isEmpty() || m_leadGroups.contains(d->group)){ - m_lastPos[d->systemIndex] = curPos; - if(m_leadGroups.contains(d->group)) - return false; - } - - qreal fx = 0.0; - qreal fy = 0.0; - for(int i=0; i < m_lastPos.count(); i++){ - if(m_lastPos[i].isNull()) - continue; - QPointF diff = m_lastPos[i] - curPos; - qreal r = sqrt(diff.x() * diff.x() + diff.y() * diff.y()); - if(r == 0.0) - continue; - qreal f = m_strength * (1/r); - if(f < epsilon) - continue; - qreal theta = atan2(diff.y(), diff.x()); - fx += cos(theta) * f; - fy += sin(theta) * f; - } - if(!fx && !fy) - return false; - d->setInstantaneousSX(d->curSX()+fx * dt); - d->setInstantaneousSY(d->curSY()+fy * dt); - return true; -} - -void SwarmAffector::reset(int systemIdx) -{ - if(!m_system) - return; - if(!m_lastPos[systemIdx].isNull()) - m_lastPos[systemIdx] = QPointF(); -} - -void SwarmAffector::updateGroupList() -{ - if(!m_system || !m_system->m_initialized) - return; - m_leadGroups.clear(); - foreach(const QString &s, m_leaders) - m_leadGroups << m_system->m_groupIds[s]; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/swarmaffector.h b/src/imports/particles/swarmaffector.h deleted file mode 100644 index 63f77c9294..0000000000 --- a/src/imports/particles/swarmaffector.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SWARMAFFECTOR_H -#define SWARMAFFECTOR_H -#include "particleaffector.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class ParticleType; - -class SwarmAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(QStringList leaders READ leaders WRITE setLeaders NOTIFY leadersChanged) -public: - explicit SwarmAffector(QSGItem *parent = 0); - virtual bool affectParticle(ParticleData *d, qreal dt); - virtual void reset(int systemIdx); - - qreal strength() const - { - return m_strength; - } - - QStringList leaders() const - { - return m_leaders; - } - -signals: - - void strengthChanged(qreal arg); - - void leadersChanged(QStringList arg); - -public slots: - -void setStrength(qreal arg) -{ - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); - } -} - -void setLeaders(QStringList arg) -{ - if (m_leaders != arg) { - m_leaders = arg; - emit leadersChanged(arg); - } -} - -private: - void ensureInit(); - void mapUpdate(int idx, qreal strength); - QVector m_lastPos; - qreal m_strength; - bool m_inited; - QStringList m_leaders; - QSet m_leadGroups; -private slots: - void updateGroupList(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SWARMAFFECTOR_H diff --git a/src/imports/particles/toggleaffector.cpp b/src/imports/particles/toggleaffector.cpp deleted file mode 100644 index 5e03b17684..0000000000 --- a/src/imports/particles/toggleaffector.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "toggleaffector.h" - -QT_BEGIN_NAMESPACE - -ToggleAffector::ToggleAffector(QObject *parent) : - ParticleAffector(parent) -{ -} - -bool ToggleAffector::affect(ParticleData *d, qreal dt) -{ - if(m_affecting) - return m_affector->affect(d, dt); - else - return false; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/toggleaffector.h b/src/imports/particles/toggleaffector.h deleted file mode 100644 index 08e7c0e2eb..0000000000 --- a/src/imports/particles/toggleaffector.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TOGGLEAFFECTOR_H -#define TOGGLEAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class ToggleAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(bool affecting READ affecting WRITE setAffecting NOTIFY affectingChanged) - Q_PROPERTY(ParticleAffector* affector READ affector WRITE affector NOTIFY affectorChanged) - Q_CLASSINFO("DefaultProperty", "affector") - -public: - explicit ToggleAffector(QObject *parent = 0); - virtual bool affect(ParticleData *d, qreal dt); - bool affecting() const - { - return m_affecting; - } - - ParticleAffector* affector() const - { - return m_affector; - } - -signals: - - void affectingChanged(bool arg); - - void affectorChanged(ParticleAffector* arg); - -public slots: -void setAffecting(bool arg) -{ - if (m_affecting != arg) { - m_affecting = arg; - emit affectingChanged(arg); - } -} - -void affector(ParticleAffector* arg) -{ - if (m_affector != arg) { - m_affector = arg; - emit affectorChanged(arg); - } -} - -private: -bool m_affecting; -ParticleAffector* m_affector; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // TOGGLEAFFECTOR_H diff --git a/src/imports/particles/trailsemitter.cpp b/src/imports/particles/trailsemitter.cpp deleted file mode 100644 index 41635a4299..0000000000 --- a/src/imports/particles/trailsemitter.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "trailsemitter.h" -#include "particlesystem.h" -#include "particle.h" -QT_BEGIN_NAMESPACE - -TrailsEmitter::TrailsEmitter(QSGItem* parent) - : ParticleEmitter(parent) - , m_speed_from_movement(0) - , m_particle_count(0) - , m_reset_last(true) - , m_last_timestamp(0) - , m_last_emission(0) -{ -// setFlag(ItemHasContents); -} - -void TrailsEmitter::setSpeedFromMovement(qreal t) -{ - if (t == m_speed_from_movement) - return; - m_speed_from_movement = t; - emit speedFromMovementChanged(); -} - -void TrailsEmitter::reset() -{ - m_reset_last = true; -} - -void TrailsEmitter::emitWindow(int timeStamp) -{ - if (m_system == 0) - return; - if((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && m_burstQueue.isEmpty()){ - m_reset_last = true; - return; - } - - if (m_reset_last) { - m_last_emitter = m_last_last_emitter = QPointF(x(), y()); - m_last_timestamp = timeStamp/1000.; - m_last_emission = m_last_timestamp; - m_reset_last = false; - } - - if(m_burstLeft){ - m_burstLeft -= timeStamp - m_last_timestamp * 1000.; - if(m_burstLeft < 0){ - if(!m_emitting) - timeStamp += m_burstLeft; - m_burstLeft = 0; - } - } - - qreal time = timeStamp / 1000.; - - qreal particleRatio = 1. / m_particlesPerSecond; - qreal pt = m_last_emission; - - qreal opt = pt; // original particle time - qreal dt = time - m_last_timestamp; // timestamp delta... - if(!dt) - dt = 0.000001; - - // emitter difference since last... - qreal dex = (x() - m_last_emitter.x()); - qreal dey = (y() - m_last_emitter.y()); - - qreal ax = (m_last_last_emitter.x() + m_last_emitter.x()) / 2; - qreal bx = m_last_emitter.x(); - qreal cx = (x() + m_last_emitter.x()) / 2; - qreal ay = (m_last_last_emitter.y() + m_last_emitter.y()) / 2; - qreal by = m_last_emitter.y(); - qreal cy = (y() + m_last_emitter.y()) / 2; - - qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; - qreal emitter_x_offset = m_last_emitter.x() - x(); - qreal emitter_y_offset = m_last_emitter.y() - y(); - if(!m_burstQueue.isEmpty() && !m_burstLeft && !m_emitting)//'outside time' emissions only - pt = time; - while (pt < time || !m_burstQueue.isEmpty()) { - //int pos = m_last_particle % m_particle_count; - ParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle]); - if(datum){//actually emit(otherwise we've been asked to skip this one) - datum->e = this;//###useful? - ParticleVertex &p = datum->pv; - qreal t = 1 - (pt - opt) / dt; - qreal vx = - - 2 * ax * (1 - t) - + 2 * bx * (1 - 2 * t) - + 2 * cx * t; - qreal vy = - - 2 * ay * (1 - t) - + 2 * by * (1 - 2 * t) - + 2 * cy * t; - - - // Particle timestamp - p.t = pt; - p.lifeSpan = //TODO:Promote to base class? - (m_particleDuration - + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) - / 1000.0; - - // Particle position - QRectF boundsRect; - if(!m_burstQueue.isEmpty()){ - boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(), - width(), height()); - } else { - boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt - , width(), height()); - } - QPointF newPos = effectiveExtruder()->extrude(boundsRect); - p.x = newPos.x(); - p.y = newPos.y(); - - // Particle speed - const QPointF &speed = m_speed->sample(newPos); - p.sx = speed.x() - + m_speed_from_movement * vx; - p.sy = speed.y() - + m_speed_from_movement * vy; - - // Particle acceleration - const QPointF &accel = m_acceleration->sample(newPos); - p.ax = accel.x(); - p.ay = accel.y(); - - // Particle size - float sizeVariation = -m_particleSizeVariation - + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; - - float size = qMax((qreal)0.0 , m_particleSize + sizeVariation); - float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation); - - p.size = size;// * float(m_emitting); - p.endSize = endSize;// * float(m_emitting); - - m_system->emitParticle(datum); - } - if(m_burstQueue.isEmpty()){ - pt += particleRatio; - }else{ - m_burstQueue.first().first--; - if(m_burstQueue.first().first <= 0) - m_burstQueue.pop_front(); - } - } - m_last_emission = pt; - - m_last_last_last_emitter = m_last_last_emitter; - m_last_last_emitter = m_last_emitter; - m_last_emitter = QPointF(x(), y()); - m_last_timestamp = time; -} - - -QT_END_NAMESPACE diff --git a/src/imports/particles/trailsemitter.h b/src/imports/particles/trailsemitter.h deleted file mode 100644 index 1ae150c0d2..0000000000 --- a/src/imports/particles/trailsemitter.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TRAILSEMITTER_H -#define TRAILSEMITTER_H - -#include -#include - -#include "particleemitter.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class ParticleTrailsMaterial; -class QSGGeometryNode; - -class TrailsEmitter : public ParticleEmitter -{ - Q_OBJECT - - Q_PROPERTY(qreal speedFromMovement READ speedFromMovement WRITE setSpeedFromMovement NOTIFY speedFromMovementChanged) - -public: - explicit TrailsEmitter(QSGItem* parent=0); - virtual ~TrailsEmitter(){} - virtual void emitWindow(int timeStamp); - - - qreal speedFromMovement() const { return m_speed_from_movement; } - void setSpeedFromMovement(qreal s); - - qreal renderOpacity() const { return m_render_opacity; } - -signals: - - void speedFromMovementChanged(); - -public slots: -public: - virtual void reset(); -protected: - -private: - - qreal m_speed_from_movement; - - // derived values... - int m_particle_count; - bool m_reset_last; - qreal m_last_timestamp; - qreal m_last_emission; - - QPointF m_last_emitter; - QPointF m_last_last_emitter; - QPointF m_last_last_last_emitter; - - qreal m_render_opacity; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // TRAILSEMITTER_H diff --git a/src/imports/particles/turbulenceaffector.cpp b/src/imports/particles/turbulenceaffector.cpp deleted file mode 100644 index d29f09d974..0000000000 --- a/src/imports/particles/turbulenceaffector.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "turbulenceaffector.h" -#include "particle.h" -#include -#include -#include -QT_BEGIN_NAMESPACE - -TurbulenceAffector::TurbulenceAffector(QSGItem *parent) : - ParticleAffector(parent), - m_strength(10), m_lastT(0), m_frequency(64), m_gridSize(10), m_field(0), m_inited(false) -{ - //TODO: Update grid on size change -} - -TurbulenceAffector::~TurbulenceAffector() -{ - if (m_field) { - for(int i=0; i m_strength){ - //Speed limit - qreal theta = atan2(m_field[i][j].y(), m_field[i][j].x()); - m_field[i][j].setX(m_strength * cos(theta)); - m_field[i][j].setY(m_strength * sin(theta)); - } - } - } -} - - -void TurbulenceAffector::affectSystem(qreal dt) -{ - if(!m_system || !m_active) - return; - ensureInit(); - qreal period = 1.0/m_frequency; - qreal time = m_system->m_timeInt / 1000.0; - while( m_lastT < time ){ - mapUpdate(); - m_lastT += period; - } - - foreach(ParticleData *d, m_system->m_data){ - if(!d || !activeGroup(d->group)) - return; - qreal fx = 0.0; - qreal fy = 0.0; - QPointF pos = QPointF(d->curX() - x(), d->curY() - y());//TODO: Offset - QPointF nodePos = QPointF(pos.x() / m_spacing.x(), pos.y() / m_spacing.y()); - QSet > nodes; - nodes << qMakePair((int)ceil(nodePos.x()), (int)ceil(nodePos.y())); - nodes << qMakePair((int)ceil(nodePos.x()), (int)floor(nodePos.y())); - nodes << qMakePair((int)floor(nodePos.x()), (int)ceil(nodePos.y())); - nodes << qMakePair((int)floor(nodePos.x()), (int)floor(nodePos.y())); - typedef QPair intPair; - foreach(const intPair &p, nodes){ - if(!QRect(0,0,m_gridSize-1,m_gridSize-1).contains(QPoint(p.first, p.second))) - continue; - qreal dist = magnitude(pos.x() - p.first*m_spacing.x(), pos.y() - p.second*m_spacing.y());//TODO: Mathematically valid - fx += m_field[p.first][p.second].x() * ((m_magSum - dist)/m_magSum);//Proportionally weight nodes - fy += m_field[p.first][p.second].y() * ((m_magSum - dist)/m_magSum); - } - if(fx || fy){ - d->setInstantaneousSX(d->curSX()+ fx * dt); - d->setInstantaneousSY(d->curSY()+ fy * dt); - m_system->m_needsReset << d; - } - } -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/turbulenceaffector.h b/src/imports/particles/turbulenceaffector.h deleted file mode 100644 index 2dc2ddcdfd..0000000000 --- a/src/imports/particles/turbulenceaffector.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TURBULENCEAFFECTOR_H -#define TURBULENCEAFFECTOR_H -#include "particleaffector.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class ParticleType; - -class TurbulenceAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(int strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged) - Q_PROPERTY(int gridSize READ size WRITE setSize NOTIFY sizeChanged) -public: - explicit TurbulenceAffector(QSGItem *parent = 0); - ~TurbulenceAffector(); - virtual void affectSystem(qreal dt); - - int strength() const - { - return m_strength; - } - - int frequency() const - { - return m_frequency; - } - - int size() const - { - return m_gridSize; - } - -signals: - - void strengthChanged(int arg); - - void frequencyChanged(int arg); - - void sizeChanged(int arg); - -public slots: - -void setStrength(int arg) -{ - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); - } -} - -void setFrequency(int arg) -{ - if (m_frequency != arg) { - m_frequency = arg; - emit frequencyChanged(arg); - } -} - -void setSize(int arg); - -private: - void ensureInit(); - void mapUpdate(); - int m_strength; - qreal m_lastT; - int m_frequency; - int m_gridSize; - QPointF** m_field; - QPointF m_spacing; - qreal m_magSum; - bool m_inited; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // TURBULENCEAFFECTOR_H diff --git a/src/imports/particles/ultraparticle.cpp b/src/imports/particles/ultraparticle.cpp deleted file mode 100644 index fd49523aff..0000000000 --- a/src/imports/particles/ultraparticle.cpp +++ /dev/null @@ -1,993 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "ultraparticle.h" -#include "particleemitter.h" -#include "spritestate.h" -#include "spriteengine.h" -#include -#include - -QT_BEGIN_NAMESPACE - -const float CONV = 0.017453292519943295; -class UltraMaterial : public QSGMaterial -{ -public: - UltraMaterial(bool withSprites=false) - : timestamp(0) - , framecount(1) - , animcount(1) - , usesSprites(withSprites) - { - setFlag(Blending, true); - } - - ~UltraMaterial() - { - delete texture; - delete colortable; - delete sizetable; - delete opacitytable; - } - - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const - { - return this - static_cast(other); - } - - QSGTexture *texture; - QSGTexture *colortable; - QSGTexture *sizetable; - QSGTexture *opacitytable; - - qreal timestamp; - int framecount; - int animcount; - bool usesSprites; -}; -class UltraMaterialData : public QSGMaterialShader -{ -public: - UltraMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/ultravertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/ultrafragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - UltraMaterial *m = static_cast(newEffect); - state.context()->functions()->glActiveTexture(GL_TEXTURE1); - m->colortable->bind(); - program()->setUniformValue(m_colortable_id, 1); - - state.context()->functions()->glActiveTexture(GL_TEXTURE2); - m->sizetable->bind(); - program()->setUniformValue(m_sizetable_id, 2); - - state.context()->functions()->glActiveTexture(GL_TEXTURE3); - m->opacitytable->bind(); - program()->setUniformValue(m_opacitytable_id, 3); - - state.context()->functions()->glActiveTexture(GL_TEXTURE0);//Investigate why this screws up Text{} if placed before 1 - m->texture->bind(); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - program()->setUniformValue(m_framecount_id, (float) m->framecount); - program()->setUniformValue(m_animcount_id, (float) m->animcount); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_colortable_id = program()->uniformLocation("colortable"); - m_sizetable_id = program()->uniformLocation("sizetable"); - m_opacitytable_id = program()->uniformLocation("opacitytable"); - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_framecount_id = program()->uniformLocation("framecount"); - m_animcount_id = program()->uniformLocation("animcount"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vPos", - "vTex", - "vData", - "vVec", - "vColor", - "vDeformVec", - "vRotation", - "vAnimData", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - int m_colortable_id; - int m_sizetable_id; - int m_opacitytable_id; - int m_framecount_id; - int m_animcount_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float UltraMaterialData::chunkOfBytes[1024]; - -QSGMaterialShader *UltraMaterial::createShader() const -{ - if(usesSprites)//TODO: Perhaps just swap the shaders, and don't mind the extra vector? - return new UltraMaterialData; - else - return new UltraMaterialData; -} - - -class SimpleMaterial : public UltraMaterial -{ - virtual QSGMaterialShader *createShader() const; - virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; } -}; - -class SimpleMaterialData : public QSGMaterialShader -{ -public: - SimpleMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0) - { - QFile vf(vertexFile ? vertexFile : ":resources/simplevertex.shader"); - vf.open(QFile::ReadOnly); - m_vertex_code = vf.readAll(); - - QFile ff(fragmentFile ? fragmentFile : ":resources/simplefragment.shader"); - ff.open(QFile::ReadOnly); - m_fragment_code = ff.readAll(); - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - void deactivate() { - QSGMaterialShader::deactivate(); - - for (int i=0; i<8; ++i) { - program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0); - } - } - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) - { - UltraMaterial *m = static_cast(newEffect); - state.context()->functions()->glActiveTexture(GL_TEXTURE0); - m->texture->bind(); - - program()->setUniformValue(m_opacity_id, state.opacity()); - program()->setUniformValue(m_timestamp_id, (float) m->timestamp); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - - virtual void initialize() { - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); - m_timestamp_id = program()->uniformLocation("timestamp"); - } - - virtual const char *vertexShader() const { return m_vertex_code.constData(); } - virtual const char *fragmentShader() const { return m_fragment_code.constData(); } - - virtual char const *const *attributeNames() const { - static const char *attr[] = { - "vPos", - "vTex", - "vData", - "vVec", - 0 - }; - return attr; - } - - virtual bool isColorTable() const { return false; } - - int m_matrix_id; - int m_opacity_id; - int m_timestamp_id; - - QByteArray m_vertex_code; - QByteArray m_fragment_code; - - static float chunkOfBytes[1024]; -}; -float SimpleMaterialData::chunkOfBytes[1024]; - -QSGMaterialShader *SimpleMaterial::createShader() const { - return new SimpleMaterialData; -} - -UltraParticle::UltraParticle(QSGItem* parent) - : ParticleType(parent) - , m_do_reset(false) - , m_color_variation(0.0) - , m_node(0) - , m_material(0) - , m_alphaVariation(0.0) - , m_alpha(1.0) - , m_redVariation(0.0) - , m_greenVariation(0.0) - , m_blueVariation(0.0) - , m_rotation(0) - , m_autoRotation(false) - , m_xVector(0) - , m_yVector(0) - , m_rotationVariation(0) - , m_rotationSpeed(0) - , m_rotationSpeedVariation(0) - , m_spriteEngine(0) - , m_bloat(false) - , perfLevel(Unknown) - , m_lastLevel(Unknown) -{ - setFlag(ItemHasContents); -} - -QDeclarativeListProperty UltraParticle::sprites() -{ - return QDeclarativeListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); -} - -void UltraParticle::setImage(const QUrl &image) -{ - if (image == m_image_name) - return; - m_image_name = image; - emit imageChanged(); - reset(); -} - - -void UltraParticle::setColortable(const QUrl &table) -{ - if (table == m_colortable_name) - return; - m_colortable_name = table; - emit colortableChanged(); - reset(); -} - -void UltraParticle::setSizetable(const QUrl &table) -{ - if (table == m_sizetable_name) - return; - m_sizetable_name = table; - emit sizetableChanged(); - reset(); -} - -void UltraParticle::setOpacitytable(const QUrl &table) -{ - if (table == m_opacitytable_name) - return; - m_opacitytable_name = table; - emit opacitytableChanged(); - reset(); -} - -void UltraParticle::setColor(const QColor &color) -{ - if (color == m_color) - return; - m_color = color; - emit colorChanged(); - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setColorVariation(qreal var) -{ - if (var == m_color_variation) - return; - m_color_variation = var; - emit colorVariationChanged(); - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setAlphaVariation(qreal arg) -{ - if (m_alphaVariation != arg) { - m_alphaVariation = arg; - emit alphaVariationChanged(arg); - } - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setAlpha(qreal arg) -{ - if (m_alpha != arg) { - m_alpha = arg; - emit alphaChanged(arg); - } - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setRedVariation(qreal arg) -{ - if (m_redVariation != arg) { - m_redVariation = arg; - emit redVariationChanged(arg); - } - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setGreenVariation(qreal arg) -{ - if (m_greenVariation != arg) { - m_greenVariation = arg; - emit greenVariationChanged(arg); - } - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setBlueVariation(qreal arg) -{ - if (m_blueVariation != arg) { - m_blueVariation = arg; - emit blueVariationChanged(arg); - } - if(perfLevel < Coloured) - reset(); -} - -void UltraParticle::setRotation(qreal arg) -{ - if (m_rotation != arg) { - m_rotation = arg; - emit rotationChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setRotationVariation(qreal arg) -{ - if (m_rotationVariation != arg) { - m_rotationVariation = arg; - emit rotationVariationChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setRotationSpeed(qreal arg) -{ - if (m_rotationSpeed != arg) { - m_rotationSpeed = arg; - emit rotationSpeedChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setRotationSpeedVariation(qreal arg) -{ - if (m_rotationSpeedVariation != arg) { - m_rotationSpeedVariation = arg; - emit rotationSpeedVariationChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setAutoRotation(bool arg) -{ - if (m_autoRotation != arg) { - m_autoRotation = arg; - emit autoRotationChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setXVector(VaryingVector* arg) -{ - if (m_xVector != arg) { - m_xVector = arg; - emit xVectorChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setYVector(VaryingVector* arg) -{ - if (m_yVector != arg) { - m_yVector = arg; - emit yVectorChanged(arg); - } - if(perfLevel < Deformable) - reset(); -} - -void UltraParticle::setBloat(bool arg) -{ - if (m_bloat != arg) { - m_bloat = arg; - emit bloatChanged(arg); - } - if(perfLevel < 9999) - reset(); -} -void UltraParticle::setCount(int c) -{ - ParticleType::setCount(c); - m_pleaseReset = true; -} - -void UltraParticle::reset() -{ - ParticleType::reset(); - m_pleaseReset = true; -} - -void UltraParticle::createEngine() -{ - if(m_spriteEngine) - delete m_spriteEngine; - if(m_sprites.count()) - m_spriteEngine = new SpriteEngine(m_sprites, this); - else - m_spriteEngine = 0; - reset(); -} - -static QSGGeometry::Attribute SimpleParticle_Attributes[] = { - { 0, 2, GL_FLOAT }, // Position - { 1, 2, GL_FLOAT }, // TexCoord - { 2, 4, GL_FLOAT }, // Data - { 3, 4, GL_FLOAT } // Vectors -}; - -static QSGGeometry::AttributeSet SimpleParticle_AttributeSet = -{ - 4, // Attribute Count - (2 + 2 + 4 + 4 ) * sizeof(float), - SimpleParticle_Attributes -}; - -static QSGGeometry::Attribute UltraParticle_Attributes[] = { - { 0, 2, GL_FLOAT }, // Position - { 1, 2, GL_FLOAT }, // TexCoord - { 2, 4, GL_FLOAT }, // Data - { 3, 4, GL_FLOAT }, // Vectors - { 4, 4, GL_UNSIGNED_BYTE }, // Colors - { 5, 4, GL_FLOAT }, // DeformationVectors - { 6, 3, GL_FLOAT }, // Rotation - { 7, 4, GL_FLOAT } // Anim Data -}; - -static QSGGeometry::AttributeSet UltraParticle_AttributeSet = -{ - 8, // Attribute Count - (2 + 2 + 4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar), - UltraParticle_Attributes -}; - -QSGGeometryNode* UltraParticle::buildSimpleParticleNode() -{ - perfLevel = Simple;//TODO: Intermediate levels - QImage image = QImage(m_image_name.toLocalFile()); - if (image.isNull()) { - printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile())); - return 0; - } - int vCount = m_count * 4; - int iCount = m_count * 6; - qDebug() << "Simple Case"; - - QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - SimpleVertex *vertices = (SimpleVertex *) g->vertexData(); - for (int p=0; pindexDataAsUShort(); - for (int i=0; itexture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - m_material->framecount = 1; - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - - m_last_particle = 0; - - return m_node; -} - -QSGGeometryNode* UltraParticle::buildParticleNode() -{ - if (m_count * 4 > 0xffff) { - printf("UltraParticle: Too many particles... \n");//####Why is this here? - return 0; - } - - if(m_count <= 0) { - printf("UltraParticle: Too few particles... \n"); - return 0; - } - - if(!m_sprites.count() && !m_bloat - && m_colortable_name.isEmpty() - && m_sizetable_name.isEmpty() - && m_opacitytable_name.isEmpty() - && !m_autoRotation - && !m_rotation && !m_rotationVariation - && !m_rotationSpeed && !m_rotationSpeedVariation - && !m_alphaVariation && m_alpha == 1.0 - && !m_redVariation && !m_blueVariation && !m_greenVariation - && !m_color.isValid() - ) - return buildSimpleParticleNode(); - perfLevel = Sprites;//TODO: intermediate levels - if(!m_color.isValid())//But we're in colored level (or higher) - m_color = QColor(Qt::white); - qDebug() << "Complex Case"; - - QImage image; - if(m_sprites.count()){ - if (!m_spriteEngine) { - qWarning() << "UltraParticle: No sprite engine..."; - return 0; - } - image = m_spriteEngine->assembledImage(); - if(image.isNull())//Warning is printed in engine - return 0; - }else{ - image = QImage(m_image_name.toLocalFile()); - if (image.isNull()) { - printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile())); - return 0; - } - } - - int vCount = m_count * 4; - int iCount = m_count * 6; - - QSGGeometry *g = new QSGGeometry(UltraParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - - UltraVertex *vertices = (UltraVertex *) g->vertexData(); - SimpleVertex *oldSimple = (SimpleVertex *) m_lastData;//TODO: Other levels - if(m_lastLevel == 1) - qDebug() << "Theta" << m_lastLevel << oldSimple[0].x << oldSimple[0].y << oldSimple[0].t; - for (int p=0; pindexDataAsUShort();//TODO: Speed gains by copying this over if count unchanged? - for (int i=0; icolortable = sceneGraphEngine()->createTextureFromImage(colortable); - m_material->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable); - m_material->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable); - - m_material->texture = sceneGraphEngine()->createTextureFromImage(image); - m_material->texture->setFiltering(QSGTexture::Linear); - - m_material->framecount = 1; - if(m_spriteEngine){ - m_material->framecount = m_spriteEngine->maxFrames(); - m_spriteEngine->setCount(m_count); - } - - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - - m_last_particle = 0; - - return m_node; -} - -QSGNode *UltraParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if(m_pleaseReset){ - if(m_node){ - if(perfLevel == 1){ - qDebug() << "Beta"; - m_lastData = qMalloc(m_count*sizeof(SimpleVertices));//TODO: Account for count_changed possibility - memcpy(m_lastData, m_node->geometry()->vertexData(), m_count * sizeof(SimpleVertices));//TODO: Multiple levels - } - m_lastLevel = perfLevel; - delete m_node; - } - if(m_material) - delete m_material; - - m_node = 0; - m_material = 0; - m_pleaseReset = false; - } - - if(m_system && m_system->isRunning()) - prepareNextFrame(); - if (m_node){ - update(); - m_node->markDirty(QSGNode::DirtyMaterial); - } - - return m_node; -} - -void UltraParticle::prepareNextFrame() -{ - if (m_node == 0){ //TODO: Staggered loading (as emitted) - m_node = buildParticleNode(); - if(m_node == 0) - return; - qDebug() << "Feature level: " << perfLevel; - } - qint64 timeStamp = m_system->systemSync(this); - - qreal time = timeStamp / 1000.; - m_material->timestamp = time; - - //Advance State - if(m_spriteEngine){//perfLevel == Sprites? - m_material->animcount = m_spriteEngine->spriteCount(); - UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData(); - m_spriteEngine->updateSprites(timeStamp); - for(int i=0; ispriteState(i); - if(curIdx != p.v1.animIdx){ - p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx; - p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(i)/1000.0; - p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(i); - p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(i); - } - } - }else{ - m_material->animcount = 1; - } -} - -template -IntermediateVertices* transplant(IntermediateVertices* iv, VT &v) -{//Deliberate typemangling cast - iv->v1 = (UltraVertex*)&(v.v1); - iv->v2 = (UltraVertex*)&(v.v2); - iv->v3 = (UltraVertex*)&(v.v3); - iv->v4 = (UltraVertex*)&(v.v4); - return iv; -} - -IntermediateVertices* UltraParticle::fetchIntermediateVertices(int pos) -{ - //Note that this class ruins typesafety for you. Maybe even thread safety. - //TODO: Something better, possibly with templates or inheritance - static IntermediateVertices iv; - SimpleVertices *sv; - UltraVertices *uv; - switch(perfLevel){ - case Simple: - sv = (SimpleVertices *) m_node->geometry()->vertexData(); - return transplant(&iv, sv[pos]); - case Coloured: - case Deformable: - case Tabled: - case Sprites: - default: - uv = (UltraVertices *) m_node->geometry()->vertexData(); - return transplant(&iv,uv[pos]); - } -} - -void UltraParticle::reloadColor(const Color4ub &c, ParticleData* d) -{ - UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData(); - int pos = particleTypeIndex(d); - UltraVertices &p = particles[pos]; - p.v1.color = p.v2.color = p.v3.color = p.v4.color = c; -} - -void UltraParticle::reload(ParticleData *d) -{ - if (m_node == 0) - return; - - int pos = particleTypeIndex(d); - IntermediateVertices* p = fetchIntermediateVertices(pos); - - //Perhaps we could be more efficient? - vertexCopy(*p->v1, d->pv); - vertexCopy(*p->v2, d->pv); - vertexCopy(*p->v3, d->pv); - vertexCopy(*p->v4, d->pv); -} - -void UltraParticle::load(ParticleData *d) -{ - if (m_node == 0) - return; - - int pos = particleTypeIndex(d); - IntermediateVertices* p = fetchIntermediateVertices(pos);//Remember this removes typesafety! - Color4ub color; - qreal redVariation = m_color_variation + m_redVariation; - qreal greenVariation = m_color_variation + m_greenVariation; - qreal blueVariation = m_color_variation + m_blueVariation; - switch(perfLevel){//Fall-through is intended on all of them - case Sprites: - // Initial Sprite State - p->v1->animT = p->v2->animT = p->v3->animT = p->v4->animT = p->v1->t; - p->v1->animIdx = p->v2->animIdx = p->v3->animIdx = p->v4->animIdx = 0; - if(m_spriteEngine){ - m_spriteEngine->startSprite(pos); - p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = m_spriteEngine->spriteFrames(pos); - p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = m_spriteEngine->spriteDuration(pos); - }else{ - p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = 1; - p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = 9999; - } - case Tabled: - case Deformable: - //Initial Rotation - if(m_xVector){ - const QPointF &ret = m_xVector->sample(QPointF(d->pv.x, d->pv.y)); - p->v1->xx = p->v2->xx = p->v3->xx = p->v4->xx = ret.x(); - p->v1->xy = p->v2->xy = p->v3->xy = p->v4->xy = ret.y(); - } - if(m_yVector){ - const QPointF &ret = m_yVector->sample(QPointF(d->pv.x, d->pv.y)); - p->v1->yx = p->v2->yx = p->v3->yx = p->v4->yx = ret.x(); - p->v1->yy = p->v2->yy = p->v3->yy = p->v4->yy = ret.y(); - } - p->v1->rotation = p->v2->rotation = p->v3->rotation = p->v4->rotation = - (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; - p->v1->rotationSpeed = p->v2->rotationSpeed = p->v3->rotationSpeed = p->v4->rotationSpeed = - (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; - p->v1->autoRotate = p->v2->autoRotate = p->v3->autoRotate = p->v4->autoRotate = m_autoRotation?1.0:0.0; - case Coloured: - //Color initialization - // Particle color - color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; - color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; - color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; - color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; - p->v1->color = p->v2->color = p->v3->color = p->v4->color = color; - default: - break; - } - - vertexCopy(*p->v1, d->pv); - vertexCopy(*p->v2, d->pv); - vertexCopy(*p->v3, d->pv); - vertexCopy(*p->v4, d->pv); -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/ultraparticle.h b/src/imports/particles/ultraparticle.h deleted file mode 100644 index cb120f9273..0000000000 --- a/src/imports/particles/ultraparticle.h +++ /dev/null @@ -1,354 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ULTRAPARTICLE_H -#define ULTRAPARTICLE_H -#include "particle.h" -#include "varyingvector.h" -#include - -#include "coloredparticle.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class UltraMaterial; -class QSGGeometryNode; - -class SpriteState; -class SpriteEngine; - -/*struct Color4ub {//in coloredparticle - uchar r; - uchar g; - uchar b; - uchar a; -};*/ - -struct SimpleVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; -}; - -struct SimpleVertices { - SimpleVertex v1; - SimpleVertex v2; - SimpleVertex v3; - SimpleVertex v4; -}; - -struct UltraVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float sx; - float sy; - float ax; - float ay; - Color4ub color; - float xx; - float xy; - float yx; - float yy; - float rotation; - float rotationSpeed; - float autoRotate;//Assume that GPUs prefer floats to bools - float animIdx; - float frameDuration; - float frameCount; - float animT; -}; - -struct UltraVertices { - UltraVertex v1; - UltraVertex v2; - UltraVertex v3; - UltraVertex v4; -}; - -struct IntermediateVertices { - UltraVertex* v1; - UltraVertex* v2; - UltraVertex* v3; - UltraVertex* v4; -}; - -class UltraParticle : public ParticleType -{ - Q_OBJECT - Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) - Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) - Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) - Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) - - //###Now just colorize - add a flag for 'solid' color particles(where the img is just a mask?)? - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - //Stacks (added) with individual colorVariations - Q_PROPERTY(qreal colorVariation READ colorVariation WRITE setColorVariation NOTIFY colorVariationChanged) - Q_PROPERTY(qreal redVariation READ redVariation WRITE setRedVariation NOTIFY redVariationChanged) - Q_PROPERTY(qreal greenVariation READ greenVariation WRITE setGreenVariation NOTIFY greenVariationChanged) - Q_PROPERTY(qreal blueVariation READ blueVariation WRITE setBlueVariation NOTIFY blueVariationChanged) - //Stacks (multiplies) with the Alpha in the color, mostly here so you can use svg color names (which have full alpha) - Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged) - Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged) - - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) - Q_PROPERTY(qreal rotationVariation READ rotationVariation WRITE setRotationVariation NOTIFY rotationVariationChanged) - Q_PROPERTY(qreal rotationSpeed READ rotationSpeed WRITE setRotationSpeed NOTIFY rotationSpeedChanged) - Q_PROPERTY(qreal rotationSpeedVariation READ rotationSpeedVariation WRITE setRotationSpeedVariation NOTIFY rotationSpeedVariationChanged) - //If true, then will face the direction of motion. Stacks with rotation, e.g. setting rotation - //to 180 will lead to facing away from the direction of motion - Q_PROPERTY(bool autoRotation READ autoRotation WRITE setAutoRotation NOTIFY autoRotationChanged) - - //###Call i/j? Makes more sense to those with vector calculus experience, and I could even add the cirumflex in QML? - //xVector is the vector from the top-left point to the top-right point, and is multiplied by current size - Q_PROPERTY(VaryingVector* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged) - //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram. - Q_PROPERTY(VaryingVector* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged) - Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) - Q_PROPERTY(bool bloat READ bloat WRITE setBloat NOTIFY bloatChanged)//Just a debugging property to bypass optimizations -public: - explicit UltraParticle(QSGItem *parent = 0); - virtual ~UltraParticle(){} - - virtual void load(ParticleData*); - virtual void reload(ParticleData*); - virtual void setCount(int c); - - QDeclarativeListProperty sprites(); - SpriteEngine* spriteEngine() {return m_spriteEngine;} - - enum PerformanceLevel{//TODO: Expose? - Unknown = 0, - Simple, - Coloured, - Deformable, - Tabled, - Sprites - }; - - QUrl image() const { return m_image_name; } - void setImage(const QUrl &image); - - QUrl colortable() const { return m_colortable_name; } - void setColortable(const QUrl &table); - - QUrl sizetable() const { return m_sizetable_name; } - void setSizetable (const QUrl &table); - - QUrl opacitytable() const { return m_opacitytable_name; } - void setOpacitytable(const QUrl &table); - - QColor color() const { return m_color; } - void setColor(const QColor &color); - - qreal colorVariation() const { return m_color_variation; } - void setColorVariation(qreal var); - - qreal renderOpacity() const { return m_render_opacity; } - - qreal alphaVariation() const { return m_alphaVariation; } - - qreal alpha() const { return m_alpha; } - - qreal redVariation() const { return m_redVariation; } - - qreal greenVariation() const { return m_greenVariation; } - - qreal blueVariation() const { return m_blueVariation; } - - qreal rotation() const { return m_rotation; } - - qreal rotationVariation() const { return m_rotationVariation; } - - qreal rotationSpeed() const { return m_rotationSpeed; } - - qreal rotationSpeedVariation() const { return m_rotationSpeedVariation; } - - bool autoRotation() const { return m_autoRotation; } - - VaryingVector* xVector() const { return m_xVector; } - - VaryingVector* yVector() const { return m_yVector; } - - bool bloat() const { return m_bloat; } - -signals: - - void imageChanged(); - void colortableChanged(); - void sizetableChanged(); - void opacitytableChanged(); - - void colorChanged(); - void colorVariationChanged(); - - void particleDurationChanged(); - void alphaVariationChanged(qreal arg); - - void alphaChanged(qreal arg); - - void redVariationChanged(qreal arg); - - void greenVariationChanged(qreal arg); - - void blueVariationChanged(qreal arg); - - void rotationChanged(qreal arg); - - void rotationVariationChanged(qreal arg); - - void rotationSpeedChanged(qreal arg); - - void rotationSpeedVariationChanged(qreal arg); - - void autoRotationChanged(bool arg); - - void xVectorChanged(VaryingVector* arg); - - void yVectorChanged(VaryingVector* arg); - - void bloatChanged(bool arg); - -public slots: - void reloadColor(const Color4ub &c, ParticleData* d); - void setAlphaVariation(qreal arg); - - void setAlpha(qreal arg); - - void setRedVariation(qreal arg); - - void setGreenVariation(qreal arg); - - void setBlueVariation(qreal arg); - - void setRotation(qreal arg); - - void setRotationVariation(qreal arg); - - void setRotationSpeed(qreal arg); - - void setRotationSpeedVariation(qreal arg); - - void setAutoRotation(bool arg); - - void setXVector(VaryingVector* arg); - - void setYVector(VaryingVector* arg); - - void setBloat(bool arg); - -protected: - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void reset(); - void prepareNextFrame(); - QSGGeometryNode* buildParticleNode(); - QSGGeometryNode* buildSimpleParticleNode(); - -private slots: - void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty - -private: - //void vertexCopy(UltraVertex &b,const ParticleVertex& a); - IntermediateVertices* fetchIntermediateVertices(int pos); - bool m_do_reset; - - QUrl m_image_name; - QUrl m_colortable_name; - QUrl m_sizetable_name; - QUrl m_opacitytable_name; - - - QColor m_color; - qreal m_color_variation; - qreal m_particleDuration; - - QSGGeometryNode *m_node; - UltraMaterial *m_material; - - // derived values... - int m_last_particle; - - qreal m_render_opacity; - qreal m_alphaVariation; - qreal m_alpha; - qreal m_redVariation; - qreal m_greenVariation; - qreal m_blueVariation; - qreal m_rotation; - qreal m_rotationVariation; - qreal m_rotationSpeed; - qreal m_rotationSpeedVariation; - bool m_autoRotation; - VaryingVector* m_xVector; - VaryingVector* m_yVector; - - QList m_sprites; - SpriteEngine* m_spriteEngine; - - bool m_bloat; - PerformanceLevel perfLevel; - - PerformanceLevel m_lastLevel; - void* m_lastData; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ULTRAPARTICLE_H diff --git a/src/imports/particles/varyingvector.cpp b/src/imports/particles/varyingvector.cpp deleted file mode 100644 index ab09f47f79..0000000000 --- a/src/imports/particles/varyingvector.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "varyingvector.h" - -QT_BEGIN_NAMESPACE - -VaryingVector::VaryingVector(QObject *parent) : - QObject(parent) -{ -} - -const QPointF &VaryingVector::sample(const QPointF &from) -{ - return m_ret; -} - -QT_END_NAMESPACE diff --git a/src/imports/particles/varyingvector.h b/src/imports/particles/varyingvector.h deleted file mode 100644 index 9f80366d2e..0000000000 --- a/src/imports/particles/varyingvector.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VARYINGVECTOR_H -#define VARYINGVECTOR_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class VaryingVector : public QObject -{ - Q_OBJECT -public: - explicit VaryingVector(QObject *parent = 0); - - virtual const QPointF &sample(const QPointF &from); -signals: - -public slots: - -protected: - QPointF m_ret; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // VARYINGVECTOR_H diff --git a/src/imports/particles/wanderaffector.cpp b/src/imports/particles/wanderaffector.cpp deleted file mode 100644 index 4d3ba5f7ce..0000000000 --- a/src/imports/particles/wanderaffector.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "wanderaffector.h" -#include "particlesystem.h"//for ParticlesVertices -QT_BEGIN_NAMESPACE - -WanderAffector::WanderAffector(QSGItem *parent) : - ParticleAffector(parent) -{ - m_needsReset = true; -} - -WanderAffector::~WanderAffector() -{ - for(QHash::const_iterator iter=m_wanderData.constBegin(); - iter != m_wanderData.constEnd(); iter++) - delete (*iter); -} - -WanderData* WanderAffector::getData(int idx) -{ - if(m_wanderData.contains(idx)) - return m_wanderData[idx]; - WanderData* d = new WanderData; - d->x_vel = 0; - d->y_vel = 0; - d->x_peak = m_xVariance; - d->y_peak = m_yVariance; - d->x_var = m_pace * qreal(qrand()) / RAND_MAX; - d->y_var = m_pace * qreal(qrand()) / RAND_MAX; - - m_wanderData.insert(idx, d); - return d; -} - -void WanderAffector::reset(int systemIdx) -{ - if(m_wanderData.contains(systemIdx)) - delete m_wanderData[systemIdx]; - m_wanderData.remove(systemIdx); -} - -bool WanderAffector::affectParticle(ParticleData* data, qreal dt) -{ - WanderData* d = getData(data->systemIndex); - if (m_xVariance != 0.) { - if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) { - d->x_var = -d->x_var; - d->x_peak = m_xVariance + m_xVariance * qreal(qrand()) / RAND_MAX; - } - d->x_vel += d->x_var * dt; - } - qreal dx = dt * d->x_vel; - - if (m_yVariance != 0.) { - if ((d->y_vel > d->y_peak && d->y_var > 0.0) || (d->y_vel < -d->y_peak && d->y_var < 0.0)) { - d->y_var = -d->y_var; - d->y_peak = m_yVariance + m_yVariance * qreal(qrand()) / RAND_MAX; - } - d->y_vel += d->y_var * dt; - } - qreal dy = dt * d->x_vel; - - //### Should we be amending vel instead? - ParticleVertex* p = &(data->pv); - p->x += dx; - - p->y += dy; - return true; -} -QT_END_NAMESPACE diff --git a/src/imports/particles/wanderaffector.h b/src/imports/particles/wanderaffector.h deleted file mode 100644 index 612872830b..0000000000 --- a/src/imports/particles/wanderaffector.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WANDERAFFECTOR_H -#define WANDERAFFECTOR_H -#include -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class SpriteEmitter; - -struct WanderData{ - qreal x_vel; - qreal y_vel; - qreal x_peak; - qreal x_var; - qreal y_peak; - qreal y_var; -}; - -class WanderAffector : public ParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged) - Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) - Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) - -public: - explicit WanderAffector(QSGItem *parent = 0); - ~WanderAffector(); - virtual void reset(int systemIdx); - - qreal xVariance() const - { - return m_xVariance; - } - - qreal yVariance() const - { - return m_yVariance; - } - - qreal pace() const - { - return m_pace; - } -protected: - virtual bool affectParticle(ParticleData *d, qreal dt); -signals: - - void xVarianceChanged(qreal arg); - - void yVarianceChanged(qreal arg); - - void paceChanged(qreal arg); - -public slots: -void setXVariance(qreal arg) -{ - if (m_xVariance != arg) { - m_xVariance = arg; - emit xVarianceChanged(arg); - } -} - -void setYVariance(qreal arg) -{ - if (m_yVariance != arg) { - m_yVariance = arg; - emit yVarianceChanged(arg); - } -} - -void setPace(qreal arg) -{ - if (m_pace != arg) { - m_pace = arg; - emit paceChanged(arg); - } -} - -private: - WanderData* getData(int idx); - QHash m_wanderData; - qreal m_xVariance; - qreal m_yVariance; - qreal m_pace; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // WANDERAFFECTOR_H diff --git a/src/imports/particles/zoneaffector.cpp b/src/imports/particles/zoneaffector.cpp deleted file mode 100644 index cb7adca795..0000000000 --- a/src/imports/particles/zoneaffector.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "zoneaffector.h" -#include - -QT_BEGIN_NAMESPACE - -ZoneAffector::ZoneAffector(QObject *parent) : - ParticleAffector(parent), m_x(0), m_y(0), m_width(0), m_height(0), m_affector(0) -{ -} - -bool ZoneAffector::affect(ParticleData *d, qreal dt) -{ - if(!m_affector) - return false; - qreal x = d->curX(); - qreal y = d->curY(); - if(x >= m_x && x <= m_x+m_width && y >= m_y && y <= m_y+m_height) - return m_affector->affect(d, dt); - return false; -} - -void ZoneAffector::reset(int systemIdx) -{ - if(m_affector) - m_affector->reset(systemIdx); -} -QT_END_NAMESPACE diff --git a/src/imports/particles/zoneaffector.h b/src/imports/particles/zoneaffector.h deleted file mode 100644 index 8c17cedba2..0000000000 --- a/src/imports/particles/zoneaffector.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Declarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ZONEAFFECTOR_H -#define ZONEAFFECTOR_H -#include "particleaffector.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class ZoneAffector : public ParticleAffector -{ - Q_OBJECT - //TODO: Can we get anchors in here? consider becoming an un-parented QSGItem? - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged); - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged); - Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged); - Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged); - Q_PROPERTY(ParticleAffector* affector READ affector WRITE affector NOTIFY affectorChanged) - Q_CLASSINFO("DefaultProperty", "affector") -public: - explicit ZoneAffector(QObject *parent = 0); - - virtual bool affect(ParticleData *d, qreal dt); - virtual void reset(int systemIdx); - - ParticleAffector* affector() const - { - return m_affector; - } - - qreal x() const - { - return m_x; - } - - qreal y() const - { - return m_y; - } - - qreal width() const - { - return m_width; - } - - qreal height() const - { - return m_height; - } - -signals: - - - void affectorChanged(ParticleAffector* arg); - - void xChanged(qreal arg); - - void yChanged(qreal arg); - - void widthChanged(qreal arg); - - void heightChanged(qreal arg); - -public slots: - - -void affector(ParticleAffector* arg) -{ - if (m_affector != arg) { - m_affector = arg; - emit affectorChanged(arg); - } -} - -void setX(qreal arg) -{ - if (m_x != arg) { - m_x = arg; - emit xChanged(arg); - } -} - -void setY(qreal arg) -{ - if (m_y != arg) { - m_y = arg; - emit yChanged(arg); - } -} - -void setWidth(qreal arg) -{ - if (m_width != arg) { - m_width = arg; - emit widthChanged(arg); - } -} - -void setHeight(qreal arg) -{ - if (m_height != arg) { - m_height = arg; - emit heightChanged(arg); - } -} - -private: -qreal m_x; -qreal m_y; -qreal m_width; -qreal m_height; -ParticleAffector* m_affector; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ZONEAFFECTOR_H -- cgit v1.2.3 From 984f21f18d1a3981e7363df467ff2e24e69aa847 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 7 Jun 2011 19:39:38 +1000 Subject: Immense Particles Refactor Part B Examples work again. Also augmented Wander and PointAttractor with physics modes. --- src/declarative/particles/qsgmaskextruder.cpp | 11 +++++- src/declarative/particles/qsgparticleaffector_p.h | 1 - src/declarative/particles/qsgpointattractor.cpp | 32 ++++++++++++--- src/declarative/particles/qsgpointattractor_p.h | 48 +++++++++++++++++++++++ src/declarative/particles/qsgwander.cpp | 36 ++++++++++++++++- src/declarative/particles/qsgwander_p.h | 29 +++++++++++++- 6 files changed, 147 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/declarative/particles/qsgmaskextruder.cpp b/src/declarative/particles/qsgmaskextruder.cpp index 3fe28b30a3..d9a463910d 100644 --- a/src/declarative/particles/qsgmaskextruder.cpp +++ b/src/declarative/particles/qsgmaskextruder.cpp @@ -53,7 +53,7 @@ QSGMaskExtruder::QSGMaskExtruder(QObject *parent) : QPointF QSGMaskExtruder::extrude(const QRectF &r) { ensureInitialized(r); - if(!m_mask.count()) + if(!m_mask.count() || m_img.isNull()) return r.topLeft(); const QPointF p = m_mask[rand() % m_mask.count()]; //### Should random sub-pixel positioning be added? @@ -63,6 +63,8 @@ QPointF QSGMaskExtruder::extrude(const QRectF &r) bool QSGMaskExtruder::contains(const QRectF &bounds, const QPointF &point) { ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? + if(m_img.isNull()) + return false; QPoint p = point.toPoint() - bounds.topLeft().toPoint(); return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); } @@ -70,14 +72,19 @@ bool QSGMaskExtruder::contains(const QRectF &bounds, const QPointF &point) void QSGMaskExtruder::ensureInitialized(const QRectF &r) { if(m_lastWidth == r.width() && m_lastHeight == r.height()) - return; + return;//Same as before m_lastWidth = r.width(); m_lastHeight = r.height(); + m_img = QImage(); m_mask.clear(); if(m_source.isEmpty()) return; m_img = QImage(m_source.toLocalFile()); + if(m_img.isNull()){ + qWarning() << "MaskShape: Cannot load" << qPrintable(m_source.toLocalFile()); + return; + } m_img = m_img.createAlphaMask(); m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? diff --git a/src/declarative/particles/qsgparticleaffector_p.h b/src/declarative/particles/qsgparticleaffector_p.h index 1572ad8102..b299158069 100644 --- a/src/declarative/particles/qsgparticleaffector_p.h +++ b/src/declarative/particles/qsgparticleaffector_p.h @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) - class QSGParticleAffector : public QSGItem { Q_OBJECT diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp index 3c3ca33086..4c675237ba 100644 --- a/src/declarative/particles/qsgpointattractor.cpp +++ b/src/declarative/particles/qsgpointattractor.cpp @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE QSGPointAttractorAffector::QSGPointAttractorAffector(QSGItem *parent) : QSGParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) + , m_physics(Velocity), m_proportionalToDistance(Linear) { } @@ -52,15 +53,36 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt) { if(m_strength == 0.0) return false; - qreal dx = m_x - d->curX(); - qreal dy = m_y - d->curY(); + qreal dx = m_y - d->curX(); + qreal dy = m_x - d->curY(); qreal r = sqrt((dx*dx) + (dy*dy)); qreal theta = atan2(dy,dx); - qreal ds = (m_strength / r) * dt; + qreal ds = 0; + switch(m_proportionalToDistance){ + case Quadratic: + ds = (m_strength / qMax(1.,r*r)) * dt; + break; + case Linear://also default + default: + ds = (m_strength / qMax(1.,r)) * dt; + } dx = ds * cos(theta); dy = ds * sin(theta); - d->setInstantaneousSX(d->pv.sx + dx); - d->setInstantaneousSY(d->pv.sy + dy); + switch(m_physics){ + case Position: + d->pv.x = (d->pv.x + dx); + d->pv.y = (d->pv.y + dy); + break; + case Acceleration: + d->setInstantaneousAX(d->pv.ax + dx); + d->setInstantaneousAY(d->pv.ay + dy); + break; + case Velocity: //also default + default: + d->setInstantaneousSX(d->pv.sx + dx); + d->setInstantaneousSY(d->pv.sy + dy); + } + return true; } QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgpointattractor_p.h b/src/declarative/particles/qsgpointattractor_p.h index d4f715928a..3ca29dfa96 100644 --- a/src/declarative/particles/qsgpointattractor_p.h +++ b/src/declarative/particles/qsgpointattractor_p.h @@ -57,7 +57,23 @@ class QSGPointAttractorAffector : public QSGParticleAffector Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) + Q_PROPERTY(PhysicsAffects physics READ physics WRITE setPhysics NOTIFY physicsChanged) + Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged) + Q_ENUMS(PhysicsAffects) + Q_ENUMS(Proportion) + public: + enum Proportion{ + Linear, + Quadratic + }; + + enum PhysicsAffects { + Position, + Velocity, + Acceleration + }; + explicit QSGPointAttractorAffector(QSGItem *parent = 0); qreal strength() const @@ -75,6 +91,16 @@ public: return m_y; } + PhysicsAffects physics() const + { + return m_physics; + } + + Proportion proportionalToDistance() const + { + return m_proportionalToDistance; + } + signals: void strengthChanged(qreal arg); @@ -83,6 +109,10 @@ signals: void yChanged(qreal arg); + void physicsChanged(PhysicsAffects arg); + + void proportionalToDistanceChanged(Proportion arg); + public slots: void setStrength(qreal arg) { @@ -107,12 +137,30 @@ void setY(qreal arg) emit yChanged(arg); } } +void setPhysics(PhysicsAffects arg) +{ + if (m_physics != arg) { + m_physics = arg; + emit physicsChanged(arg); + } +} + +void setProportionalToDistance(Proportion arg) +{ + if (m_proportionalToDistance != arg) { + m_proportionalToDistance = arg; + emit proportionalToDistanceChanged(arg); + } +} + protected: virtual bool affectParticle(QSGParticleData *d, qreal dt); private: qreal m_strength; qreal m_x; qreal m_y; +PhysicsAffects m_physics; +Proportion m_proportionalToDistance; }; QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgwander.cpp b/src/declarative/particles/qsgwander.cpp index e6787f2570..6e56d6a05b 100644 --- a/src/declarative/particles/qsgwander.cpp +++ b/src/declarative/particles/qsgwander.cpp @@ -44,7 +44,8 @@ QT_BEGIN_NAMESPACE QSGWanderAffector::QSGWanderAffector(QSGItem *parent) : - QSGParticleAffector(parent) + QSGParticleAffector(parent), m_xVariance(0), m_yVariance(0), m_pace(0) + , m_physics(Velocity) { m_needsReset = true; } @@ -81,6 +82,7 @@ void QSGWanderAffector::reset(int systemIdx) bool QSGWanderAffector::affectParticle(QSGParticleData* data, qreal dt) { + /*TODO: Add a mode which does basically this - picking a direction, going in it (random speed) and then going back WanderData* d = getData(data->systemIndex); if (m_xVariance != 0.) { if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) { @@ -106,5 +108,37 @@ bool QSGWanderAffector::affectParticle(QSGParticleData* data, qreal dt) p->y += dy; return true; + */ + qreal dx = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); + qreal dy = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); + qreal newX, newY; + switch(m_physics){ + case Position: + newX = data->curX() + dx; + if(m_xVariance > qAbs(newX) ) + data->pv.x += dx; + newY = data->curY() + dy; + if(m_yVariance > qAbs(newY) ) + data->pv.y += dy; + break; + default: + case Velocity: + newX = data->curSX() + dx; + if(m_xVariance > qAbs(newX) ) + data->setInstantaneousSX(newX); + newY = data->curSY() + dy; + if(m_yVariance > qAbs(newY) ) + data->setInstantaneousSY(newY); + break; + case Acceleration: + newX = data->pv.ax + dx; + if(m_xVariance > qAbs(newX) ) + data->setInstantaneousAX(newX); + newY = data->pv.ay + dy; + if(m_yVariance > qAbs(newY) ) + data->setInstantaneousAY(newY); + break; + } + return true; } QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgwander_p.h b/src/declarative/particles/qsgwander_p.h index 45c8ca8b20..783efc8636 100644 --- a/src/declarative/particles/qsgwander_p.h +++ b/src/declarative/particles/qsgwander_p.h @@ -63,11 +63,19 @@ struct WanderData{ class QSGWanderAffector : public QSGParticleAffector { Q_OBJECT + Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged) Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) - Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) + Q_PROPERTY(PhysicsAffects physics READ physics WRITE setPhysics NOTIFY physicsChanged) + Q_ENUMS(PhysicsAffects) public: + enum PhysicsAffects { + Position, + Velocity, + Acceleration + }; + explicit QSGWanderAffector(QSGItem *parent = 0); ~QSGWanderAffector(); virtual void reset(int systemIdx); @@ -86,6 +94,12 @@ public: { return m_pace; } + + PhysicsAffects physics() const + { + return m_physics; + } + protected: virtual bool affectParticle(QSGParticleData *d, qreal dt); signals: @@ -96,6 +110,9 @@ signals: void paceChanged(qreal arg); + + void physicsChanged(PhysicsAffects arg); + public slots: void setXVariance(qreal arg) { @@ -121,12 +138,22 @@ void setPace(qreal arg) } } + +void setPhysics(PhysicsAffects arg) +{ + if (m_physics != arg) { + m_physics = arg; + emit physicsChanged(arg); + } +} + private: WanderData* getData(int idx); QHash m_wanderData; qreal m_xVariance; qreal m_yVariance; qreal m_pace; + PhysicsAffects m_physics; }; QT_END_NAMESPACE -- cgit v1.2.3 From 8b5b68ba41da1b7f93dfa6164fb7c3b00c832aae Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 27 May 2011 14:55:06 +0200 Subject: Fixed clock_gettime() library dependency. The old construct doesn't work if the QtBase source is unavailable. Reviewed-by: Marius Storm-Olsen --- src/declarative/qml/qml.pri | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 78fb06358e..233359079d 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -135,5 +135,7 @@ include(parser/parser.pri) include(rewriter/rewriter.pri) include(v4/v4.pri) -# mirrors logic in corelib/kernel/kernel.pri -unix:!symbian: contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri) +# clock_gettime() is implemented in librt on these systems +contains(QT_CONFIG, clock-gettime) { + linux-*|hpux-*|solaris-*:LIBS_PRIVATE *= -lrt +} -- cgit v1.2.3 From 50ccddca51daf995c5cc9505f36c9acc979e0f25 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 30 May 2011 16:11:05 +0200 Subject: Use feature profile loading instead of direct inclusion. --- src/declarative/declarative.pro | 2 +- src/imports/qimportbase.pri | 4 ++-- src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro | 2 +- src/plugins/qmltooling/qmldbg_ost/qmldbg_ost.pro | 2 +- src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index adf1408c58..cbd7d24753 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -19,7 +19,7 @@ exists("qdeclarative_enable_gcov") { LIBS += -lgcov } -include($$QT_SOURCE_TREE/src/qbase.pri) +load(qt_module_config) HEADERS += qtdeclarativeversion.h diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri index 8647f05cb9..405af24ece 100644 --- a/src/imports/qimportbase.pri +++ b/src/imports/qimportbase.pri @@ -1,6 +1,6 @@ load(qt_module) -symbian:include($$QT_SOURCE_TREE/src/plugins/qpluginbase.pri) +symbian:load(qt_plugin) TEMPLATE = lib CONFIG += qt plugin @@ -27,7 +27,7 @@ QMAKE_EXTRA_COMPILERS += copy2build TARGET = $$qtLibraryTarget($$TARGET) contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols -include($$QT_SOURCE_TREE/src/qt_targets.pri) +load(qt_targets) wince*:LIBS += $$QMAKE_LIBS_GUI diff --git a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro index d7c2061556..385326a806 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro +++ b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro @@ -3,7 +3,7 @@ load(qt_module) TARGET = qmldbg_inspector QT += declarative-private -include($$QT_SOURCE_TREE/src/plugins/qpluginbase.pri) +load(qt_plugin) DESTDIR = $$QT.declarative.plugins/qmltooling QTDIR_build:REQUIRES += "contains(QT_CONFIG, declarative)" diff --git a/src/plugins/qmltooling/qmldbg_ost/qmldbg_ost.pro b/src/plugins/qmltooling/qmldbg_ost/qmldbg_ost.pro index 274888940a..a12fac5da3 100644 --- a/src/plugins/qmltooling/qmldbg_ost/qmldbg_ost.pro +++ b/src/plugins/qmltooling/qmldbg_ost/qmldbg_ost.pro @@ -1,7 +1,7 @@ TARGET = qmldbg_ost QT += declarative network -include(../../qpluginbase.pri) +load(qt_plugin) QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/qmltooling QTDIR_build:REQUIRES += "contains(QT_CONFIG, declarative)" diff --git a/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro b/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro index e5e28a4c38..c5f8f90cd6 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro +++ b/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro @@ -3,7 +3,7 @@ load(qt_module) TARGET = qmldbg_tcp QT += declarative-private network -include($$QT_SOURCE_TREE/src/plugins/qpluginbase.pri) +load(qt_plugin) DESTDIR = $$QT.declarative.plugins/qmltooling QTDIR_build:REQUIRES += "contains(QT_CONFIG, declarative)" -- cgit v1.2.3 From 79e3289376aa1b7d8df0b46f62e2a83b98845955 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Tue, 7 Jun 2011 08:28:02 -0500 Subject: Fix missing include->load conversion of qbase.pri --- src/qmltest/qmltest.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro index 0c3b7c825d..1c2bfd0ab0 100644 --- a/src/qmltest/qmltest.pro +++ b/src/qmltest/qmltest.pro @@ -11,7 +11,7 @@ QT += testlib-private declarative script testlib DEFINES += QT_BUILD_QUICK_TEST_LIB QT_NO_URL_CAST_FROM_STRING -include($$QT_SOURCE_TREE/src/qbase.pri) +load(qt_module_config) # Install qmltestcase.prf into the Qt mkspecs so that "CONFIG += qmltestcase" # can be used in customer applications to build against QtQuickTest. -- cgit v1.2.3 From 6d91133bae78ecb98cc701b5c31f7a570cf58a6e Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 8 Jun 2011 07:06:25 +0200 Subject: Wake render thread when doing paint() and grab() as in resize() --- src/declarative/items/qsgcanvas.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 963c19f25d..240088cf23 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -2085,8 +2085,11 @@ void QSGCanvasRenderThread::paint() exhaustSyncEvent(); isPaintCompleted = false; - while (isRunning() && !isPaintCompleted) + while (isRunning() && !isPaintCompleted) { + if (isRenderBlocked) + wake(); wait(); + } unlockInGui(); // paint is only called for the inital show. After that we will do all @@ -2182,9 +2185,7 @@ QImage QSGCanvasRenderThread::grab() doGrab = true; isPaintCompleted = false; while (isRunning() && !isPaintCompleted) { - // If we're in an animation we don't need to wake as we know another frame - // will be pending anyway. - if (!d->animationRunning) + if (!isRenderBlocked) wake(); wait(); } -- cgit v1.2.3 From e2d979243c398a46ee9c3b1f36c647884952b6c7 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 8 Jun 2011 16:59:33 +1000 Subject: Don't crash if GL context initialization failed --- src/declarative/items/qsgcanvas.cpp | 84 +++++++++++++++++++++---------------- src/declarative/items/qsgcanvas_p.h | 1 + 2 files changed, 49 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 16bd8ce44c..8caf1856ab 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -222,29 +222,31 @@ void QSGCanvas::showEvent(QShowEvent *e) QGLWidget::showEvent(e); - if (d->threadedRendering) { - d->contextInThread = true; - doneCurrent(); - if (!d->animationDriver) { - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(_q_animationStarted()), Qt::DirectConnection); - connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(_q_animationStopped()), Qt::DirectConnection); - } - d->animationDriver->install(); - d->mutex.lock(); - d->thread->start(); - d->wait.wait(&d->mutex); - d->mutex.unlock(); - } else { - makeCurrent(); + if (!d->contextFailed) { + if (d->threadedRendering) { + d->contextInThread = true; + doneCurrent(); + if (!d->animationDriver) { + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), this, SLOT(_q_animationStarted()), Qt::DirectConnection); + connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(_q_animationStopped()), Qt::DirectConnection); + } + d->animationDriver->install(); + d->mutex.lock(); + d->thread->start(); + d->wait.wait(&d->mutex); + d->mutex.unlock(); + } else { + makeCurrent(); - if (!d->context || !d->context->isReady()) { - d->initializeSceneGraph(); - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); - } + if (!d->context || !d->context->isReady()) { + d->initializeSceneGraph(); + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); + } - d->animationDriver->install(); + d->animationDriver->install(); + } } } @@ -252,10 +254,12 @@ void QSGCanvas::hideEvent(QHideEvent *e) { Q_D(QSGCanvas); - if (d->threadedRendering) - d->stopRenderingThread(); + if (!d->contextFailed) { + if (d->threadedRendering) + d->stopRenderingThread(); - d->animationDriver->uninstall(); + d->animationDriver->uninstall(); + } QGLWidget::hideEvent(e); } @@ -460,6 +464,7 @@ QSGCanvasPrivate::QSGCanvasPrivate() , hoverItem(0) , dirtyItemList(0) , context(0) + , contextFailed(false) , contextInThread(false) , threadedRendering(false) , exitThread(false) @@ -482,6 +487,11 @@ void QSGCanvasPrivate::init(QSGCanvas *c) { QUnifiedTimer::instance(true)->setConsistentTiming(qmlFixedAnimationStep()); + if (!c->context() || !c->context()->isValid()) { + contextFailed = true; + qWarning("QSGCanvas: Couldn't acquire a GL context."); + } + q_ptr = c; Q_Q(QSGCanvas); @@ -960,18 +970,20 @@ QSGCanvas::~QSGCanvas() d->cleanupNodes(); - // We need to remove all references to textures pointing to "our" QSGContext - // from the QDeclarativePixmapCache. Call into the cache to remove the GL / Scene Graph - // part of those cache entries. - // To "play nice" with other GL apps that are potentially running in the GUI thread, - // We get the current context and only temporarily make our own current - QGLContext *currentContext = const_cast(QGLContext::currentContext()); - makeCurrent(); - extern void qt_declarative_pixmapstore_clean(QSGContext *context); - qt_declarative_pixmapstore_clean(d->context); - delete d->context; - if (currentContext) - currentContext->makeCurrent(); + if (!d->contextFailed) { + // We need to remove all references to textures pointing to "our" QSGContext + // from the QDeclarativePixmapCache. Call into the cache to remove the GL / Scene Graph + // part of those cache entries. + // To "play nice" with other GL apps that are potentially running in the GUI thread, + // We get the current context and only temporarily make our own current + QGLContext *currentContext = const_cast(QGLContext::currentContext()); + makeCurrent(); + extern void qt_declarative_pixmapstore_clean(QSGContext *context); + qt_declarative_pixmapstore_clean(d->context); + delete d->context; + if (currentContext) + currentContext->makeCurrent(); + } } QSGItem *QSGCanvas::rootItem() const diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h index 6b8034f922..9d37391f57 100644 --- a/src/declarative/items/qsgcanvas_p.h +++ b/src/declarative/items/qsgcanvas_p.h @@ -156,6 +156,7 @@ public: QSGContext *context; + uint contextFailed : 1; uint contextInThread : 1; uint threadedRendering : 1; uint exitThread : 1; -- cgit v1.2.3 From c8a5c00ec1c06f7c00070d55cd61cb8d52dc67cf Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 8 Jun 2011 17:55:41 +1000 Subject: Immense Particles Refactor Part D Changed the names of several properties: FollowEmitter: emissionShape->emitShape emissionHeight->emitHeight emissionWidth->emitWidth Emitter: particlesPerSecond->emitRate particleDuration->lifeSpan particleDurationVariation->lifeSpanVariation maxParticles->emitCap particleSize->size particleEndSize->endSize particleSizeVariation->sizeVariation ImageParticle: image->source And stopped being silly in the example launcher. --- src/declarative/particles/qsgfollowemitter_p.h | 8 ++++---- src/declarative/particles/qsgimageparticle_p.h | 2 +- src/declarative/particles/qsgparticleemitter_p.h | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/declarative/particles/qsgfollowemitter_p.h b/src/declarative/particles/qsgfollowemitter_p.h index 314bd4e7c1..bf5d2fe8ef 100644 --- a/src/declarative/particles/qsgfollowemitter_p.h +++ b/src/declarative/particles/qsgfollowemitter_p.h @@ -56,13 +56,13 @@ class QSGFollowEmitter : public QSGParticleEmitter Q_OBJECT Q_PROPERTY(QString follow READ follow WRITE setFollow NOTIFY followChanged) //### Remove, and just document that particles per second is per particle? But has count issues - Q_PROPERTY(int particlesPerParticlePerSecond READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged) + Q_PROPERTY(int emitRatePerParticle READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged) //TODO: Document that FollowEmitter's box is where it follows. It emits in a rect centered on the followed particle //TODO: A set of properties that can involve the particle size of the followed - Q_PROPERTY(QSGParticleExtruder* emissionShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged) - Q_PROPERTY(qreal emissionHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) - Q_PROPERTY(qreal emissionWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) + Q_PROPERTY(QSGParticleExtruder* emitShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged) + Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) + Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) public: explicit QSGFollowEmitter(QSGItem *parent = 0); diff --git a/src/declarative/particles/qsgimageparticle_p.h b/src/declarative/particles/qsgimageparticle_p.h index 1318647cc9..c6ec4c2c6a 100644 --- a/src/declarative/particles/qsgimageparticle_p.h +++ b/src/declarative/particles/qsgimageparticle_p.h @@ -130,7 +130,7 @@ struct IntermediateVertices { class QSGImageParticle : public QSGParticlePainter { Q_OBJECT - Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged) + Q_PROPERTY(QUrl source READ image WRITE setImage NOTIFY imageChanged) Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h index ad6a5f645f..9fafd9d43d 100644 --- a/src/declarative/particles/qsgparticleemitter_p.h +++ b/src/declarative/particles/qsgparticleemitter_p.h @@ -66,14 +66,14 @@ class QSGParticleEmitter : public QSGItem Q_PROPERTY(QSGParticleExtruder* shape READ extruder WRITE setExtruder NOTIFY extruderChanged) Q_PROPERTY(bool emitting READ emitting WRITE setEmitting NOTIFY emittingChanged) - Q_PROPERTY(qreal particlesPerSecond READ particlesPerSecond WRITE setParticlesPerSecond NOTIFY particlesPerSecondChanged) - Q_PROPERTY(int particleDuration READ particleDuration WRITE setParticleDuration NOTIFY particleDurationChanged) - Q_PROPERTY(int particleDurationVariation READ particleDurationVariation WRITE setParticleDurationVariation NOTIFY particleDurationVariationChanged) - Q_PROPERTY(int maxParticles READ maxParticleCount WRITE setMaxParticleCount NOTIFY maxParticleCountChanged) - - Q_PROPERTY(qreal particleSize READ particleSize WRITE setParticleSize NOTIFY particleSizeChanged) - Q_PROPERTY(qreal particleEndSize READ particleEndSize WRITE setParticleEndSize NOTIFY particleEndSizeChanged) - Q_PROPERTY(qreal particleSizeVariation READ particleSizeVariation WRITE setParticleSizeVariation NOTIFY particleSizeVariationChanged) + Q_PROPERTY(qreal emitRate READ particlesPerSecond WRITE setParticlesPerSecond NOTIFY particlesPerSecondChanged) + Q_PROPERTY(int lifeSpan READ particleDuration WRITE setParticleDuration NOTIFY particleDurationChanged) + Q_PROPERTY(int lifeSpanVariation READ particleDurationVariation WRITE setParticleDurationVariation NOTIFY particleDurationVariationChanged) + Q_PROPERTY(int emitCap READ maxParticleCount WRITE setMaxParticleCount NOTIFY maxParticleCountChanged) + + Q_PROPERTY(qreal size READ particleSize WRITE setParticleSize NOTIFY particleSizeChanged) + Q_PROPERTY(qreal endSize READ particleEndSize WRITE setParticleEndSize NOTIFY particleEndSizeChanged) + Q_PROPERTY(qreal sizeVariation READ particleSizeVariation WRITE setParticleSizeVariation NOTIFY particleSizeVariationChanged) Q_PROPERTY(QSGStochasticDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged) Q_PROPERTY(QSGStochasticDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) -- cgit v1.2.3 From ccf706d0bb2d9f70f5a8c18e4aab8ee7e6369817 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 8 Jun 2011 13:18:35 +1000 Subject: Optimized QDeclarativeScriptString constructor for QDeclarativeExpression. When the compiler sees a script string, it will attempt to rewrite it and store the id for the rewrite in the script string. We can then create a QDeclarativeExpression using the id, which saves us a rewrite at runtime. Reviewed-by: Aaron Kennedy --- src/declarative/qml/qdeclarativecompiler.cpp | 6 ++- src/declarative/qml/qdeclarativeexpression.cpp | 53 ++++++++++++++++++++ src/declarative/qml/qdeclarativeexpression.h | 2 + src/declarative/qml/qdeclarativeinstruction.cpp | 2 +- src/declarative/qml/qdeclarativeinstruction_p.h | 2 + src/declarative/qml/qdeclarativescriptstring.cpp | 15 ++---- src/declarative/qml/qdeclarativescriptstring.h | 3 ++ src/declarative/qml/qdeclarativescriptstring_p.h | 63 ++++++++++++++++++++++++ src/declarative/qml/qdeclarativevme.cpp | 3 ++ src/declarative/qml/qml.pri | 1 + 10 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 src/declarative/qml/qdeclarativescriptstring_p.h (limited to 'src') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index e66a3fe792..72010c0ef2 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1012,12 +1012,14 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) { typedef QPair PropPair; foreach(const PropPair &prop, obj->scriptStringProperties) { + const QString &script = prop.first->values.at(0)->value.asScript(); QDeclarativeInstruction ss; ss.setType(QDeclarativeInstruction::StoreScriptString); ss.storeScriptString.propertyIndex = prop.first->index; - ss.storeScriptString.value = - output->indexForString(prop.first->values.at(0)->value.asScript()); + ss.storeScriptString.value = output->indexForString(script); ss.storeScriptString.scope = prop.second; + ss.storeScriptString.bindingId = rewriteBinding(script, prop.first->name); + ss.storeScriptString.line = prop.first->location.start.line; output->addInstruction(ss); } diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 247bde9a6c..8079cf3eea 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -45,6 +45,7 @@ #include "private/qdeclarativeengine_p.h" #include "private/qdeclarativecontext_p.h" #include "private/qdeclarativerewrite_p.h" +#include "private/qdeclarativescriptstring_p.h" #include "private/qdeclarativecompiler_p.h" #include "private/qdeclarativeglobalscriptclass_p.h" @@ -268,6 +269,58 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, vo d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); } +/*! + Create a QDeclarativeExpression object that is a child of \a parent. + + The \script provides the expression to be evaluated, the context to evaluate it in, + and the scope object to evaluate it with. + + This constructor is functionally equivalent to the following, but in most cases + is more efficient. + \code + QDeclarativeExpression expression(script.context(), script.scopeObject(), script.script(), parent); + \endcode + + \sa QDeclarativeScriptString +*/ +QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &script, QObject *parent) +: QObject(*new QDeclarativeExpressionPrivate, parent) +{ + Q_D(QDeclarativeExpression); + bool defaultConstruction = false; + + int id = script.d.data()->bindingId; + if (id < 0) { + defaultConstruction = true; + } else { + QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(script.context()); + + QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(script.scopeObject())); + QDeclarativeCompiledData *cdata = 0; + QDeclarativeTypeData *typeData = 0; + if (engine && ctxtdata && !ctxtdata->url.isEmpty()) { + typeData = engine->typeLoader.get(ctxtdata->url); + cdata = typeData->compiledData(); + } + + if (cdata) + d->init(ctxtdata, (void*)cdata->datas.at(id).constData(), cdata, script.scopeObject(), + cdata->name, script.d.data()->lineNumber); + else + defaultConstruction = true; + + if (typeData) + typeData->release(); + } + + if (defaultConstruction) + d->init(QDeclarativeContextData::get(script.context()), script.script(), script.scopeObject()); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); +} + /*! Create a QDeclarativeExpression object that is a child of \a parent. diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h index fef97de2b2..b76205c82e 100644 --- a/src/declarative/qml/qdeclarativeexpression.h +++ b/src/declarative/qml/qdeclarativeexpression.h @@ -43,6 +43,7 @@ #define QDECLARATIVEEXPRESSION_H #include +#include #include #include @@ -66,6 +67,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject public: QDeclarativeExpression(); QDeclarativeExpression(QDeclarativeContext *, QObject *, const QString &, QObject * = 0); + explicit QDeclarativeExpression(const QDeclarativeScriptString &, QObject * = 0); virtual ~QDeclarativeExpression(); QDeclarativeEngine *engine() const; diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index fa0d8ea6f4..79a2a1cc34 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -160,7 +160,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value; break; case QDeclarativeInstruction::StoreScriptString: - qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; + qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope << "\t" << instr->storeScriptString.bindingId; break; case QDeclarativeInstruction::AssignSignalObject: qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << datas.at(instr->assignSignalObject.signal); diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index d040967882..3db55a66d3 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -245,6 +245,8 @@ union QDeclarativeInstruction int propertyIndex; int value; int scope; + int bindingId; + ushort line; }; struct instr_storeScript { QML_INSTR_HEADER diff --git a/src/declarative/qml/qdeclarativescriptstring.cpp b/src/declarative/qml/qdeclarativescriptstring.cpp index f544393b9b..02d6e5603e 100644 --- a/src/declarative/qml/qdeclarativescriptstring.cpp +++ b/src/declarative/qml/qdeclarativescriptstring.cpp @@ -40,19 +40,10 @@ ****************************************************************************/ #include "qdeclarativescriptstring.h" +#include "qdeclarativescriptstring_p.h" QT_BEGIN_NAMESPACE -class QDeclarativeScriptStringPrivate : public QSharedData -{ -public: - QDeclarativeScriptStringPrivate() : context(0), scope(0) {} - - QDeclarativeContext *context; - QObject *scope; - QString script; -}; - /*! \class QDeclarativeScriptString \since 4.7 @@ -75,8 +66,8 @@ and the class could choose how to handle it. Typically, the class will evaluate the script at some later time using a QDeclarativeExpression. \code -QDeclarativeExpression expr(scriptString.context(), scriptString.script(), scriptStr.scopeObject()); -expr.value(); +QDeclarativeExpression expr(scriptString); +expr.evaluate(); \endcode \sa QDeclarativeExpression diff --git a/src/declarative/qml/qdeclarativescriptstring.h b/src/declarative/qml/qdeclarativescriptstring.h index 5408dd404d..5f3a2fe73f 100644 --- a/src/declarative/qml/qdeclarativescriptstring.h +++ b/src/declarative/qml/qdeclarativescriptstring.h @@ -75,6 +75,9 @@ public: private: QSharedDataPointer d; + + friend class QDeclarativeVME; + friend class QDeclarativeExpression; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativescriptstring_p.h b/src/declarative/qml/qdeclarativescriptstring_p.h new file mode 100644 index 0000000000..cd0cc43995 --- /dev/null +++ b/src/declarative/qml/qdeclarativescriptstring_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVESCRIPTSTRING_P_H +#define QDECLARATIVESCRIPTSTRING_P_H + +#include + +QT_BEGIN_NAMESPACE + +class QDeclarativeScriptStringPrivate : public QSharedData +{ +public: + QDeclarativeScriptStringPrivate() : context(0), scope(0), bindingId(-1), lineNumber(-1) {} + + QDeclarativeContext *context; + QObject *scope; + QString script; + int bindingId; + int lineNumber; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVESCRIPTSTRING_P_H diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index dd080a85e9..a9b303c94f 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -61,6 +61,7 @@ #include "private/qdeclarativeglobal_p.h" #include "private/qdeclarativeglobalscriptclass_p.h" #include "qdeclarativescriptstring.h" +#include "qdeclarativescriptstring_p.h" #include #include @@ -640,6 +641,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, ss.setContext(ctxt->asQDeclarativeContext()); ss.setScopeObject(scope); ss.setScript(primitives.at(instr.value)); + ss.d.data()->bindingId = instr.bindingId; + ss.d.data()->lineNumber = instr.line; void *a[] = { &ss, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 233359079d..5d56b300ba 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -129,6 +129,7 @@ HEADERS += \ $$PWD/qdeclarativeimport_p.h \ $$PWD/qdeclarativeextensionplugin.h \ $$PWD/qintrusivelist_p.h \ + $$PWD/qdeclarativescriptstring_p.h QT += sql include(parser/parser.pri) -- cgit v1.2.3 From 1cf2984ea74f837d4e8ae476dac2622f0a049eab Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 9 Jun 2011 12:10:03 +1000 Subject: Remove clock_gettime() library dependency. Should have been removed as part of cd6ebb4912a5d96c788ea0c838d8a1a06ff4029e. --- src/declarative/qml/qml.pri | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 5d56b300ba..a69d52c8dc 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -135,8 +135,3 @@ QT += sql include(parser/parser.pri) include(rewriter/rewriter.pri) include(v4/v4.pri) - -# clock_gettime() is implemented in librt on these systems -contains(QT_CONFIG, clock-gettime) { - linux-*|hpux-*|solaris-*:LIBS_PRIVATE *= -lrt -} -- cgit v1.2.3 From 1e3a1ead3ffad7d641e9fb7b3558349c512ef057 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 7 Jun 2011 13:58:39 +0200 Subject: Introduced simple material --- src/declarative/scenegraph/scenegraph.pri | 1 + .../scenegraph/util/qsgsimplematerial.h | 222 +++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 src/declarative/scenegraph/util/qsgsimplematerial.h (limited to 'src') diff --git a/src/declarative/scenegraph/scenegraph.pri b/src/declarative/scenegraph/scenegraph.pri index 77a93e4811..17370804a3 100644 --- a/src/declarative/scenegraph/scenegraph.pri +++ b/src/declarative/scenegraph/scenegraph.pri @@ -29,6 +29,7 @@ HEADERS += \ $$PWD/util/qsgareaallocator_p.h \ $$PWD/util/qsgengine.h \ $$PWD/util/qsgflatcolormaterial.h \ + $$PWD/util/qsgsimplematerial.h \ $$PWD/util/qsgsimplerectnode.h \ $$PWD/util/qsgsimpletexturenode.h \ $$PWD/util/qsgtexturematerial.h \ diff --git a/src/declarative/scenegraph/util/qsgsimplematerial.h b/src/declarative/scenegraph/util/qsgsimplematerial.h new file mode 100644 index 0000000000..810d89f224 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgsimplematerial.h @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSIMPLEMATERIAL_H +#define QSGSIMPLEMATERIAL_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +template +class QSGSimpleMaterialShader : public QSGMaterialShader +{ +public: + void initialize() { + QSGMaterialShader::initialize(); + + m_id_matrix = program()->uniformLocation(uniformMatrixName()); + if (m_id_matrix < 0) { + qFatal("QSGSimpleMaterialShader does not implement 'uniform highp mat4 %s;' in its vertex shader", + uniformMatrixName()); + } + + const char *opacity = uniformOpacityName(); + if (opacity) { + m_id_opacity = program()->uniformLocation(uniformOpacityName()); + if (m_id_opacity < 0) { + qFatal("QSGSimpleMaterialShader does not implement 'uniform lowp float %s' in its fragment shader", + uniformOpacityName()); + } + } else { + m_id_opacity = -1; + } + + resolveUniforms(); + } + + const char *uniformMatrixName() const { return "qt_ModelViewProjectionMatrix"; } + const char *uniformOpacityName() const { return "qt_Opacity"; } + + void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); + + virtual void updateState(const State *newState, const State *oldState) = 0; + + virtual void resolveUniforms() {} + + virtual QList attributes() const = 0; + + char const *const *attributeNames() const + { + if (m_attribute_pointers.size()) + return m_attribute_pointers.constData(); + + QList names = attributes(); + + // Calculate the total number of bytes needed, so we don't get rellocs and + // bad pointers while copying over the individual names. + // Add an extra byte pr entry for the '\0' char. + int total = 0; + for (int i=0; i m_attribute_pointers; +}; + +#define QSG_DECLARE_SIMPLE_SHADER(Shader, State) \ +static QSGMaterialShader *createShader() \ +{ \ + return new Shader; \ +} \ +public: \ +static QSGSimpleMaterial *createMaterial() \ +{ \ + return new QSGSimpleMaterial(createShader); \ +} + + +typedef QSGMaterialShader *(*PtrShaderCreateFunc)(); + + +template +class QSGSimpleMaterial : public QSGMaterial +{ + +public: + QSGSimpleMaterial(const State &state, PtrShaderCreateFunc func) + : m_state(state) + , m_func(func) + { + } + + QSGSimpleMaterial(PtrShaderCreateFunc func) + : m_func(func) + { + } + + QSGMaterialShader *createShader() const { return m_func(); } + QSGMaterialType *type() const { return &m_type; } + + State *state() { return &m_state; } + const State *state() const { return &m_state; } + +private: + static QSGMaterialType m_type; + State m_state; + PtrShaderCreateFunc m_func; +}; + +#define QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(Shader, State) \ +static QSGMaterialShader *createShader() \ +{ \ + return new Shader; \ +} \ +public: \ +static QSGSimpleMaterialComparableMaterial *createMaterial() \ +{ \ + return new QSGSimpleMaterialComparableMaterial(createShader); \ +} + +template +class QSGSimpleMaterialComparableMaterial : public QSGSimpleMaterial +{ + +public: + QSGSimpleMaterialComparableMaterial(const State &state, PtrShaderCreateFunc func) + : QSGSimpleMaterial(state, func) {} + + QSGSimpleMaterialComparableMaterial(PtrShaderCreateFunc func) + : QSGSimpleMaterial(func) {} + + int compare(const QSGMaterial *other) const { + return QSGSimpleMaterialComparableMaterial::state()->compare(static_cast *>(other)->state()); + } +}; + + +template +QSGMaterialType QSGSimpleMaterial::m_type; + + +template +Q_INLINE_TEMPLATE void QSGSimpleMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + if (state.isMatrixDirty()) + program()->setUniformValue(m_id_matrix, state.combinedMatrix()); + if (state.isOpacityDirty() && m_id_opacity >= 0) + program()->setUniformValue(m_id_opacity, state.opacity()); + + State *ns = static_cast *>(newMaterial)->state(); + State *old = 0; + if (oldMaterial) + old = static_cast *>(oldMaterial)->state(); + updateState(ns, old); +} + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif -- cgit v1.2.3 From 283a37447b8c400957c4da7dda35a84ea86ac4ad Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 9 Jun 2011 15:17:52 +1000 Subject: Automatically set system if parent is a ParticleSystem --- src/declarative/particles/qsgparticleaffector.cpp | 2 ++ src/declarative/particles/qsgparticleemitter.cpp | 2 ++ src/declarative/particles/qsgparticlepainter.cpp | 4 +++- src/declarative/particles/qsgparticlesystem.cpp | 10 ++++++++-- src/declarative/particles/qsgparticlesystem_p.h | 1 + 5 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/declarative/particles/qsgparticleaffector.cpp b/src/declarative/particles/qsgparticleaffector.cpp index d4b588a44f..96c5cfb25b 100644 --- a/src/declarative/particles/qsgparticleaffector.cpp +++ b/src/declarative/particles/qsgparticleaffector.cpp @@ -56,6 +56,8 @@ QSGParticleAffector::QSGParticleAffector(QSGItem *parent) : void QSGParticleAffector::componentComplete() { + if(!m_system && qobject_cast(parentItem())) + setSystem(qobject_cast(parentItem())); if(!m_system) qWarning() << "Affector created without a particle system specified";//TODO: useful QML warnings, like line number? QSGItem::componentComplete(); diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp index c04c86cfe5..20f3c6bb4b 100644 --- a/src/declarative/particles/qsgparticleemitter.cpp +++ b/src/declarative/particles/qsgparticleemitter.cpp @@ -76,6 +76,8 @@ QSGParticleEmitter::~QSGParticleEmitter() void QSGParticleEmitter::componentComplete() { + if(!m_system && qobject_cast(parentItem())) + setSystem(qobject_cast(parentItem())); if(!m_system) qWarning() << "Emitter created without a particle system specified";//TODO: useful QML warnings, like line number? QSGItem::componentComplete(); diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp index 8814c61b56..a5e8c0a3e6 100644 --- a/src/declarative/particles/qsgparticlepainter.cpp +++ b/src/declarative/particles/qsgparticlepainter.cpp @@ -54,8 +54,10 @@ QSGParticlePainter::QSGParticlePainter(QSGItem *parent) : void QSGParticlePainter::componentComplete() { + if(!m_system && qobject_cast(parentItem())) + setSystem(qobject_cast(parentItem())); if(!m_system) - qWarning() << "Particle created without a particle system specified";//TODO: useful QML warnings, like line number? + qWarning() << "ParticlePainter created without a particle system specified";//TODO: useful QML warnings, like line number? QSGItem::componentComplete(); } diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp index a2aa377c82..4a8f75bb04 100644 --- a/src/declarative/particles/qsgparticlesystem.cpp +++ b/src/declarative/particles/qsgparticlesystem.cpp @@ -67,7 +67,9 @@ QSGParticleData::QSGParticleData() } QSGParticleSystem::QSGParticleSystem(QSGItem *parent) : - QSGItem(parent), m_particle_count(0), m_running(true) , m_startTime(0), m_overwrite(false) + QSGItem(parent), m_particle_count(0), m_running(true) + , m_startTime(0), m_overwrite(false) + , m_componentComplete(false) { m_groupIds = QHash(); } @@ -111,7 +113,9 @@ void QSGParticleSystem::setRunning(bool arg) void QSGParticleSystem::componentComplete() { QSGItem::componentComplete(); - reset(); + m_componentComplete = true; + if(!m_emitters.isEmpty() && !m_particles.isEmpty()) + reset(); } void QSGParticleSystem::initializeSystem() @@ -191,6 +195,8 @@ void QSGParticleSystem::initializeSystem() void QSGParticleSystem::reset() { + if(!m_componentComplete) + return;//Batch starting reset()s a little //Clear guarded pointers which have been deleted int cleared = 0; cleared += m_emitters.removeAll(0); diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h index aab3c5d50f..9730ff35e8 100644 --- a/src/declarative/particles/qsgparticlesystem_p.h +++ b/src/declarative/particles/qsgparticlesystem_p.h @@ -163,6 +163,7 @@ private: qint64 m_startTime; int m_nextGroupId; bool m_overwrite; + bool m_componentComplete; }; //TODO: Clean up all this into ParticleData -- cgit v1.2.3