Трекинг поверхностей¶
Трекинг поверхностей - обнаружение горизонтальных и вертикальных поверхностей в окружающей среде, например пола или стен. Часто используется в AR приложениях для размещения на обнаруженных поверхностях виртуальных объектов. Использует камеру, сенсоры устройства, а также алгоритмы. Может не работать в плохо освещенной среде и на отражающих поверхностях.
На устройствах с iOS осуществляется с помощью технологии ARKit, на устройствах с Android - с помощью ARCore.
Код для версии Advanced, пример на нашем гитхабе:
local sys = evi.os()
local info_txt = getReactorOrDie("info_txt")
local button = getReactorOrDie("btn")
local ar_plane_transform = getReactorOrDie("ar_plane_transform")
local plane_image = getReactorOrDie("plane/image")
local plane_model = getReactorOrDie("plane/model")
-- initial state
button:hide(0x0) -- not visible, not clickable
ar_plane_transform:hide() -- just hide (does not matter if clickable or not)
plane_image:show() -- just show (does not matter if clickable or not)
plane_model:hide()
-- NOTE: trackingSystem is global (used by TrackingSystemReactor also)
local busARCore = trackingSystem.busARCore
local busARKit = trackingSystem.busARKit
-- Symlinks for clean code
local busAR = busARCore and busARCore or busARKit
local BusAR_Class = busARCore and evar.BusARCore or evar.BusARKit
if not busAR then
local msg = "Cannot detect ARKit/ARcore"
if sys == "android" then
msg = msg .. "\nPlease install Google Play Services for AR"
end
logger:error(msg)
info_txt.text.value = msg
info_txt.text.color = osg.Vec4(1.0, 0.0, 0.0, 1.0)
return
end
local planeFindingMode = bit_or(BusAR_Class.PLANE_HORIZONTAL, BusAR_Class.PLANE_VERTICAL)
busAR:setPlaneFindingModeMask(planeFindingMode)
-- NOTE: Use busAR:setPlaneFindingModeMask(0) to stop finding planes (will improve performance)
local function showPlane()
ar_plane_transform:show()
button:show(bit_or(NodeReactor.Mask.VISIBLE, NodeReactor.Mask.CLICKABLE))
end
local function onPlaneEnter()
logger:info("Plane entered")
showPlane()
end
local function onPlaneMove(mat)
local m = evar.evar2osg(mat, false)
ar_plane_transform.node:setMatrix(m)
if not ar_plane_transform.visible then
showPlane()
end
end
local function onPlaneLeave()
logger:info("Plane leave")
ar_plane_transform:hide(0x0)
button:hide(0x0)
end
local classification, min_area, min_distance, max_distance = BusAR_Class.MarkerPlane.PLANE_CLASS_NONE, 1.0, 1.0, 5.0
local planeTraits = BusAR_Class.MarkerPlane.Traits(classification, min_area, min_distance, max_distance)
local markerPlaneImpl = BusAR_Class.MarkerPlane(planeTraits) -- markerImpl ref. by the handler
markerImplHandler = nil -- handler not ref. by busARCore/busARKit, so create it global, this will be fixed in the future releases
if busARCore then
markerImplHandler = evar.BusARCore.Marker.HandlerLua(markerPlaneImpl, onPlaneEnter, onPlaneMove, onPlaneLeave)
else
markerImplHandler = evar.BusARKit.Marker.HandlerLua(markerPlaneImpl, trackingSystem.bus, onPlaneEnter, onPlaneMove, onPlaneLeave)
end
busAR:addListener(markerImplHandler) -- handler not ref. by busARCore/busARKit
busAR:addMarker(markerPlaneImpl)
ar_plane_transform:subscribeEvent("onShowed", function()
info_txt:hide()
end)
ar_plane_transform:subscribeEvent("onHidden", function()
info_txt:show()
end)
button:subscribeEvent("onDown", function()
if markerPlaneImpl:isTagged() then
markerPlaneImpl:untag()
button.text.value = "ПОМЕСТИТЬ"
plane_image:show()
plane_model:hide()
else
markerPlaneImpl:tag()
button.text.value = "ПЕРЕМЕСТИТЬ"
plane_image:hide()
plane_model:show()
end
end)