Raycasting. Thank You Corona!

Icy Spark,  Thank you, we must also change here:

local gameloop = function(event) for i = 1, 200 do if ray[i] then -- Update the ray by removing the old one and creating a new one. display.remove( ray[i] ) end hits[i] = physics.rayCast( from\_x, from\_y, to\_x-(i\*2), to\_y, 1 ) if hits[i] then -- Draw a line to the first hit. ray[i] = display.newLine( from\_x, from\_y, hits[i][1].x, hits[i][1].y ) else -- no hit. ray[i] = display.newLine( from\_x, from\_y, to\_x-(i\*2), to\_y ) end ray[i].width = 2 end end Runtime:addEventListener("enterFrame", gameloop)

We are waiting for the bug fixes you described Corona

Just wanted to let everyone know that rayCasting is working great now.  Thank you for your super quick bug fix Corona, and for adding the “normal”.  All is perfect!

local main = display.newGroup() local physics = require("physics") physics.start() physics.setGravity( 0, 0 ) physics.setDrawMode( "hybrid" ) local cub = display.newGroup() local cub = display.newRect(200, 200, 40, 40) cub.x = 205 --cub:setFillColor(255, 255, 255) physics.addBody(cub, { density = 1, friction = 0.5, bounce = 1.6 } ) cub.isSensor = true cub.id = "cub" main:insert(cub ) -- f\_sensor local f\_sensor = display.newRect(cub.x-15, cub.y-154, 30, 30) physics.addBody(f\_sensor, {density = 0.0001, friction = 1.0, bounce = 0.1}) f\_sensor.isFixedRotation = true f\_sensor.isSensor = true f\_sensor.sensor = "sensor" f\_sensor.alpha = 0 f\_sensor.id = "cub" main:insert(f\_sensor) local Pivot = physics.newJoint( "pivot", cub, f\_sensor, cub.x,cub.y) local x1,x2,y1,y2 = 0 local startX = 0 local startY = 0 local endX = 0 local endY = 0 local function distanceBetween(x1, y1, x2, y2) local dist\_x = x2 - x1 local dist\_y = y2 - y1 local distanceBetween = math.sqrt((dist\_x\*dist\_x) + (dist\_y\*dist\_y)) return distanceBetween end function onTouch(e) if(e.phase == "began") then startX = e.x startY = e.y center = display.newRect(e.x, e.y, 10, 10) elseif(e.phase == "moved") then endX = e.x endY = e.y distance = distanceBetween(startX, startY, e.x, e.y) rr2 = (math.atan2( endX-startX,endY-startY )\*180 / math.pi)-180 if distance \> 50 then distance = 50 end Dv\_x = math.cos( math.rad(rr2-90) )\*-distance/1\*2 Dv\_y = -math.sin( math.rad(rr2-90) )\*-distance/1\*2 cub.rotation = -rr2 f\_sensor.rotation = cub.rotation print("Dv\_y " .. Dv\_y) elseif(e.phase == "ended") then distance = 0 Dv\_x = 0 Dv\_y = 0 display.remove(center) end end Runtime:addEventListener("touch", onTouch) local startX = 0 local startY = 0 local endX = 0 local endY = 0 local t = 0 local crate = display.newRect( 0, 0, 50, 50 ) crate.x = 350 crate.y = 80 physics.addBody( crate, "static",{ density=3.0, friction=0.5, bounce=0.3 } ) main:insert(crate) local chaser = display.newRect(600, 50, 10, 10) physics.addBody(chaser, "dynamic", {isSensor = true, density = 1.0, friction = 1.0, bounce = 0.1}) main:insert(chaser) chaser.id = "cub" chaser.alpha = 0 -- start local from\_x = 0 local from\_y = 0 local to\_x = 200 local to\_y = 380 local hits = {} local ray = {} local obj\_x = {} local obj\_y = {} local gameloop = function(event) cub:setLinearVelocity(Dv\_x,Dv\_y) -- camera chaser.chaseSpeed = 6 local xDist = cub.x - chaser.x local yDist = cub.y - chaser.y chaser:setLinearVelocity(xDist \* chaser.chaseSpeed, yDist \* chaser.chaseSpeed) main.x = (chaser.x \* -1) + display.contentWidth / 2 main.y = (chaser.y \* -1) + display.contentHeight / 2 --n = n + 1 for i = 1, 50 do if ray[i] then -- Update the ray by removing the old one and creating a new one. display.remove( ray[i] ) end hits[i] = physics.rayCast( cub.x, cub.y, f\_sensor.x+(i\*6), f\_sensor.y, 1 ) if hits[i] and hits[i][1].object.id ~= "cub" then -- Draw a line to the first hit. obj\_x[i] = hits[i][1].position.x obj\_y[i] = hits[i][1].position.y ray[i] = display.newLine( cub.x, cub.y, obj\_x[i], obj\_y[i] ) else ray[i] = display.newLine( cub.x, cub.y, f\_sensor.x+(i\*6), f\_sensor.y) end ray[i].width = 5 main:insert(ray[i]) end end local timerUpd = timer.performWithDelay( 5, gameloop,-1 )

