Hello, like the title says, it seems like the rayCast method is messed up in the sense that it just straight up seems to skip objects to check for collision against. Here are a couple of pictures to show you what my problem is.
1. there is a :rayCast from the 1st body to the 2nd, there is nothing in-between and everything is OK.
2. placed a wall that serves as an obstacle, the wall seems to be occluding the :rayCast just fine. Everything is OK.
3. now I move a couple of pixels to the right away from the wall, and bam, it's ignoring the obstacle. What the hell is going on?
Additionally, here's a video which shows even more weird stuff: https://www.dropbox.com/s/xefdxde4zrw0c ... 6.mp4?dl=0
Here's another video which showcases more errata when it comes to obstacles and multiple objects: https://www.dropbox.com/s/vw3zmouhexjp5 ... 7.mp4?dl=0
It's as if the query for objects to check the collision against is not working properly.
I've checked the position of the wall obstacle, and it doesn't change before/after I move (it's not meant to, anyway), the wall obstacles are static objects, and collision detection works just fine, but raycasting messes up and just ignores that object completely. Has anyone else had a similar problem? This is incredibly infuriating because I am not doing anything wrong as far as I'm concerned, especially considering that the start/finish positions check out just fine.
This happens using both 0.10.2 and 11.1, so I am at a complete loss right now.
I've googled this issue, but found no one else having the same problem in the LOVE2D community, yet at the same time someone else was having a similar issue with Box2D outside of LOVE2D so maybe this has something to do with Box2D itself?
I've tried calling :setSleepingAllowed(false) on the world object to prevent objects from sleeping (I was thinking maybe the walls were doing that and it was ignoring them?). That didn't help. I tried manually disabling sleeping on wall obstacles, that didn't help either. I'm clueless as to what the hell is going on at the moment.
Any help would be appreciated.
Messed up World:rayCast()?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Messed up World:rayCast()?
Works for me.
I added a second object that isn't toggled or moveable, just in case, but that didn't change anything.
Can you provide some code to reproduce the issue?
Code: Select all
local world = love.physics.newWorld(0, 0, false)
local ray1x, ray1y = 400, 300
local ray2x, ray2y = 700, 500
local intersectx, intersecty
local range
local obstacle = false
local obsBody = love.physics.newBody(world, 900, 0, "static")
local obsShape = love.physics.newRectangleShape(64, 64)
local obsFixture = love.physics.newFixture(obsBody, obsShape)
local obsBody2 = love.physics.newBody(world, 348, 300, "static")
local obsFix2 = love.physics.newFixture(obsBody2, obsShape)
local obsx, obsy = 620, 415
local function fixtures(fixture, x, y, xn, yn, fraction)
if fraction < range then
intersectx, intersecty = x, y
range = fraction
end
return fraction
end
function love.update(dt)
if obstacle then
obsBody:setPosition(obsx, obsy)
else
obsBody:setPosition(1000, 0)
end
world:update(dt)
if love.mouse.isDown(2) then
ray1x, ray1y = love.mouse.getPosition()
elseif love.mouse.isDown(1) then
obsx, obsy = love.mouse.getPosition()
else
ray2x, ray2y = love.mouse.getPosition()
end
intersectx, intersecty = ray2x, ray2y
range = 1
if math.abs(ray1x - ray2x) + math.abs(ray1y - ray2y) > 1 then
world:rayCast(ray1x, ray1y, ray2x, ray2y, fixtures)
end
end
function love.keypressed(k)
if k == "escape" then return love.event.quit() end
if k == "space" then
obstacle = not obstacle
end
end
function love.draw()
love.graphics.setColor(0,1,1)
love.graphics.polygon("line", obsBody:getWorldPoints(obsShape:getPoints()))
love.graphics.polygon("line", obsBody2:getWorldPoints(obsShape:getPoints()))
love.graphics.setColor(1,0,0)
love.graphics.line(ray1x, ray1y, intersectx, intersecty)
love.graphics.setColor(1,1,1)
love.graphics.print("space to toggle obstacle, lbutton to move obstacle, rbutton to change start of ray")
end
Can you provide some code to reproduce the issue?
-
- Party member
- Posts: 106
- Joined: Sat Jun 21, 2014 3:45 pm
Re: Messed up World:rayCast()?
I noticed you return fraction in the callback, is that the default use case for the :rayCast method? This wasn't mentioned anywhere. I thought the :rayCast method would automatically test against closest-to-farthest objects, and would return the closest point of impact into the callback method first, not test against all objects between the ray start/finish position and return each point of intersection in an arbitrary order. I think this is why I was having my problems.pgimeno wrote: ↑Mon Nov 19, 2018 10:54 pm Works for me.
I added a second object that isn't toggled or moveable, just in case, but that didn't change anything.Code: Select all
local world = love.physics.newWorld(0, 0, false) local ray1x, ray1y = 400, 300 local ray2x, ray2y = 700, 500 local intersectx, intersecty local range local obstacle = false local obsBody = love.physics.newBody(world, 900, 0, "static") local obsShape = love.physics.newRectangleShape(64, 64) local obsFixture = love.physics.newFixture(obsBody, obsShape) local obsBody2 = love.physics.newBody(world, 348, 300, "static") local obsFix2 = love.physics.newFixture(obsBody2, obsShape) local obsx, obsy = 620, 415 local function fixtures(fixture, x, y, xn, yn, fraction) if fraction < range then intersectx, intersecty = x, y range = fraction end return fraction end function love.update(dt) if obstacle then obsBody:setPosition(obsx, obsy) else obsBody:setPosition(1000, 0) end world:update(dt) if love.mouse.isDown(2) then ray1x, ray1y = love.mouse.getPosition() elseif love.mouse.isDown(1) then obsx, obsy = love.mouse.getPosition() else ray2x, ray2y = love.mouse.getPosition() end intersectx, intersecty = ray2x, ray2y range = 1 if math.abs(ray1x - ray2x) + math.abs(ray1y - ray2y) > 1 then world:rayCast(ray1x, ray1y, ray2x, ray2y, fixtures) end end function love.keypressed(k) if k == "escape" then return love.event.quit() end if k == "space" then obstacle = not obstacle end end function love.draw() love.graphics.setColor(0,1,1) love.graphics.polygon("line", obsBody:getWorldPoints(obsShape:getPoints())) love.graphics.polygon("line", obsBody2:getWorldPoints(obsShape:getPoints())) love.graphics.setColor(1,0,0) love.graphics.line(ray1x, ray1y, intersectx, intersecty) love.graphics.setColor(1,1,1) love.graphics.print("space to toggle obstacle, lbutton to move obstacle, rbutton to change start of ray") end
Can you provide some code to reproduce the issue?
Edit: yep, this is why I was having my problems. God fucking damn it. Someone needs to document that it returns points of intersection in an arbitrary order, because some other poor soul might end up spending 5 hours trying to figure out what the hell they did wrong with their world/body/shape/fixture setup and then it turns out the :rayCast method behavior is not what they expected...
Re: Messed up World:rayCast()?
Returning 1 worked as well. I started returning 1, but changed it to 'fraction' when I saw the forum post you linked, to try to copy their repro and see if that changed something, but it didn't. However I assumed that the order was going to be arbitrary, so I added the code to check the minimum since the beginning. It didn't make sense in my mind that Box2D first creates a list of fixtures that intersect your line, then sorts it and then calls your callback in sorted order: you can do that yourself if that's what you need, and it would waste time and memory if you don't need it at all (e.g. in some use cases you want to detect whether there's a collision at all, you don't need the closest one).Whatthefuck wrote: ↑Tue Nov 20, 2018 10:06 am I noticed you return fraction in the callback, is that the default use case for the :rayCast method? This wasn't mentioned anywhere.
Now that I notice, it's likely that in that other post, their problem is the same: not picking the nearest match.
Glad it helped!
-
- Party member
- Posts: 106
- Joined: Sat Jun 21, 2014 3:45 pm
Re: Messed up World:rayCast()?
Yeah, it makes sense why it wouldn't sort them internally, but for some reason I still expected it to work that way.pgimeno wrote: ↑Tue Nov 20, 2018 12:52 pmReturning 1 worked as well. I started returning 1, but changed it to 'fraction' when I saw the forum post you linked, to try to copy their repro and see if that changed something, but it didn't. However I assumed that the order was going to be arbitrary, so I added the code to check the minimum since the beginning. It didn't make sense in my mind that Box2D first creates a list of fixtures that intersect your line, then sorts it and then calls your callback in sorted order: you can do that yourself if that's what you need, and it would waste time and memory if you don't need it at all (e.g. in some use cases you want to detect whether there's a collision at all, you don't need the closest one).Whatthefuck wrote: ↑Tue Nov 20, 2018 10:06 am I noticed you return fraction in the callback, is that the default use case for the :rayCast method? This wasn't mentioned anywhere.
Now that I notice, it's likely that in that other post, their problem is the same: not picking the nearest match.
Glad it helped!
Someone should really document that it returns intersections in an arbitrary order, so that someone else doesn't end up spending several hours trying to figure out what the hell is going on, haha.
Re: Messed up World:rayCast()?
well, if you have a forum account, you also have a wiki account The same user and password works in the wiki.
Who is online
Users browsing this forum: Ahrefs [Bot], Majestic-12 [Bot] and 5 guests