I am writing a GUI that is supposed to display entities of a system in a 2D coordinate system, which the user can select and drag around. The system is mirror-symmetric w.r.t. the x and y axes. Currently I am subclassing an entity using a QGraphicsRectItem so that I can drag it around in the first quadrant (x>0, y>0) of the coordinate system. I reimplemented the paint method to draw the other three additional rectangles with painter.drawRectangle(). So when I move the entity in quadrant 1, the elements in the other three quadrants perform mirror motions. That works well.
In the next stage, each entity can be subdivided, i.e. consist of hundreds of rectangles. So I need to draw hundreds of rectangles and that four times, with mirror operations. The naive approach takes four for-loops, but I'm wondering if there is a smarter way of doing this in QT. The for-loops hurt a little because I'm using PyQt.
If your drawing operations are so slow the simplest thing you could do is draw to an image, and then simply draw the cached painting from the image 4 times, which will be very fast, since it will just be copying some pixel values.
It might be efficient to cache the drawing result not on item basis but to cache a quadrant of your grid. This way if you zoom in and the items get huge or numerous in count, you won't be wasting lots of memory, instead you will only need one image cache that's the screen size of the quadrant.
It really depends what you want to achieve, which at this point is not entirely clear from the description, and your image isn't showing neither.
Related
I'm trying to write my own CAD program, and it's pretty important that I give the user the ability to select vertices/edges/faces(triangles) of interest by drawing a box or polygon on a 2D screen, and then highlighting whatever is underneath in the 3D view (both ignoring the back faces and also not ignoring the back faces).
How is this done usually? Is there any open-source example I can look at? What's generally the process for this?
This is especially harder when you are trying to handle 1 million+ triangles.
there are many ways to do this here two most often used:
Ray picking
First see:
OpenGL 3D-raypicking with high poly meshes
The idea is to cast a ray(s) from camera focal point into mouse (or cursor) direction and what the ray hits is selected. The link above exploits OpenGL rendering where you can do this very easily and fast (almost for free) and the result is pixel perfect. In order to use selecting box/polygon you need to read all of its pixels on CPU side and convert them to list of entities selected. This is slightly slower but still can be done very fast (regardless of complexity of the rendered scene). This approach is O(1) however if you do the same on CPU it will be much much slower with complexity O(n) while n is number of entities total (unless BVH or is Octree used). This method however will select only what is visible (so no back faces or objects behind).
Geometry tests
Basicaly your 2D rectangle will slice the perspective 3D frustrum to smaller one and what is inside or intersecting should be selected. You can compute this with geometry on CPU side in form of tests (object inside cuboid or box) something like this:
Cone to box collision
The complexity is also O(n) unless BVH or Octree is used. This method will select all objects (even not visible ones).
Also I think this might be interesting reading for you:
simple Drag&Drop in C++
It shows a simple C++ app architecture able of placing and moving objects in 2D. Its a basic start point for CAD like app. For 3D you just add the matrix math and or editation controls...
Also a hint for selecting in CAD/CAM software (IIRC AUTOCAD started with) is that if your selection box was created from left to right and from top to bottom manner you select all objects that are fully inside or intersect and if the selection box was created in reverse direction you select only what is fully inside. This way allows for more comfortable editation.
Let's say I have a static object and a movable object which can be moved and rotated, what is the best way to very quickly calculate the difference of those two meshes?
Precision here is not so important, speed is though, since I have to use it in the update phase of the main loop.
Maybe, given the strict time limit, modifying the static object's vertices and triangles directly is to be preferred. Should voxels be preferred here instead?
EDIT: The use case is an interactive viewer of a wood panel (parallelepiped) and a milling tool (a revolved contour, some like these).
The milling tool can be rotated and can work oriented at varying degrees (5 axes).
EDIT 2: The milling tool may not pierce the wood.
EDIT 3: The panel can be as large as 6000x2000mm and the milling tool can be as little as 3x3mm.
If you need the best possible performance then the generic CSG approach may be too slow for you (but still depending on meshes and target hardware).
You may try to find some specialized algorithm, coded for your specific meshes. Let's say you have two cubes - one is a 'wall' and second is a 'window' - then it's much easier/faster to compute resulting mesh with your custom code, than full CSG. Unfortunately you don't say anything about your meshes.
You may also try to make it a 2D problem, use some simplified meshes to compute the result that will 'look like expected'.
If the movement of your meshes is somehow limited you may be able to precompute full or partial results for different mesh combinations to use at runtime.
You may use some space partitioning like BSP or Octrees to divide your meshes during precomputing stage. This way you could split one big problem into many smaller ones that may be faster to compute or at least to make the solution multi-threaded.
You've said about voxels - if you're fine with their look and limits you may voxelize both meshes and just read and mix two voxel values, instead of one. Then you would triangulate it using algorithm like Marching Cubes.
Those are all just some general ideas but we'll need better info to help you more.
EDIT:
With your description it looks like you're modeling some bas-relief, so you may use Relief Mapping to fake this effect. It's based on a height map stored as a texture, so you'd need to just update few pixels of the texture and render a plane. It should be quite fast compared to other approaches, the downside is that it's based on height map, so you can't get shapes that Tee Slot or Dovetail cutter would create.
If you want the real geometry then I'd start from a simple plane as your panel (don't need full 3D yet, just a front surface) and divide it with a 2D grid. The grid element should be slightly bigger than the drill size and every element is a separate mesh. In the frame update you'd cut one, or at most 4 elements that are touched with a drill. Thanks to this grid all your cutting operations will be run with very simple mesh so they may work with your intended speed. You can also cut all current elements in separate threads. After the cutting is done you'll upload to the GPU only currently modified elements so you may end up with quite complex mesh but small modifications per frame.
I'm running a simple sketch in an HTML5 canvas using Processing.js that creates "ball" objects which are just ellipses that have position, speed, and acceleration vectors as well as a diameter. In the draw function, I call on a function called applyPhysics() which loops over each ball in a hashmap and checks them against each other to see if their positions make them crash. If they do, their speed vectors are reversed.
Long story short, the number of calculations as it is now is (number of balls)^2 which ends up being a lot when I get to into the hundreds of balls. Using this sort of check slows down the sketch too much so I'm looking for ways to do smart collisions some other way.
Any suggestions? Using PGraphics somehow maybe?
I assume you're already simplifying the physics by treating the ellipses as if they were circles.
Other than that, check out quadtree collision detection:
http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/
I don't know your project, but if the balls have non-random forces applied to them (e.g. gravity) you might use predictive analytics also.
If you grid the space and create a data structure that reflects this (e.g. an array of row objects each containing an array of column objects each containing an ArrayList of ball objects), you can just consider interactions within each cell (or also with neighbouring cells). You can reassign data location for balls that cross boundaries. You then have far fewer interactions.
In my opengl app, I am drawing the same polygon approximately 50k times but at different points on the screen. In my current approach, I do the following:
Draw the polygon once into a display list
for each instance of the polygon, push the matrix, translate to that point, scale and rotate appropriate (the scaling of each point will be the same, the translation and rotation will not).
However, with 50k polygons, this is 50k push and pops and computations of the correct matrix translations to move to the correct point.
A coworker of mine also suggested drawing the entire scene into a buffer and then just drawing the whole buffer with a single translation. The tradeoff here is that we need to keep all of the polygon vertices in memory rather than just the display list, but we wouldn't need to do a push/translate/scale/rotate/pop for each vertex.
The first approach is the one we currently have implemented, and I would prefer to see if we can improve that since it would require major changes to do it the second way (however, if the second way is much faster, we can always do the rewrite).
Are all of these push/pops necessary? Is there a faster way to do this? And should I be concerned that this many push/pops will degrade performance?
It depends on your ultimate goal. More recent OpenGL specs enable features for "geometry instancing". You can load all the matrices into a buffer and then draw all 50k with a single "draw instances" call (OpenGL 3+). If you are looking for a temporary fix, at the very least, load the polygon into a Vertex Buffer Object. Display Lists are very old and deprecated.
Are these 50k polygons going to move independently? You'll have to put up with some form of "pushing/popping" (even though modern scene graphs do not necessarily use an explicit matrix stack). If the 50k polygons are static, you could pre-compile the entire scene into one VBO. That would make it render very fast.
If you can assume a recent version of OpenGL (>=3.1, IIRC) you might want to look at glDrawArraysInstanced and/or glDrawElementsInstanced. For older versions, you can probably use glDrawArraysInstancedEXT/`glDrawElementsInstancedEXT, but they're extensions, so you'll have to access them as such.
Either way, the general idea is fairly simple: you have one mesh, and multiple transforms specifying where to draw the mesh, then you step through and draw the mesh with the different transforms. Note, however, that this doesn't necessarily give a major improvement -- it depends on the implementation (even more than most things do).
I am developing a simple tile-based 2D game. I have a level, populated with objects that can interact with the tiles and with each other. Checking collision with the tilemap is rather easy and it can be done for all objects with a linear complexity. But now I have to detect collision between the objects and now I have to check every object against every other object, which results in square complexity.
I would like to avoid square complexity. Is there any well-known methods to reduce collision detection calls between objects. Are there any data-structures (like BSP tree maybe), which are easily maintained and allow to reject many collisions at a time.
For example, the total number of objects in the level is around 500, about 50 of them are seen on screen at a time...
Thanks!
Why don't you let the tiles store information about what objects occupy them. Then collisions can be detected whenever an object is moved to a new tile, by seeing if that tile already contains another object.
This would cost virtually nothing.
You can use quadtree to divide the space and reduce the number of objects you need to check for collision.
See this article - Quadtree demonstration.
And perhaps this - Collision Detection in Two Dimensions.
Or this - Quadtree (source included)
It may seem - at first glance - that it takes a lot of CPU power to maintain the tree, but it also reduces the number of checks significantly (see the demonstration in th first link).
Your game already has the concept of a gameplay-related tilemap. You can either co-opt this tilemap for collision detection, or overlay a secondary grid over your playing field used specifically for sprite tracking and collision detection.
Within your grid, each sprite occupies one or more tiles. The sprite knows which tiles it occupies, and the tiles know which sprites occupy it. When a sprite moves, you only need to check for collisions within the tiles that the sprite occupies. This means no collision detection is necessary at all unless sprites are close enought to occupy the same tiles, and even then, you only need to check for collisions between the sprites that are close together.
If your gameplay is such that sprites will frequently clump together, you may want to implement your grid as a quadtree to allow each tile to be subdivided and prevent too many sprites from occupying the same grid tile.
Also, depending on your implementation, you may need to use a slightly larger bounding box to determine tile occupancy than you use to determine collisions. That way you'll be guaranteed that the sprites will overlap and occupy the same tile before their collision boundaries touch.