function boost_cart:get_sign(z)
	if z == 0 then
		return 0
	else
		return z / math.abs(z)
	end
end

function boost_cart:velocity_to_dir(v)
	if math.abs(v.x) > math.abs(v.z) then
		return {x=boost_cart:get_sign(v.x), y=boost_cart:get_sign(v.y), z=0}
	else
		return {x=0, y=boost_cart:get_sign(v.y), z=boost_cart:get_sign(v.z)}
	end
end

function boost_cart:is_rail(pos)
	local node = minetest.get_node(pos).name
	return minetest.get_item_group(node, "rail") ~= 0
end

function boost_cart:get_rail_direction(pos_, dir_, ctrl, old_switch)
	local pos = vector.round(pos_)
	local dir = vector.new(dir_)
	local cur = nil
	local left_check, right_check = true, true
	old_switch = old_switch or 0
	
	-- Check left and right
	local left = {x=0, y=0, z=0}
	local right = {x=0, y=0, z=0}
	if dir.z ~= 0 and dir.x == 0 then
		left.x = -dir.z
		right.x = dir.z
	elseif dir.x ~= 0 and dir.z == 0 then
		left.z = dir.x
		right.z = -dir.x
	end
	
	if ctrl then
		if old_switch == 1 then
			left_check = false
		elseif old_switch == 2 then
			right_check = false
		end
		if ctrl.left and left_check then
			cur = vector.add(pos, left)
			if boost_cart:is_rail(cur) then
				return left, 1
			end
			left_check = false
		end
		if ctrl.right and right_check then
			cur = vector.add(pos, right)
			if boost_cart:is_rail(cur) then
				return right, 2
			end
			right_check = true
		end
	end
	
	-- Front
	dir.y = 0
	cur = vector.add(pos, dir)
	if boost_cart:is_rail(cur) then
		return dir
	end
	
	-- Down
	dir.y = -1
	cur = vector.add(pos, dir)
	if boost_cart:is_rail(cur) then
		return dir
	end
	
	-- Up
	dir.y = 1
	cur = vector.add(pos, dir)
	if boost_cart:is_rail(cur) then
		return dir
	end
	
	-- Left, if not already checked
	if left_check then
		cur = vector.add(pos, left)
		if boost_cart:is_rail(cur) then
			return left
		end
	end
	
	-- Right, if not already checked
	if right_check then
		cur = vector.add(pos, right)
		if boost_cart:is_rail(cur) then
			return right
		end
	end
	
	return {x=0, y=0, z=0}
end
