local vector3_metamethod = {
	__add = function(v1, v2)
		return {
			["x"] = v1.x + v2.x,
			["y"] = v1.y + v2.y,
			["z"] = v1.z + v2.z
		}
	end,
    __sub = function(v1, v2)
		return {
			["x"] = v1.x - v2.x,
			["y"] = v1.y - v2.y,
			["z"] = v1.z - v2.z
		}
	end,
    __mul = function(v1, v2)
		if ((type(v1):match("userdata") or type(v1):match("table")) and (type(v2):match("userdata") or type(v2):match("table"))) then
			return {
				["x"] = v1.x * v2.x,
				["y"] = v1.y * v2.y,
				["z"] = v1.z * v2.z
			}
		end
		if ((type(v1):match("userdata") or type(v1):match("table")) and type(v2):match("number")) then
			return {
				["x"] = v1.x * v2,
				["y"] = v1.y * v2,
				["z"] = v1.z * v2
			}
		end
		if ((type(v2):match("userdata") or type(v2):match("table")) and type(v1):match("number")) then
			return {
				["x"] = v1 * v2.x,
				["y"] = v1 * v2.y,
				["z"] = v1 * v2.z
			}
		end
	end,
    __div = function(v1, v2)
		if ((type(v1):match("userdata") or type(v1):match("table")) and (type(v2):match("userdata") or type(v2):match("table"))) then
			return {
				["x"] = v1.x / v2.x,
				["y"] = v1.y / v2.y,
				["z"] = v1.z / v2.z
			}
		end
		if ((type(v1):match("userdata") or type(v1):match("table")) and type(v2):match("number")) then
			return {
				["x"] = v1.x / v2,
				["y"] = v1.y / v2,
				["z"] = v1.z / v2
			}
		end
		if ((type(v2):match("userdata") or type(v2):match("table")) and type(v1):match("number")) then
			return {
				["x"] = v1 / v2.x,
				["y"] = v1 / v2.y,
				["z"] = v1 / v2.z
			}
		end
	end
}

vector3 = function(...)
	local args = {...}
	local v3 = {}
	if type(...):match("userdata") or type(...):match("table") then
		local vec_f = ...
		v3.x = vec_f.x
		v3.y = vec_f.y
		v3.z = vec_f.z
	else
		v3.x = args[1]
		v3.y = args[2]
		v3.z = args[3]
	end
	setmetatable(v3, vector3_metamethod)
	return v3
end