Hi , I have been trying to reflect rays but so far no progress . I am using concepts from unity tutorials but their approach are different hard to try in defold.
Any Suggestions.
Hi , I have been trying to reflect rays but so far no progress . I am using concepts from unity tutorials but their approach are different hard to try in defold.
Any Suggestions.
Here is an example project with 1 reflection (which I believe was done right but if I did it wrong please anyone correct me).
ReflectRays.zip (4.7 KB)The important part is in the reflect script
local max_reflection_length = 1000
local max_reflections = 3
local original_color = vmath.vector4(1,1,1,0.25)
local reflection_color = vmath.vector4(1,0,0,0.5)
local raycast_groups = {hash("default")}
local function draw_line(start_point, end_point, color)
-- start, end = vmath.vector3()
-- color = vmath.vector4()
msg.post("@render:", "draw_line", { start_point = start_point, end_point = end_point, color = color } )
end
local function draw_reflections(self)
local direction = self.target - self.position
if vmath.length(direction) == 0 then
direction = vmath.vector3(0,1,0)
end
direction = vmath.normalize(direction)
--print(direction)
local target_position = self.position + direction * max_reflection_length
draw_line(self.position, target_position, original_color)
local result = physics.raycast(self.position, target_position, raycast_groups)
if result ~= nil then
pprint(result)
-- sample result
-- { --[[000001B088ACE200]]
-- normal = vmath.vector3(0, -1, 0),
-- fraction = 0.089520141482353,
-- position = vmath.vector3(75.563575744629, 48, 0),
-- group = hash: [default],
-- id = hash: [/wall]
-- }
-- rvec = ivec - (2 * dot(normal, ivec) * normal)
local reflected_vector = direction - (2 * vmath.dot(result.normal, direction) * result.normal)
local reflected_target = result.position + reflected_vector * max_reflection_length
draw_line(result.position, reflected_target, reflection_color)
-- todo do multiple reflections
end
end
function init(self)
msg.post(".", "acquire_input_focus")
self.position = vmath.vector3()
self.target = vmath.vector3()
end
function final(self)
-- Add finalization code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
end
function update(self, dt)
--pprint(self.position, self.target)
go.set_position(self.position)
draw_reflections(self)
end
function on_message(self, message_id, message, sender)
-- Add message-handling code here
-- Learn more: https://defold.com/manuals/message-passing/
-- Remove this function if not needed
end
function on_input(self, action_id, action)
if action.x then
self.target.x = action.x
self.target.y = action.y
end
if action.released then
self.position.x = action.x
self.position.y = action.y
end
end
function on_reload(self)
-- Add reload-handling code here
-- Learn more: https://defold.com/manuals/hot-reload/
-- Remove this function if not needed
end
Sort of related if you want to do lasers
LaserExample.zip (4.0 KB)
In this picture, we have an incoming ray with a direction v relative to the plane we want to reflect with.
Then the formula is r = v - 2 * dot(v, n) * n
, where the n is the normalized normal (unit length equals 1) of the plane.
In Defold:
local r = v - (2 * vmath.dot(v, normal)) * normal
Sometimes you want to use actual positions, not only directions. Then you need to convert your coordinates into plane space, by picking an (arbitrary) point on the plane.
local v = plane_pos - world_pos -- v now points towards the plane
and once you’re done calculating r, you’ll want to convert back into world space again:
local world_reflection = plane_pos + r
this works in both 2D and 3D.
I hope this helps!
Awesome, Thanks for the help. This will really help me.