Check for part overlap at (x,y,z)

As a Roblox developer, it is currently too hard to check if any parts overlaps a certain point. I tried writing a function for this using Region3, but Region3 doesn’t respect part shape or rotation.
Something like Workspace:FindIntersections(Vector3 point, array IgnoreList) would be nice.

20 Likes

I would be OK with a function like this. Don’t 100% support it, but it’d be nice for quite a few situations.

As for your Region3 solution, it is possible to call FindPartsInRegion3 but have a region with a very small size so that it’s virtually a point (i.e. under 0.001 studs in size).

I’d certainly want a whitelist-based version of this too

3 Likes

EgoMoose wrote some code for rotated Region3 casting. I do not understand 100% what you want, but this may help.
http://wiki.roblox.com/index.php?title=User:EgoMoose/Articles/Rotated_region3

That was my original Idea:

function Check_Intersection(Point)
	return #game.Workspace:FindPartsInRegion3(Region3.new(Point,Point),nil,1) ~= 0
end

It worked, but it wasn’t precise enough for what I needed. Region3’s treat all parts like bounding boxes, so something like this:

The function would return true if it was within the boundaries of that blue selection box, rather than inside the wedge.

Sorry, I should have been more specific in OP. I need a function that can tell precisely if a point is located within a part’s geometry, rather than just vaguely within the area like Region3’s return.

Give this a shot.

function partIntersectsPoint(part, point)
	local delta = part.CFrame:pointToObjectSpace(point)
	delta = Vector3.new(math.abs(delta.X), math.abs(delta.Y), math.abs(delta.Z))
	local halfSize = part.Size / 2
	
	local inX = delta.X <= halfSize.X
	local inY = delta.Y <= halfSize.Y
	local inZ = delta.Z <= halfSize.Z
	
	return inX and inY and inZ
end

function getIntersectingParts(point)
	--construct a region representing a sizable area around our checking point
	local delta = Vector3.new(8, 8, 8)
	local region3 = Region3.new(point - delta, point + delta)
	
	--use the c++ acceleration to quickly find parts that could possibly be intersecting this point
	local parts = workspace:FindPartsInRegion3(region3)
	
	--test each of those parts using simple matrix mathematics
	local intersectingParts = {}
	for _, part in pairs(parts) do
		if partIntersectsPoint(part, point) then
			table.insert(intersectingParts, part)
		end
	end
	return intersectingParts
end

EDIT: If you’re looking for “is a point in a part’s geometry” and you want it to respect wedges, I could figure that out for you. Sphere’s pretty easy. The solution I posted above also solves that for cubes.

6 Likes

It’s not a reliable solution to hardcode every type of geometry. What are you going to do when you need intersection check with unions or mesh parts?

Okay, so this kind of thing may be possible, but it’s apparently non-trivial to expose to Lua. That being said, it’s not impossible. What you as the developers need to do in order to help me help you is provide me with a myriad of legitimate use cases for it. Then I can get the ball rolling on it.

For example: As a developer, I want to be able to determine if a player is currently inside of a CanCollide = false MeshPart or UnionOperation with respect to its physical decomposition.

I’ll be honest, I’m having trouble coming up with good use cases for this. Surprise me.

cc @Khanovich

I needed it specifically to determine if the player’s camera was inside something (for this), as well as for an ability in my game that allows players to shrink at will. When they try to un-shrink, I could do a point test at where there torso would be when they un-shrunk, and then prevent them from shrinking if it’s occupied so they wouldn’t get stuck.
I also imagine it being relatively handy when coding custom player physics, but I don’t have any good examples. I’m sure other people can think of some more stuff.

That first use case is valid. The second one could/should be solved with GetTouchingParts. One is not going to cut it. Anyone else?

For Classic Build to Survive, I reimplemented the old hopperbin build tools to support FilteringEnabled. The tools need to be able to test various candidates for placement, which means being able to do easily 50 different collision checks in a single frame. The function I implemented was a test between an oriented bounding box against the world. To do that, I implemented separating axis theorem for oriented bounding boxes, and then used FindPartsInRegion3 as a broadphase. I think that should be built into roblox so that people can make polished in-game tools without having to write their own copy of roblox’s collision testers inside roblox.

6 Likes

Not necessarily with the second issue. I’d need to do a collision check in an area above the player. To use GetTouchingParts, I’d have to either A) unshrink the player, check, and then reshrink if there’s no room or B) create a new part above the player and do a check that way. Neither of those solutions are particularly ideal.