Skip to content

Commit

Permalink
Added event functions for ARKit anchor events to AKDevice
Browse files Browse the repository at this point in the history
Summary: Now, each AKDevice can react to anchor events.

Reviewed By: enpe

Differential Revision:
D65502864

Privacy Context Container: L1191897

fbshipit-source-id: 26a71c8753cf86760eb2fa1c1de2eb2f84e94261
  • Loading branch information
janherling authored and facebook-github-bot committed Nov 6, 2024
1 parent 00a05bc commit a7707da
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 35 deletions.
28 changes: 28 additions & 0 deletions impl/ocean/devices/arkit/AKDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ class OCEAN_DEVICES_ARKIT_EXPORT AKDevice : virtual public Device
TC_FACE = 1u << 5u
};

/**
* Definition of a vector holding ARAnchors.
*/
using ARAnchors = std::vector<ARAnchor*>;

/**
* Definition of an unordered map mapping devices to usage counters.
*/
using DeviceMap = std::unordered_map<AKDevice*, unsigned int>;

protected:

/**
Expand Down Expand Up @@ -145,6 +155,24 @@ class OCEAN_DEVICES_ARKIT_EXPORT AKDevice : virtual public Device
*/
inline TrackerCapabilities trackerCapabilities() const;

/**
* Event function for added anchors.
* @param anchors The added anchors, at least one
*/
virtual void onAddedAnchors(const ARAnchors& anchors);

/**
* Event function for updated anchors.
* @param anchors The updated anchors, at least one
*/
virtual void onUpdateAnchors(const ARAnchors& anchors);

/**
* Event function for removed anchors.
* @param anchors The removed anchors, at least one
*/
virtual void onRemovedAnchors(const ARAnchors& anchors);

