local x={}x.__index=x local X X={default=function(X,C)local b=setmetatable({},x)b.MinV=X b.MaxV=C return b end;CF_Size=function(x,C)local b=math.abs local L,t,d=C.X,C.Y,C.Z local n,r,h,A,O,y,P,l,S,V,j,z=x:components()local f=.5*((b(A)*L+b(O)*t)+b(y)*d)local e=.5*((b(P)*L+b(l)*t)+b(S)*d)local o=.5*((b(V)*L+b(j)*t)+b(z)*d)local Z=n-f local s=r-e local v=h-o local M=n+f local F=r+e local u=h+o local i,U=Vector3.new(Z,s,v),Vector3.new(M,F,u)return X.default(i,U)end;part=function(x)return X.CF_Size(x.CFrame,x.Size)end}function x.new(...)local x=select("\035",...)local C={...}if x==1 and typeof(C[1])=="\073\110\115\116\097\110\099\101"then return X.part(...)elseif x==2 and(typeof(C[1])=="\067\070\114\097\109\101"and typeof(C[2])=="\086\101\099\116\111\114\051")then return X.CF_Size(...)elseif x==2 and(typeof(C[1])=="\086\101\099\116\111\114\051"and typeof(C[2])=="\086\101\099\116\111\114\051")then return X.default(...)else error("\073\110\099\111\114\114\101\099\116 \103\105\118\101\110 \112\097\114\097\109\101\116\101\114\115")end end function x.isInArea(X,x)return X.MinV.X<=x.X and(x.X<=X.MaxV.X and(X.MinV.Y<=x.Y and(x.Y<=X.MaxV.Y and(X.MinV.Z<=x.Z and x.Z<=X.MaxV.Z))))end function x.getCF_Size(x)local X=Region3.new(x.MinV,x.MaxV)return X.CFrame,X.Size end return x
-- basically my own datatype
local Area = {}
Area.__index = Area


local constructors
constructors = {
   default = function(minVector3, maxVector3)
        local self = setmetatable({}, Area)
        self.MinV = minVector3
        self.MaxV = maxVector3
        return self
    end,
    CF_Size = function (CFrame, Size )
        local abs = math.abs
        local sx, sy, sz = Size.X, Size.Y, Size.Z -- this causes 3 Lua->C++ invocations

        local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = CFrame:components() -- this causes 1 Lua->C++ invocations and gets all components of cframe in one go, with no allocations

        -- https://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
        local wsx = 0.5 * (abs(R00) * sx + abs(R01) * sy + abs(R02) * sz) -- this requires 3 Lua->C++ invocations to call abs, but no hash lookups since we cached abs value above; otherwise this is just a bunch of local ops
        local wsy = 0.5 * (abs(R10) * sx + abs(R11) * sy + abs(R12) * sz) -- same
        local wsz = 0.5 * (abs(R20) * sx + abs(R21) * sy + abs(R22) * sz) -- same

        -- just a bunch of local ops
        local minx = x - wsx
        local miny = y - wsy
        local minz = z - wsz

        local maxx = x + wsx
        local maxy = y + wsy
        local maxz = z + wsz

        local minv, maxv = Vector3.new(minx, miny, minz), Vector3.new(maxx, maxy, maxz)
        -- credit for conversion https://devforum.roblox.com/t/part-to-region3-help/251348/5
        return constructors.default(minv , maxv)
    end,
    part = function(part)
        return constructors.CF_Size(part.CFrame, part.Size)
    end
}

function Area.new(...) -- constructors for Area
    local n = select("#", ...)
    local args = {...}

    if n == 1 and typeof(args[1]) == "Instance" then
        return constructors.part(...)
    elseif  n == 2 and typeof(args[1]) == "CFrame" and typeof(args[2]) == "Vector3" then
        return  constructors.CF_Size(...)
    elseif  n == 2 and typeof(args[1]) == "Vector3" and typeof(args[2]) == "Vector3" then
        return constructors.default(...)
    else
        error("Incorrect given parameters")
    end
end

function Area:isInArea(position) -- expects a vector3 instance, returns true if the position is inside the area
    return self.MinV.X <= position.X and position.X <= self.MaxV.X and self.MinV.Y <= position.Y and position.Y <= self.MaxV.Y and self.MinV.Z <= position.Z and position.Z <= self.MaxV.Z
end

function Area:getCF_Size()
    local region = Region3.new(self.MinV, self.MaxV)
    return region.CFrame, region.Size
end

return Area