I’m sort of at wits end for figuring out a couple of issues involving raycasting with the Physics engine. I’ve noticed a few things which totally confuse me.
I can’t get raycast to respect more than one category, when I enter two of them (say 1, and 8), only the first argument will work. So if the first one is “1” then I’ll get back all casted bodies with category “1”. If I reverse the order so that “8” is first, then I’ll get back hit objects with category “8”.
I’ve also witnessed a sensor with a different category somehow allow the raycast to pass through an object siting on the sensor. If I move the object off the sensor then the raycast will hit it properly. Zah?!
These two issues are enough to make me wonder if I’m missing some piece of knowledge here. I have this hunch that masks and categories require bit shifting / splitting values across one integer or somthing.
Could use some help with understanding how categories work and what might be my issue.
I had a look at the raycasting code and I’ve found a bug with the way raycasts are clipped and filtered. Basically what’s happening is the raycast is being clipped to the first object it finds (which is not always the closest). This means that sometimes it will miss objects or not return the closest one it finds, such as the issue with the sensor. It may also not be filtering objects properly. The only thing I can recommend for now until I fix it is to filter a single category at a time, although there will still be issues with finding the closest one.
what should be the result of raycast whose startpoint is within a body- should it report the intersect pt on the edge of the body it is within or will it report the intersect with the next closest body?
If you add the body which holds the raycast then it will go through, else it stops straight away.
I used this to get around the problem, you can still add categories, the one I used was 0 :
rx = physics.raycastAll(self.bl.body.position,
self.bl.body.position+vec2(x,y):normalize()*700,0)
local rb
local cent = {0,0}
for k,v in pairs(rx) do
local dst = (v.point-self.bl.body.position):len()
if ( dst < cent[2] ) or ( cent[1] == 0 ) then
cent = {v,dst}
end
end
if type(cent[1]) ~= "number" then
rb = cent[1]
end
if not rb then return end
This fixes the error for me completely, took a while to figure out the problem though…
@John - Okay, thanks for the info. It might be a tad more expensive but I should be able to raycast twice with different categories and decide myself which is closer. I haven’t noticed the “not picking the closest hit” issue when only using one category. Good to know I’m not going crazy - I can at least work around this issue. Thanks!
Oh, might a fix for this be coming in the next update?
@Luatee: Ah! You are correct, and I am a moron! My apologies. Well then…I look forward even more to the next update, this bug has been biting me pretty hard!