how to make a lantern? What would the beam is not distorted. Code is attached above.

Hi @Icy Spark,

Do you mind if I ask how you’ve utilized this in the game? Somebody was asking me yesterday “what are some use-cases for raycasting?”, and while I can think of a few immediate examples, I’m curious what you’re doing with it. :slight_smile:

Brent

Hi Brent,

Only just started working on it earlier, but it involves getting a laser to a goal.  This is perfect for being able to draw the laser to the exact point it hits an object.  

Can also use the exact contact point to bounce the laser off a mirror etc.  Even better it doesn’t require a collision listener, which is great.

One question though. 

Say I want to refract the laser light through a prism to bend the laser light.  Using raycasting I can get the initial contact point that it hits the prism, so I can also change the angle as it goes through the prism. 

But, is it possible to get the hit ended point, so that I can bend the light again as it exits the prism?

I still don’t get it.  Any pertinent Google searches on raycasting bring up Wolfenstein 3D.  I guess I’ll have to wait until I get home to download the latest daily build to try it out, but if someone can be so kind as to explain its usefulness in game development, especially in regards to physics, I’d appreciate it.

Hi @BeyondtheTech,

It think the common confusion is “raycasting” as a term in computer graphics versus the physics raycasting that this topic is about. Here’s more info on physics-based raycasting:

http://www.iforce2d.net/b2dtut/raycasting

Brent

Using the example of a laser for Raycasting I suppose can confuse you.

What it effectively does is it draws an imaginary line between two points, similar to the drawline function.

However, it counts the amount times it “hits” an object and passes the co-ordinates of the intersection point.

You can specify how many hits you would like to count.

A good example would be for line of sight in a top down game.  You set the hit count maximum to one. 

Then raycast from the baddies point of view, ie in which way they are looking.

If the raycast hits you the player then they can “see” you and act accordingly, for example start shooting at you.

Hope this helps

Holy toledo, I think that’s fantastic!

As some of you know, I’m building a remake of my space game Archangel, and I had to come up with some (what I thought was) clever thinking on how to detect if a passing asteroid or ship was on a collision course.  I set up a separate large “proximity” sensor around the ship which had to follow the ship around.  When an asteroid/ship it crosses (collides) with the proximity sensor, I had to determine the trajectories of both the player and the asteroid/ship see if they were crossing (intersecting) each other, allowing for some angular leeway.  It was quite a challenge, and it might have taken more CPU cycles than I would have wanted to allocate for it, so perhaps replacing it with this new feature will do it better justice.  Thanks!

Hi Brent,

In that example box2D exposes the normal.  Is this accessable in Corona as it would make my life so much easier.

Hi @Icy Spark,

I already asked the engineering team and I should have an answer fairly soon. Thanks for bringing this up!

Brent

Hi @Icy Spark,

The “normal” isn’t currently reported, but engineering is fixing that now and it should be exposed for your use in a daily build upcoming. Just keep an eye out. :slight_smile:

Brent

Like IcySpark says, this would be excellent for an Metal Gear Solid inspired stealth game. Raycasting to create Wolfenstein/Doom uses the technique to calculate how high a wall is based on the distance to the player.

It’s all really great that this functionality is here.

so this would mean, a NPC “raycasts” in a zelda like game my hero, and if there is no intersection point with another object in-between (like tree, unless the tree allows you to shoot through), the NPC will fire at me?

If I understood that right… this is awesome!

yep that’s pretty much it.  great news, though i found a major bug that renders raycasting useless in its current state.

great news! and I am sure they will fix it soon…

Hi @IcySpark,

What’s the bug? I can request that it gets investigated so people can start implementing ray casting a.s.a.p.

Brent

Hi Brent,

I have posted now 2 bugs in this thread http://forums.coronalabs.com/topic/33714-raycasting-is-broken/

I have also submitted the two bug reports 22591 and 22593.

First bug:  If you set from_x and/or from_y to anything other than 0 the raycasting fails to work properly or at all.

Second bug:  rayCasting doesnt adhere to its length set by from_x, from_y, to_x and to_y. 

can be obtained dynamic shadow using the ray casting?

http://www.youtube.com/watch?v=C-ScURIRTGA

Yes no problem.  Here is a quick example that I just created in Corona.  Had to make the source 0,0 due to the current bug in raycasting though.

raytracing-corona.png