1
\$\begingroup\$

I would like to understand how to calculate coordinates of boundaries group of objects as a parallelepiped in 3D game?

Let's say for simplicity we have spheres randomly slowly moving in 3d space some of them cross each other from time to time and forming groups from 2 or more object locating very close to each other. Now I need to create dynamic parallelepiped surrounding this formed group as long as this group still formed because spheres moving constantly and such groups may appear and disappear chaotically.

So how to calculate coordinates of this parallelepiped faster? The naive approach I was thinking is just calculate distance of each object from each other individually to know to which group each sphere belongs which is slow O(n^2) time complexity. Is there more efficient solution to solve this problem?

Sorry if already similar question answered. I couldn't find answer to my question so far.

\$\endgroup\$
2
  • \$\begingroup\$ I know the physics engine ODE uses a "hashspace" strategy to detect collisions. I can't write a full answer now, and if you don't get any, that could help you get started. \$\endgroup\$
    – Vaillancourt
    Commented Jun 6, 2021 at 10:30
  • \$\begingroup\$ It's not clear to me whether your problem is in identifying the groups in the first place (which looks like a clustering problem you could solve with a modified Kruskal's algorithm and a spatial partition), or in determining the parallelepiped coordinates once you have such a group. Also, can we substitute "axis aligned bounding box (AABB)" instead? "Parallelipiped" is a much broader class of shape that can include shearing (where corners are not 90°), and we don't usually use that full generality in bounds checks. \$\endgroup\$
    – DMGregory
    Commented Jun 6, 2021 at 11:14

1 Answer 1

2
\$\begingroup\$

This is a broad question, so a broad answer is required. You can follow up individual implementations / algorithms yourself, and post separate questions if you need to.

The basic approach for games

Create some sort of grid in space. This grid can be either:

  • flat (literally, a 2D grid or 3D grid)
  • hierarchical (2D: quadtree or bounding box hierarchy, 3D: octree or bounding volume hierarchy)

These are implemented as an array of containers. Hierarchical grids are arrays of containers of arrays of containers, ad nauseam, down the tree.

For now let us focus on flat structures, as these are easier to conceptualise.

enter image description here

Each grid cell or "bucket" groups a set of bodies. This approach is simple and generally works well enough in most cases, and I would recommend it as a starting point for beginners. We determine (naively) whether a body is within a cell as follows:

for each body
    get xmin and xmax for this body
    xcentre = xmin + (xmax - xmin) / 2
    find the cell which holds this body:
    xcell = xcentre / numcols //integer division, round down (in this case, numcols=4)

    repeat for y (and if in 3D, also for z).

So in the case of our bottom-most point in the image above, cx == 1 and cy == 3 (remember this is zero-based, so cols and rows each run 0-3).

Thus the boxes or volumes that we use to contain bodies, are defined by a fixed, repeating grid. Note also that the size of the cells are directly influenced by the size of the bodies they can contain. Too small, and you will not create good-sized clusters; too large, and you may not get enough reduction in the number of body-body checks.

Problems, and more advanced approaches

A problem arises in pathological cases like this:

enter image description here

...This will be less than optimal since we'd ideally have liked the four red bodies, and maybe even the orange one, grouped together. This way we'd have only had to process one bucket instead of four, which would have reduced processing costs.

This can also happen in a quadtree, which is also defined by a fixed grid structure (quadtrees are otherwise much more performant for large numbers of bodies, than flat grids):

enter image description here

Where such pathological cases are of crucial importance, e.g. they are a performance bottleneck, we prefer something that clusters more dynamically. A graph connectivity approach such as Kruskal's Spanning Tree Algorithm which DMGregory mentioned, or any other which creates a dynamic, connected clustering. If a maximum edge distance is used, long edges are eliminated, dividing output into localised subgraphs / clusters:

enter image description here

Or we can use an iterative classification method such as K-means clustering, which again creates dynamic groupings with no regard to rigid boundaries:

enter image description here

(K-means animation attributed to Chire under Creative Commons)

Once we have clustered using e.g. K-means or Kruskal's, we can use these clusterings to determine bounding box or volume limits. We could also use this as an input to a flexible bounding volume hierarchy (actually area, not volume, in 2D). There are countless ways to subdivide the space, but only a few that cluster efficiently, it all depends on the use case. This shows a space-filling bounds structure vs a sparse structure:

enter image description here

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .