Results 1 to 15 of 15

Thread: turn off collision detection?

  1. #1
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default turn off collision detection?

    Hello,

    I'm working with PyQt4.4, and I'm looking for any means to turn off collision detection in the QGraphicsView infrastructure.

    I'm loading hundreds of thousands of objects that I've reimplemented collision detection for. Its really fast except for tons and tons of .boundingRect() calls to my QGraphicsItem objects. I'm setting the sceneRect myself too, so I don't think these boundingRect() calls are necessary for any reason. Is there some way to turn them off?

    Thanks much,

    Deacon Sweeney

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: turn off collision detection?

    boundingRect() is necessary for the architecture to know which items to repaint when a particular area needs refreshing. It also defines a local coordinate system for each item, so unless you want to strip away everything the graphics view gives you (I mean all the benefits), it will be hard to get rid of boundingRect() and collision detection. On the other hand if you want to get rid of them, maybe you shouldn't use graphics view at all?

  3. The following user says thank you to wysota for this useful post:

    Deacon (2nd November 2008)

  4. #3
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    Hi wysota, thanks for your response.

    > boundingRect() is necessary for the architecture to know which items to repaint when a
    > particular area needs refreshing.

    I already know which QGItems I need to repaint, and I've tried to force to update just the boundingRect of these items, through QGraphicsItem.update(QRect) and QGraphicsScene.update(QRect) calls. But I still encounter an onslaught of unnecessary boundingRect() calls, that kill my performance.

    > It also defines a local coordinate system for each item,
    > so unless you want to strip away everything the graphics view gives you (I mean all
    > benefits), it will be hard to get rid of boundingRect() and collision detection.

    So each QGraphicsItem.paint() call requires a boundingRect() call. I can dig that because I can tell the QGraphicsView framework which areas to repaint. Going back to my .update() use above, I'm still not clear why the .update(QRect) function can not just redefine the local coordinate system starting at the .x() .y() of the QRect I pass to .update(). Can I just repaint that QRect another way? is there some other intended functionality of applying this parameter to the update function?

    > On the other
    > hand if you want to get rid of them, maybe you shouldn't use graphics view at all?

    I disagree completely. There's lots of great stuff under the hood, that Indexing seems to kill the performance of when more than a few tens of thousands of QGraphicsItems are present in the scene. So an option is offered to turn indexing off, but no option to reimplement where to repaint? It just seems like not a very big step to uncover some real performance flexibility.

    Thanks again for your time.

    Deacon
    Last edited by Deacon; 2nd November 2008 at 16:40.

  5. #4
    Join Date
    May 2006
    Location
    Germany
    Posts
    108
    Thanks
    2
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: turn off collision detection?

    According to the docs it is possible to specify the following in order to prevent QGraphicsView from doing collision detection:

    Qt Code:
    1. myView.setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
    To copy to clipboard, switch view to plain text mode 

    Or am I misunderstanding something here? :-)
    "If you lie to the compiler, it will get its revenge." - Henry Spencer

  6. The following user says thank you to Methedrine for this useful post:

    Deacon (3rd November 2008)

  7. #5
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    Thanks Methedrine, so that gets rid of my boundingRect() calls, but I had discounted this approach because it also kills the repaint function for QGraphicItem objects that I've called .update() on.

    I thought I might be able to apply the scene.invalidate() functions, but I still have to call QGraphicsScene.update() after each to get graphics updates, which ends up calling .boundingRect the same absurd number of times as when ViewportUpdate is on.

    Is there another way to update just a single QRectF when indexing and viewportUpdate are both turned off?

    Thanks,

    Deacon

  8. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: turn off collision detection?

    Quote Originally Posted by Deacon View Post
    Hi wysota, thanks for your response.

    > boundingRect() is necessary for the architecture to know which items to repaint when a
    > particular area needs refreshing.

    I already know which QGItems I need to repaint, and I've tried to force to update just the boundingRect of these items, through QGraphicsItem.update(QRect) and QGraphicsScene.update(QRect) calls. But I still encounter an onslaught of unnecessary boundingRect() calls, that kill my performance.
    The fact that you update some part of the view doesn't mean all items present there get repainted.That's where the bounding rect comes in. The view tracks regions that have been changed and repaints only those items that intersect the region. If you disable automatic updates, you have to do all the updating stuff yourself (including calling the painting routine of each item you want painted).

    If you move items often, it might be good for you to disable indexing, maybe that is what is degrading your performance.


    > It also defines a local coordinate system for each item,
    > so unless you want to strip away everything the graphics view gives you (I mean all
    > benefits), it will be hard to get rid of boundingRect() and collision detection.

    So each QGraphicsItem.paint() call requires a boundingRect() call.
    No. But anyway it's good to cache the bounding rect instead of calculating it during every call to this method.

    I can dig that because I can tell the QGraphicsView framework which areas to repaint. Going back to my .update() use above, I'm still not clear why the .update(QRect) function can not just redefine the local coordinate system starting at the .x() .y() of the QRect I pass to .update().
    The local coordinate system has nothing to do with the area you repaint.

    Can I just repaint that QRect another way?
    Yes, you can call the paint routine of each item occupying that area yourself. Before doing that you'll have to provide necessary transformations for the painter to reflect the proper coordinate system.

    > On the other
    > hand if you want to get rid of them, maybe you shouldn't use graphics view at all?

    I disagree completely. There's lots of great stuff under the hood, that Indexing seems to kill the performance of when more than a few tens of thousands of QGraphicsItems are present in the scene. So an option is offered to turn indexing off, but no option to reimplement where to repaint? It just seems like not a very big step to uncover some real performance flexibility.
    What great stuff are we talking about? Most "great stuff" in graphics view concerns determining what to repaint

    What exactly is your usecase? How come do you think you know better what to repaint than the GV architecture? Could you explain this?

  9. #7
    Join Date
    May 2006
    Location
    Germany
    Posts
    108
    Thanks
    2
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: turn off collision detection?

    Quote Originally Posted by Deacon View Post
    Thanks Methedrine, so that gets rid of my boundingRect() calls, but I had discounted this approach because it also kills the repaint function for QGraphicItem objects that I've called .update() on.

    I thought I might be able to apply the scene.invalidate() functions, but I still have to call QGraphicsScene.update() after each to get graphics updates, which ends up calling .boundingRect the same absurd number of times as when ViewportUpdate is on.

    Is there another way to update just a single QRectF when indexing and viewportUpdate are both turned off?

    Thanks,

    Deacon
    Why are you calling update on the QGraphicItems by yourself, if I may ask? What are you trying to achieve? You could certainly create a smaller scene from your already pre-processed QGraphicItems, but to me it currently sounds like you are actually re-inventing QGraphicsView then.
    "If you lie to the compiler, it will get its revenge." - Henry Spencer

  10. #8
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    Quote Originally Posted by wysota View Post
    The fact that you update some part of the view doesn't mean all items present there get repainted.That's where the bounding rect comes in. The view tracks regions that have been changed and repaints only those items that intersect the region. If you disable automatic updates, you have to do all the updating stuff yourself (including calling the painting routine of each item you want painted).

    If you move items often, it might be good for you to disable indexing, maybe that is what is degrading your performance.
    So I have to actually call the paint() function, and not rely on .update() or .invalidate() because all that stuff is turned off. Ok.

    Quote Originally Posted by wysota View Post
    Yes, you can call the paint routine of each item occupying that area yourself. Before doing that you'll have to provide necessary transformations for the painter to reflect the proper coordinate system.

    What exactly is your usecase? How come do you think you know better what to repaint than the GV architecture? Could you explain this?
    Sure, its a panel of tiles that wrap the window with window resizes. I could have gotten away with the QTableView but I was worried that it's not quite as flexible as the GV system.

  11. #9
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    Quote Originally Posted by Methedrine View Post
    Why are you calling update on the QGraphicItems by yourself, if I may ask? What are you trying to achieve? You could certainly create a smaller scene from your already pre-processed QGraphicItems, but to me it currently sounds like you are actually re-inventing QGraphicsView then.
    I'm just trying to improve performance by limiting graphical updates to the items, which know when they need updated. When I allow scene.update() to do the job it goes through thousands of .boundingRect() calls, making any dynamic interaction with the screen take at least half of a second. Yes it is definitely reinventing much of QGV but its done already so I guess Ijust have to force paint() calls to make this work.

  12. #10
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Thumbs up Re: turn off collision detection?

    [Weeks Later...]



    [QUOTE=Deacon;84597] So I have to actually call the paint() function, and not rely on .update() or .invalidate() because all that stuff is turned off. Ok.



    Qt 4 issues warnings when the paint function is called outside of a paintEvent, so this approach did not work for me and I've found a better way.


    I've recently discovered two rendering commands that DO work even when setViewportUpdateMode .( QtGui.QGraphicsView. NoViewportUpdate ) has been called; qgrapics_view_object.viewport().update() and .viewport().repaint(x, y, w, h)... I've so far found these to offer a very efficient alternative to the build-in paint event handling for some must-be-immediate events. This applies mostly because of my somewhat unusual situation where I can (and must) be able to recalculate those numbers pretty quickly.

    Just thought I'd share back a little.

  13. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: turn off collision detection?

    Correct me if I'm wrong, but calling update() or repaint() on the graphics view's viewport is intercepted by the graphics view using an event filter and redirected to the usual graphics view update mechanism...

  14. #12
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    Quote Originally Posted by wysota View Post
    Correct me if I'm wrong, but calling update() or repaint() on the graphics view's viewport is intercepted by the graphics view using an event filter and redirected to the usual graphics view update mechanism...
    seems like GV.viewport().update() reroutes back to the usual update system. I just was not previously aware of anything that renders when NoViewportUpdates is on. Only under the NoViewportUpdate setting does my CPU to not grind away at 50% the whole time my app is running.


    .repaint() I'm pretty sure does not go through .update().

    in __init__():

    self.setViewportUpdateMode(QtGui.QGraphicsView.NoV iewportUpdate)


    then in my QGraphicsItem:

    def updateNow(self):
    b = self.bRect
    self.parent.viewport().repaint(b.x(), b.y(), b.width(), b.height())

    works. So I guess its not going through the normal update() mechanism.

    Is this not the way its supposed to be?

    Deacon

  15. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: turn off collision detection?

    The only difference between update() and repaint() should be the former uses QCoreApplication::postEvent() to post a paint event and the latter uses QCoreApplication::sendEvent() to execute the same event without going through the event queue. So the result in both cases should be identical with the only difference that update() makes a deferred call and repaint() forces an immediate redraw.

  16. The following user says thank you to wysota for this useful post:

    Deacon (30th December 2008)

  17. #14
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    and that is why .repaint works while viewport updates are turned off. That makes sense. Thanks for clarifying.
    Last edited by Deacon; 30th December 2008 at 17:41. Reason: reformatted to look better

  18. #15
    Join Date
    Oct 2008
    Posts
    14
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: turn off collision detection?

    Last edited by Deacon; 30th December 2008 at 17:42.

Similar Threads

  1. 2D Race Car collision detection
    By neonnds in forum Qt Programming
    Replies: 0
    Last Post: 6th July 2008, 08:10
  2. Collision detection QGraphicsItem
    By Blade in forum Qt Programming
    Replies: 5
    Last Post: 5th January 2007, 10:20
  3. Painting and collision detection
    By aamer4yu in forum Qt Programming
    Replies: 1
    Last Post: 18th October 2006, 08:57

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.