Detecting 3D enclosed/sealed space

  1. What do you want to achieve? I’m making game about space. Player can build space ships out of parts. And I want to make realistic air supply. Quite common solution it to just make “bubble” of air, and players inside that bubble can breathe, otherwise no. This solution is used in, for example, Waste of Space. However, this is very unrealistic. Player can go outside of ship, and will still be able to breathe. On the other hand, such solution is really performant.

  2. What is the issue? I’m thinking about best method to calculate if player is in enclosed space, and there is active air supply.

  3. What solutions have you tried so far? I through about few solutions:

    • Do 6 (or more) raycasts from player’s character’s position. If all of those will reach parts, then consider this space as enclosed. And check distance from nearest air supply. However, this isn’t fully realistic. There is possibility that there is hole in ship, but not in any of those rays. Also air supply may be in another enclosed room. This would be rather performant.
    • Similar to above, but with one difference: player and air supply must be in line-of-sight. However, this would not work in maze-like constructions. This also should be performant
    • Use some kind of flood fill algorithm in 3D voxel space. Flooding would start from air supply, and after reaching some limit of flooded voxels, algorithm would stop and consider space as not-enclosed. Otherwise, if algorithm would flood all available voxels, and wouldn’t reach limit, then consider space as enclosed. If player is in one of those voxels, then let him breathe. However, this would be quite computation-expensive. I would need to set balanced voxel size. The bigger voxels, the faster algorithm, but less realistic results. The smaller volxels, the slower algorithm, but more realistic results. Maybe 2x2x2 or 4x4x4 would be good. Also in such solution, enclosed space needs to be recomputed sometimes, because ships are “dynamic” - they can be damaged, have moving parts, or just be edited by player. Recomputing it would be computation-intensive, so it cannot be done, for example, every second. It should be done only after updating ship structure.

What do you think? Which solution should I use? I want to make my game rather realistic, but not too laggy. Or maybe you’ve got better, more performant solution?

I found some topics about finding enclosed space, but most of them are only 2D, and I need 3D.

I hope you’ll give me some advice.

1 Like

Greetings!
I’ll try to suggest some available methods for you to achieve your goal.

But first, some background questions id love to hear:

  • What kind of “gap” sizes are you expecting in the game? If they get to the micro level of 0.01x0.01x0.01 then I believe no solution would be performant enough.
  • How complex do the space interiors get?

Efficiency tip
only do the calculations when you believe something changed in the room
doing it every second or so would be useless and performance eating
for better results id even do it on the client, because if you expect a lot of people to play your game, there’s no way the server would keep up.

with the background I’ve been provided here are my suggestions:

Having some “fake” cubes the size of 2x2x2 ish spread around the room checking if they are touching any wall would be your best bet for accuracy. These cubes could spread from the “air supply”. This would of course lead to some gaps going under the radar, and I’m not sure how well this would work on a moving ship, but I believe it’s possible with some testing.

How to make it more accurate?
If you want to be 100% sure that there is no tiny gap in the middle of the square you could even do some cube scaling:

  1. Start with let’s say 10x10x10 cubes
  2. Spread the cubes around the space
  3. If they are touching something, slice the cube (that is touching something) into smaller cubes (like 5x5x5)
  4. Start spreading all the smaller cubes around the space
  5. If they are touching something, slice the cube (that is touching something) into smaller cubes again
  6. Repeat till you are happy with the performance & result

To improve efficiency even further, id make any decorative furniture not get in the way of collisions and only look at the walls (this depends on your interior and design of the game tho)

Of course, cubes could just be Region3 chunks or something along those lines.

I believe there are probably better methods of achieving this (maybe checking for gaps from the outside via raycasts?) But from current known info about your game, this is probably your best bet (that I could think of).

Hope this helped.

4 Likes

Thank you for quick answer!

Small details and holes don’t matter in this game. Room with small hole (for example 0.2x0.2) could be considered as enclosed.

As you said, using cubes (e.g. 2x2x2) any checking if they collide with walls seems to be best solution.

After destroying some parts, or moving/resizing them by player, recomputing air-filled area will be triggered. However, when multiple such events occur in short period of time, recomputing shouldn’t happen too often. And it must happen at end of series of those events. So I’ll add some kind of cooldown. If one of those events occurs, schedule recomputation for, for example, 5s (or maybe less, if performance won’t be bad). Next events within those 5s period will be ignored. After that period, events will again schedule recomputations.

Probably I won’t use your suggestion to make it more accurate, because it isn’t as important.

Also, ships in this game can move. So I think that those “air-cubes” will be just welded to air supply (and thus to whole ship). Thanks to it, just moving a ship won’t need to recompute air-filled area.

1 Like

Happy that I could help!
Checked out your game, looks amazing.
Can’t wait to see it done and polished but for now Goodluck :slight_smile:

(mark the post as solved if you believe you got all the info you wanted)

Mark persons post as solution if it worked

robloxapp-20220726-1053117.wmv (3.7 MB)
robloxapp-20220726-1102279.wmv (1.2 MB)
Working air supply.
I use 3D flood fill method, using queue. Voxels have size 2x2x2. Algorithm stops after reaching 10000 voxels (in this case space is considered as not sealed), or when all possible spaces had been filled (in this case space is considered as sealed).
Currently it isn’t very fast, but it was in Roblox Studio. I hope on real Roblox servers it’ll be quite faster. Or alternatively I’ll enlarge voxels, and reduce voxel limit. And maybe I’ll use Actors and it’ll be done asynchronously.
Currently air voxels are semi-transparent, to make effects visible, but in future I’ll make them fully transparent. Or maybe it’ll be configurable, to allow players to detect holes in their ships.
Also, if you’d want to test it, then play development version of my game, here: Universe Vastness [DEVELOPMENT] - Roblox . Main branch, here: Universe Vastness [PRE ALPHA] - Roblox is currently really out-of-date.

4 Likes