ios - Swift : ARKit Save ARPlaneAnchor for next session -


arkit quite new , quite new in swift... i'm having troubles...

i'd save arplaneanchor detected during session , reload them when relaunch app. phone @ same place , i'd scan room 1 time. , remembering anchor found in room everytime launch app.

i tried several solutions :

solution1 : save arplaneanchor using : nskeyedarchiver.archiverootobject(plane, tofile: filepath)

i got error :

terminating app due uncaught exception 'nsinvalidargumentexception', reason: '-[arplaneanchor encodewithcoder:]: unrecognized selector sent instance

i think maybe can't save kind of data locally

solution2 : store datas of arplaneanchor intantiate them when launch app. datas float. creat aranchor easily, cast them arplaneanchor, not modify "center" , "extend" parameter of arplaneanchor because have getter , not setter. can't create anchors.

i open anysolution. think need store aranchor object, not find way without crash! if can me grateful.

first... if app restricted situation device permanently installed , user can never move or rotate it, using arkit display overlay content on camera feed sort of "killing mosquitos cannon" kind of situation. work out @ development time kind of camera projection 3d engine needs, use "dumb" camera feed 3d engine running on top, , not need ios 11 or arkit-capable device.

so might want think use case or technology stack more before commit specific solutions , workarounds.


as more specific problem...

arplaneanchor entirely read-only class, because use case entirely read-only. exists sole purpose of giving arkit way give information detected planes. however, once have information, can whatever want. , there on, don't need keep arplaneanchor in equation anymore.

perhaps you're confused because of typical use case plane detection (and scenekit-based display):

  1. turn on plane detection
  2. respond renderer(_:didadd:for:) receive arplaneanchor objects
  3. in method, return virtual content associate plane anchor
  4. let arscnview automatically position content follows plane's position

if plane's position static respect camera, though, don't need that.

you need arkit handle placement of content within scene if placement needs ongoing management, case when plane detection live (arkit refines estimates of plane location , extent , updates anchor accordingly). if did plane-finding ahead of time, won't getting updates, don't need arkit manage updates.

instead steps can more this:

  1. know plane (position in world space).
  2. set position of virtual content position of plane.
  3. add content scene directly.

in other words, "solution 2" step in right direction, not far enough. want archive not arplaneanchor instance itself, information contains — , when unarchiving, don't need re-create arplaneanchor instance, need use information.

so, if place content "live" plane detection:

func renderer(_ renderer: scnscenerenderer, didadd node: scnnode, anchor: aranchor) {     guard let planeanchor = anchor as? arplaneanchor else { return }     let extent = planeanchor.extent     let center = planeanchor.center     // planeanchor.transform not used, because arscnview automatically applies     // container node, , make child of container node      let plane = scnplane(width: cgfloat(extent.x), height: cgfloat(extent.z))     let planenode = scnnode(geometry: plane)     planenode.eulerangles.x = .pi / 2     planenode.simdposition = center     node.addchildnode(planenode) } 

then can static content placement:

struct planeinfo { // save , restore arplaneanchor data     let transform: float4x4     let center: float3     let extent: float3 } func makeplane(from planeinfo: planeinfo) { // call when place content     let extent = planeinfo.extent     let center = float4(planeinfo.center, 1) * planeinfo.transform     // we're positioning content in world space, center     // offset relative transform      let plane = scnplane(width: cgfloat(extent.x), height: cgfloat(extent.z))     let planenode = scnnode(geometry: plane)     planenode.eulerangles.x = .pi / 2     planenode.simdposition = center.xyz     view.scene.rootnode.addchildnode(planenode) }  // convenience vector-width conversions used above extension float4 {     init(_ xyz: float3, _ w: float) {         self.init(xyz.x, xyz.y, xyz.z, 1)     }     var xyz: float3 {         return float3(self.x, self.y, self.z)     } } 

Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -