generic image
Processing...
  • Games
  • Catalog
  • Develop
  • Robux
  • Search in Players
  • Search in Games
  • Search in Catalog
  • Search in Groups
  • Search in Library
  • Log In
  • Sign Up
  • Games
  • Catalog
  • Develop
  • Robux
   
ROBLOX Forum » Game Creation and Development » Scripters
Home Search
 

Re: Ray reflection COMPLETE

Previous Thread :: Next Thread 
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
30 Aug 2014 07:25 PM
After working for hours, I've finally finished my ray reflection script. It flawlessly handles reflection off of any surface regardless of rotation. The arguments that it takes are:
-Start position of the original ray
-Direction of the original ray
-The ignore list for the ray that is applied the entire time it is being reflected
-A string that all objects named after it should act as reflectors -OR- a table containing all objects that should act as reflectors -AND/OR- containing strings that all objects named after then should act as reflectors
-The maximum length that each reflected ray can be

It will return:
-a table of all reflectors that the ray hit along its path
-a table of all positions where the ray intersected a reflector along its path
-the final part that the ray hit, stopping its path
-the point at which the ray stopped

Limitations:
-not designed to correctly reflect off of spheres, cylinders, wedges, or any non-brick part (for now)
-will cause a stack overflow error if you try to infinitely reflect the ray back on itself (for now)

The model is here: http://www.roblox.com/Ray-Reflection-Service-item?id=175409395


--SOURCE CODE--
_G.castRayWithReflection = function(startP, endP, ignoreList, reflectors, reflectLimit)
local mirrors, mirrorhits = {}, {}
local finalPart, finalHit
function internalCast(localStart, localEnd)
local ray = Ray.new(localStart, localEnd)
local part, point = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
local reflected = false
if (part ~= nil) then
if (type(reflectors) == "string") then
if (part.Name == reflectors) then
reflected = true
end
elseif (type(reflectors) == "table") then
for _, v in pairs(reflectors) do
if (part == v or part.Name == v) then
reflected = true
end
end
end
end
if (reflected == true) then
table.insert(mirrors, part)
table.insert(mirrorHits, point)
local normal = nil
local comps = {part.CFrame:components()}
local relative = part.CFrame:pointToObjectSpace(point) / part.Size
local rels = {relative.X, relative.Y, relative.Z}
local highest = 1
for i, v in pairs(rels) do
if (math.abs(v) > math.abs(rels[highest])) then
highest = i
end
end
local unitVT = {}
for i = 3 + highest, 9 + highest, 3 do
table.insert(unitVT, comps[i] * (rels[highest] / math.abs(rels[highest])))
end
local normal = Vector3.new(unpack(unitVT))
internalCast(point, ((point - localStart).unit - 2 * (point - localStart).unit:Dot(normal) * normal) * reflectLimit)
else
finalPart, finalHit = part, point
end
end
internalCast(startP, endP)
return mirrors, mirrorHits, finalPart, finalHit
end

Report Abuse
Seranok is not online. Seranok
Joined: 12 Dec 2009
Total Posts: 11083
30 Aug 2014 07:45 PM
> A string that all objects named after it should act as reflectors -OR- a table containing all objects that should act as reflectors -AND/OR- containing strings that all objects named after then should act as reflectors

How about just accepting a callback which should return true if the given object should act as a reflector?
Report Abuse
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
30 Aug 2014 07:58 PM
@Seranok
Not quite sure what you mean, could you elaborate? Sorry, but my brain is literally fried after working on this for so long.
Report Abuse
mathchamp is not online. mathchamp
Joined: 22 Oct 2007
Total Posts: 320
30 Aug 2014 09:51 PM
Basically, let the user pass a condition function as an argument, and when a part is hit, call the condition function with that part as the argument. The condition function would return true if the part should act as a reflector.

That way, if a user wants to implement your script, they can specify whatever condition they want instead of being restricted to those types of conditions you have implemented. Perhaps they want to check the Reflectance property of the object as the condition. Perhaps they want to check if the part has a child named "Reflect". Perhaps they even want to make it a random chance of whether the part should reflect or not.

Also, I would suggest allowing a maximum length to be specified as well. Finally, remember that the raycast function is limited to rays of length 1000 or less, so if you need to go a longer distance than that, you need to break up the ray into smaller rays that meet this limit.
Report Abuse
nicemike40 is not online. nicemike40
Joined: 19 Dec 2008
Total Posts: 1814
30 Aug 2014 11:08 PM
And put a 'local ' at the start of line 4
It's just semantics, but it's more correct
Report Abuse
nicemike40 is not online. nicemike40
Joined: 19 Dec 2008
Total Posts: 1814
30 Aug 2014 11:08 PM
Oh and nice job
Report Abuse
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
31 Aug 2014 01:40 AM
Thanks for the suggestions everyone, I'll implement them (along with support for spheres and possibly wedges) once I get back to my PC. I have a couple of questions though:

