---@class Vector3 local Vector3 = {} Vector3.__index = Vector3 function Vector3.new(x, y, z) return setmetatable({ x = x or 0, y = y or 0, z = z or 0 }, Vector3) end function Vector3:copy() return Vector3.new(self.x, self.y, self.z) end function Vector3:__tostring() return string.format("Vector3(%.3f, %.3f, %.3f)", self.x, self.y, self.z) end function Vector3:add(v) return Vector3.new(self.x + v.x, self.y + v.y, self.z + v.z) end function Vector3:sub(v) return Vector3.new(self.x - v.x, self.y - v.y, self.z - v.z) end function Vector3:mul(scalar) return Vector3.new(self.x * scalar, self.y * scalar, self.z * scalar) end function Vector3:div(scalar) return Vector3.new(self.x / scalar, self.y / scalar, self.z / scalar) end function Vector3.__add(self, v) return Vector3.new(self.x + v.x, self.y + v.y, self.z + v.z) end function Vector3.__sub(self, v) return Vector3.new(self.x - v.x, self.y - v.y, self.z - v.z) end function Vector3:length() return math.sqrt(self.x^2 + self.y^2 + self.z^2) end function Vector3:lengthSq() return self.x^2 + self.y^2 + self.z^2 end function Vector3:normalize() local len = self:length() if len == 0 then return Vector3.new(0, 0, 0) end return Vector3.new(self.x / len, self.y / len, self.z / len) end function Vector3:dot(v) return self.x * v.x + self.y * v.y + self.z * v.z end function Vector3:cross(v) return Vector3.new( self.y * v.z - self.z * v.y, self.z * v.x - self.x * v.z, self.x * v.y - self.y * v.x ) end function Vector3:distanceTo(v) return (self:sub(v)):length() end function Vector3:distanceToSq(v) return (self:sub(v)):lengthSq() end function Vector3:equals(v, epsilon) epsilon = epsilon or 1e-5 return math.abs(self.x - v.x) < epsilon and math.abs(self.y - v.y) < epsilon and math.abs(self.z - v.z) < epsilon end function Vector3:map(func) return Vector3.new(func(self.x), func(self.y), func(self.z)) end function Vector3:toTable() return { x = self.x, y = self.y, z = self.z } end function Vector3.fromTable(tbl) return Vector3.new(tbl.x, tbl.y, tbl.z) end function Vector3.fromArray(tbl) return Vector3.new(tbl[1], tbl[2], tbl[3]) end function Vector3:unpack() return self.x, self.y, self.z end function Vector3:toArray() return {self.x, self.y, self.z} end return Vector3