local u=require(script.Parent.OctreeRegionUtils)local W={}W.ClassName="\079\099\116\114\101\101\078\111\100\101"W.__index=W function W.new(u,O)local Q=setmetatable({},W)Q._octree=u or error("\078\111 \111\099\116\114\101\101")Q._object=O or error("\078\111 \111\098\106\101\099\116")Q._currentLowestRegion=nil Q._position=nil return Q end function W.KNearestNeighborsSearch(O,u,W)return O._octree:KNearestNeighborsSearch(O._position,u,W)end function W.GetObject(u)return u._object end function W.RadiusSearch(W,u)return W._octree:RadiusSearch(W._position,u)end function W.GetPosition(u)return u._position end function W.GetRawPosition(u)return u._px,u._py,u._pz end function W.SetPosition(O,W)if O._position==W then return end local Q,v,Z=W.x,W.y,W.z O._px=Q O._py=v O._pz=Z O._position=W if O._currentLowestRegion then if u.inRegionBounds(O._currentLowestRegion,Q,v,Z)then return end end local l=O._octree:GetOrCreateLowestSubRegion(Q,v,Z)if O._currentLowestRegion then u.moveNode(O._currentLowestRegion,l,O)else u.addNode(l,O)end O._currentLowestRegion=l end function W.Destroy(W)if W._currentLowestRegion then u.removeNode(W._currentLowestRegion,W)end end return W

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