When dealing with ray collisions, do cylinders truly act like cylinders? I know that physically they merely act like spheres. Will a ray collide with the edges that normally don't interact physically with other parts?

Also, do you think it would be more intuitive to have it return 2 tables that include ALL of the parts and intersection points (including the start point and the end point) as opposed to indexing them separately?
Report Abuse
nicemike40 is not online. nicemike40
Joined: 19 Dec 2008
Total Posts: 1814
31 Aug 2014 02:49 AM
No they act like spheres and it pissed me off when I wrote my own normal finding script. I got WedgeParts and CornerWedgeParts to work fine though :P

And no, I would maybe consider even switching the return order so that it's finalPart, finalHit, mirrors, mirrorHits because I think people would access the final part and hit way more often than the individual mirrors.
Report Abuse
RobustPhysics is not online. RobustPhysics
Joined: 12 Jul 2012
Total Posts: 3064
31 Aug 2014 04:42 PM
Nice job. I had tried to make one to help somebody a while back, but I don't think it really worked out too well. Probably should have done some research on reflection mechanics, but oh well.

Anyways, I think what Seranok meant was using a function as an argument. You'd call that function inside of _G.castRayWithReflection, sending 'part' as an argument. So something like...

local reflected = false
if (part ~= nil) and reflectors(part) then
reflected = true
end

It'd give it more options, like only reflecting parts with a Reflectance that's at least 0.3 or parts with a certain BrickColor.
Report Abuse
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
31 Aug 2014 04:58 PM
Yeah I understand that now. I'll work on that once I get back to my computer.
Report Abuse
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
31 Aug 2014 09:36 PM
I've been working on support for spheres for around 10 minutes now, and apparently I was wrong when I thought it would be easy. Is the normal vector not just (intersection - Sphere.Position).unit? When I use that for the "normal" variable in my script, I get a quite beautiful-looking ring around the sphere, but it is still incorrect.
Report Abuse
nicemike40 is not online. nicemike40
Joined: 19 Dec 2008
Total Posts: 1814
31 Aug 2014 10:17 PM
I made my own quick too and my solution was to temporarily add the last part hit to the ignore list for the next ray. It won't affect anything because all ROBLOX shapes are convex
Report Abuse
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
31 Aug 2014 10:23 PM
The problem with that, though, is that if the ray at some point gets reflected back to that part, it will pass through it instead of reflecting properly. Maybe I'll only add it to the ignore list for the immediately next reflection, then remove it afterwards.
Report Abuse
nicemike40 is not online. nicemike40
Joined: 19 Dec 2008
Total Posts: 1814
31 Aug 2014 10:41 PM
(that's what I meant)
Report Abuse
blockoo is not online. blockoo
Joined: 08 Nov 2007
Total Posts: 17202
31 Aug 2014 10:52 PM
Woops, didn't see where you typed "for the next ray"
Report Abuse
nicemike40 is not online. nicemike40
Joined: 19 Dec 2008
Total Posts: 1814
31 Aug 2014 11:07 PM
If you wanted to find the normals for everything I made this function codepad/oLP2DNZR a few months ago - I even commented it for some reason.
It ain't very efficient, but it's a good proof of concept.
Report Abuse
cxcharlie is not online. cxcharlie
Joined: 26 Aug 2009
Total Posts: 1414
01 Sep 2014 11:27 AM
good job, you should check out xxmonkey's surface normal computer for other things like spheres, cylinders, and terrain.
Report Abuse
Previous Thread :: Next Thread 
Page 1 of 1
 
 
ROBLOX Forum » Game Creation and Development » Scripters
   
 
   
  • About Us
  • Jobs
  • Blog
  • Parents
  • Help
  • Terms
  • Privacy

©2017 Roblox Corporation. Roblox, the Roblox logo, Robux, Bloxy, and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.



Progress
Starting Roblox...
Connecting to Players...
R R

Roblox is now loading. Get ready to play!

R R

You're moments away from getting into the game!

Click here for help

Check Remember my choice and click Launch Application in the dialog box above to join games faster in the future!

Gameplay sponsored by:
Loading 0% - Starting game...
Get more with Builders Club! Join Builders Club
Choose Your Avatar
I have an account
generic image