Provide surface testing methods on `WorldRoot`

As a Roblox developer, it is currently too hard to determine what parts are contacting other parts’ surfaces in a WorldModel, or if two parts contact eachother.

If Roblox is able to address this issue, it would improve my development experience because it would allow me to stop relying on unreliable/performance intensive approximations.

The following two methods each are close to implementing the desired behaviour but don’t:
WorldRoot:ArePartsTouchingOthers() - Only tells you that a part is touching others, does not tell you which parts
Workspace:JoinToOutsiders() - Only creates welds between surfaces, and only works for parts in the workspace (not in a WorldModel)


Use case

My use case is to implement surface connections for parts, similar to the behaviour of :JoinToOutsiders(), but with custom logic, and the ability to perform this in a WorldModel. This is very useful behaviour for building games which don’t use strict grids or allow players to build on surfaces that aren’t grid aligned.

If desired, determining which surface a part is connected to is also relatively easy and performant with a few dot products for the part’s three axes to determine which frustum the partner part is in, but determining that two parts are contacting eachother in the first place is much harder and doesn’t have a good non-engine solution without direct access to the parts’ collision geometries.

Motivation

The following edge case is particularly difficult to deal with for arbitrary part geometries:

Specifically, determining if the surface isn’t smooth at the contact point (this is kind of similar to smooth shading in concept) would currently require sampling multiple points on the part’s surface to approximate the gradient, which isn’t performant, or necessarily reliable/accurate enough for the use case above.

In practice, all of my attempts to implement the above have not really gone well and lead to a worse experience than falling back to :JoinToOutsiders which is more limited in its usefulness due to it requiring parts to be parented to the world already.

What’s the best that can currently be done?

An almost valid solution, and the best that I have come up with so far, is to use a handful of calls to :GetClosestPointOnSurface() to find a point which minimizes the distance between the surfaces of both parts (in other words, one contact point between the two parts).

If the two points on the surfaces of the two parts closest to this ‘contact point’ are within some epsilon value, then they can be considered touching. This should generally work for any non-concave geometry and is relatively easy to implement so it works in a lot of cases, but it’s imperfect and an in-engine solution would be desirable to get around the above edge case and edge cases with concave geometries.

What could APIs that solve this problem look like?

APIs ideally should go by a similar definition to the one :JoinToOutsiders uses for when two surfaces are considered contacting.

For example, one or both of these APIs would fit the use case I gave in an ideal way:

  • WorldModel:ArePartsContacting(partA: BasePart, partB: BasePart): boolean - Would return whether or not the two parts’ surfaces are contacting somewhere (not on their edges)
  • WorldModel:GetContactingParts(partA: BasePart, overlapParams: OverlapParams?): {BasePart} - Would return a list of parts which are contacting eachother
19 Likes

Yeah, this would be pretty nice.

I along with Garrytinkle support this change
#maketetrahedrons weld again

I’ve never met this man in my life!