/**
* Translates the value of an ARGeoTrackingState to a readable string.
* @param state The state to translate
Expand Down
114 changes: 79 additions & 35 deletions impl/ocean/devices/arkit/AKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ @implementation AKTracker6DOFDelegate
Media::LiveVideoRef inputLiveVideo_;

/// The map mapping devices to reference counters.
std::unordered_map<AKDevice*, unsigned int> deviceMap_;
AKDevice::DeviceMap deviceMap_;

/// The map mapping object ids to anchors.
std::unordered_map<Devices::Measurement::ObjectId, ARAnchor*> anchorMap_;
/// The map mapping object ids to geo anchors.
std::unordered_map<Devices::Measurement::ObjectId, ARAnchor*> geoAnchorMap_;

/// The last ARGeoTrackingState value.
API_AVAILABLE(ios(14.0)) ARGeoTrackingState lastARGeoTrackingState_;
Expand All @@ -58,6 +58,9 @@ @implementation AKTracker6DOFDelegate
/// The last ARGeoTrackingAccuracy value.
API_AVAILABLE(ios(14.0)) ARGeoTrackingAccuracy lastARGeoTrackingAccuracy_;

/// Reusable anchors.
AKDevice::ARAnchors reusableAnchors_;

/// The delegate's lock.
@public Lock lock_;
}
Expand Down Expand Up @@ -97,7 +100,7 @@ - (bool)restart:(AKDevice*)device withMedium:(const Media::LiveVideoRef&)inputLi
}

#ifdef OCEAN_DEBUG
for (std::unordered_map<AKDevice*, unsigned int>::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
for (AKDevice::DeviceMap::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
{
ocean_assert(iDevice->first == device || iDevice->first->name() != device->name());
}
Expand Down Expand Up @@ -375,7 +378,7 @@ - (bool)pause:(AKDevice*)tracker

- (bool)stop:(AKDevice*)tracker
{
std::unordered_map<AKDevice*, unsigned int>::iterator iDevice = deviceMap_.find(tracker);
AKDevice::DeviceMap::iterator iDevice = deviceMap_.find(tracker);
ocean_assert(iDevice != deviceMap_.cend());
ocean_assert(iDevice->second >= 1u);

Expand All @@ -399,12 +402,12 @@ - (bool)stop:(AKDevice*)tracker
return false;
}

for (std::pair<Devices::Measurement::ObjectId, ARAnchor*> pair : anchorMap_)
for (std::pair<Devices::Measurement::ObjectId, ARAnchor*> pair : geoAnchorMap_)
{
[arSession_ removeAnchor:pair.second];
}

anchorMap_.clear();
geoAnchorMap_.clear();

[arSession_ pause];

Expand Down Expand Up @@ -432,7 +435,7 @@ - (bool)addGeoAnchor:(Devices::Measurement::ObjectId)objectId withLatitude:(doub
return false;
}

if (anchorMap_.find(objectId) != anchorMap_.cend())
if (geoAnchorMap_.find(objectId) != geoAnchorMap_.cend())
{
ocean_assert(false && "This should never happen!");
return false;
Expand Down Expand Up @@ -473,7 +476,7 @@ - (bool)addGeoAnchor:(Devices::Measurement::ObjectId)objectId withLatitude:(doub

[arSession_ addAnchor:geoAnchor];

anchorMap_.emplace(objectId, geoAnchor);
geoAnchorMap_.emplace(objectId, geoAnchor);

return true;
}
Expand All @@ -483,17 +486,17 @@ - (bool)addGeoAnchor:(Devices::Measurement::ObjectId)objectId withLatitude:(doub

- (bool)removeGeoAnchor:(Devices::Measurement::ObjectId)objectId
{
const std::unordered_map<Devices::Measurement::ObjectId, ARAnchor*>::const_iterator iAnchor = anchorMap_.find(objectId);
const std::unordered_map<Devices::Measurement::ObjectId, ARAnchor*>::const_iterator iAnchor = geoAnchorMap_.find(objectId);

if (iAnchor == anchorMap_.cend())
if (iAnchor == geoAnchorMap_.cend())
{
ocean_assert(false && "This should never happen!");
return false;
}

[arSession_ removeAnchor:iAnchor->second];

anchorMap_.erase(iAnchor);
geoAnchorMap_.erase(iAnchor);

return true;
}
Expand Down Expand Up @@ -565,7 +568,7 @@ - (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame

bool containsGeoTracker = false;

for (std::unordered_map<AKDevice*, unsigned int>::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
for (AKDevice::DeviceMap::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
{
AKDevice* device = iDevice->first;

Expand Down Expand Up @@ -655,35 +658,61 @@ - (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame

- (void)session:(ARSession *)session didAddAnchors:(NSArray<__kindof ARAnchor *> *)anchors
{
if (@available(iOS 14.0, *))
ocean_assert(anchors.count > 0);

reusableAnchors_.clear();
reusableAnchors_.reserve(anchors.count);

for (ARAnchor* anchor in anchors)
{
#ifdef OCEAN_DEBUG
for (ARAnchor* anchor in anchors)
{
const std::string anchorName = StringApple::toUTF8(anchor.name);
if (!anchorName.empty())
{
Log::debug() << "Added anchor with id '" << anchorName;
}
}
#endif
reusableAnchors_.push_back(anchor);
}

const ScopedLock scopedLock(lock_);

for (AKDevice::DeviceMap::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
{
iDevice->first->onAddedAnchors(reusableAnchors_);
}
}

- (void)session:(ARSession *)session didUpdateAnchors:(NSArray<__kindof ARAnchor *> *)anchors
{
ocean_assert(anchors.count > 0);

reusableAnchors_.clear();
reusableAnchors_.reserve(anchors.count);

for (ARAnchor* anchor in anchors)
{
reusableAnchors_.push_back(anchor);
}

const ScopedLock scopedLock(lock_);

for (AKDevice::DeviceMap::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
{
iDevice->first->onUpdateAnchors(reusableAnchors_);
}
}

- (void)session:(ARSession *)session didRemoveAnchors:(NSArray<__kindof ARAnchor *> *)anchors
{
if (@available(iOS 14.0, *))
ocean_assert(anchors.count > 0);

reusableAnchors_.clear();
reusableAnchors_.reserve(anchors.count);

for (ARAnchor* anchor in anchors)
{
#ifdef OCEAN_DEBUG
for (ARAnchor* anchor in anchors)
{
const std::string anchorName = StringApple::toUTF8(anchor.name);
if (!anchorName.empty())
{
Log::debug() << "Removed anchor with id '" << anchorName;
}
}
#endif
reusableAnchors_.push_back(anchor);
}

const ScopedLock scopedLock(lock_);

for (AKDevice::DeviceMap::const_iterator iDevice = deviceMap_.cbegin(); iDevice != deviceMap_.cend(); ++iDevice)
{
iDevice->first->onRemovedAnchors(reusableAnchors_);
}
}

Expand Down Expand Up @@ -933,6 +962,21 @@ + (ARVideoFormat*)determinePreferredVideoFormat:(NSArray<ARVideoFormat *> *)supp
return nameARKitLibrary();
}

void AKDevice::onAddedAnchors(const ARAnchors& /*anchors*/)
{
// nothing to do here
}

void AKDevice::onUpdateAnchors(const ARAnchors& /*anchors*/)
{
// nothing to do here
}

void AKDevice::onRemovedAnchors(const ARAnchors& /*anchors*/)
{
// nothing to do here
}

API_AVAILABLE(ios(14.0))
std::string AKDevice::translateGeoTrackingState(const ARGeoTrackingState& state)
{
Expand Down

0 comments on commit a7707da

Please sign in to comment.