local Y=require(script.Parent.OctreeRegionUtils)local n={}n.ClassName="\079\099\116\114\101\101\078\111\100\101"n.__index=n function n.new(Y,o)local C=setmetatable({},n)C._octree=Y or error("\078\111 \111\099\116\114\101\101")C._object=o or error("\078\111 \111\098\106\101\099\116")C._currentLowestRegion=nil C._position=nil return C end function n.KNearestNeighborsSearch(o,Y,n)return o._octree:KNearestNeighborsSearch(o._position,Y,n)end function n.GetObject(Y)return Y._object end function n.RadiusSearch(n,Y)return n._octree:RadiusSearch(n._position,Y)end function n.GetPosition(Y)return Y._position end function n.GetRawPosition(Y)return Y._px,Y._py,Y._pz end function n.SetPosition(o,n)if o._position==n then return end local C,b,v=n.x,n.y,n.z o._px=C o._py=b o._pz=v o._position=n if o._currentLowestRegion then if Y.inRegionBounds(o._currentLowestRegion,C,b,v)then return end end local M=o._octree:GetOrCreateLowestSubRegion(C,b,v)if o._currentLowestRegion then Y.moveNode(o._currentLowestRegion,M,o)else Y.addNode(M,o)end o._currentLowestRegion=M end function n.Destroy(n)if n._currentLowestRegion then Y.removeNode(n._currentLowestRegion,n)end end return n
--- Basic node interacting with the octree
-- @classmod OctreeNode
local OctreeRegionUtils = require(script.Parent.OctreeRegionUtils)

local OctreeNode = {}
OctreeNode.ClassName = "OctreeNode"
OctreeNode.__index = OctreeNode

function OctreeNode.new(octree, object)
	local self = setmetatable({}, OctreeNode)

	self._octree = octree or error("No octree")
	self._object = object or error("No object")

	self._currentLowestRegion = nil
	self._position = nil

	return self
end

function OctreeNode:KNearestNeighborsSearch(k, radius)
	return self._octree:KNearestNeighborsSearch(self._position, k, radius)
end

function OctreeNode:GetObject()
	return self._object
end

function OctreeNode:RadiusSearch(radius)
	return self._octree:RadiusSearch(self._position, radius)
end

function OctreeNode:GetPosition()
	return self._position
end

function OctreeNode:GetRawPosition()
	return self._px, self._py, self._pz
end

function OctreeNode:SetPosition(position)
	if self._position == position then
		return
	end

	local px, py, pz = position.x, position.y, position.z

	self._px = px
	self._py = py
	self._pz = pz
	self._position = position

	if self._currentLowestRegion then
		if OctreeRegionUtils.inRegionBounds(self._currentLowestRegion, px, py, pz) then
			return
		end
	end

	local newLowestRegion = self._octree:GetOrCreateLowestSubRegion(px, py, pz)

	-- Sanity check for debugging
	-- if not OctreeRegionUtils.inRegionBounds(newLowestRegion, px, py, pz) then
	-- 	error("[OctreeNode.SetPosition] newLowestRegion is not in region bounds!")
	-- end

	if self._currentLowestRegion then
		OctreeRegionUtils.moveNode(self._currentLowestRegion, newLowestRegion, self)
	else
		OctreeRegionUtils.addNode(newLowestRegion, self)
	end

	self._currentLowestRegion = newLowestRegion
end

function OctreeNode:Destroy()
	if self._currentLowestRegion then
		OctreeRegionUtils.removeNode(self._currentLowestRegion, self)
	end
end

return OctreeNode
