Unparing a networked iPhone in devices and simulators worked for me too.
Post
Replies
Boosts
Views
Activity
I have the same problem wth the public database but mine is compounded with needing to be pre-seeded with a few thousand records. Some devices happily update when you add new records, some do not This may be an ios 15 beta issue). All are using the same apple id. I also found that the CDMR type was never added to the dashboard despite there being logical connections between entities in coredata, so I had to create that by hand. Deleting records from the public database through the dashboard never seem to be reflected on the local database.
I'm now only getting the error on a device with iOS15 beta installed. And that device also seems to fail to sync with new server data. IOS14 devices have no errors and receive new records added by a different device. Syncing with private databases works fine on ios15 but public throws the error described above and never seems to receive updates.
I have the same stutter scrolling on a pro-motion device when using a regular UIScrollview and a content offset. Older devices work fine, turning off pro-motion on the iphone 13 stops it too.
My understanding is that if you want access to the RoomPlan session you need to use the data api rather than the RoomCaptureView. You create a RoomCaptureSession and hand that over to an ARSCNView and listen to all the callbacks from the RoomCaptureSessionDelegate. It will update you with a new version of the room as it finds it. It's up to you to then build the room from the data it gives you. This was the conversation I had with the apple engineer this morning, but I've yet to try it.
I just got it to work with this code
private var roomCaptureSessionConfig: RoomCaptureSession.Configuration = RoomCaptureSession.Configuration()
var arSceneView: ARSCNView!
var session:RoomCaptureSession!
override func viewDidLoad() {
super.viewDidLoad()
arSceneView = ARSCNView.init(frame: self.view.bounds)
self.view.addSubview(arSceneView)
roomCaptureSessionConfig.isCoachingEnabled = true
session = RoomCaptureSession()
session.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
session.run(configuration: roomCaptureSessionConfig)
}
func captureSession(_ session: RoomCaptureSession, didStartWith configuration: RoomCaptureSession.Configuration){
arSceneView.session = session.arSession
}
No specifically. Though you can infer the ceiling height from the height of the walls - presuming your walls are all the same height. Slipping and drop ceilings confuse Roomplan. It doesn't give you the floor either. The coordinate system if relative to the point the device was first fired up.
If you find the corner vertices of your walls you can create the floor using an extruded SCNShape. The tricky part is to make sure your vertices are in logical order, but after that, you can draw a bezier it using the x and z coordinates of your points. You'll have to rotate it by 90 degrees and position it but it should already have the correct rotation. This will help if your room is not rectangular. I'd add code but it's still on my list of things to do I'm afraid. But broadly my plan is to pick a wall and choose a corner, find the wall that's got a corner in the same position, presume it's the next in line and iterate through all the outside walls.
But a quick and dirty way if your room is always rectangular is to find the rotation of the longest wall and rotate your floor by the same angle.
Yes, the CapturedRoom.surface has a category that includes door(isOpen:Bool) which will give you that information. I have occasionally seen open doors classified as openings instead of doors that are open, so it's best to prompt the user to close doors to be sure.
Another option is to export the CapturedRoom as a parametric file that you can use later. CapturedRoom confirms to Encodable so it can be turned into a JSON file if you want to import it later. The only fly in the ointment is that it looks like the serialising is currently broken. It throws an error on re-importing dimensions. For our apps, we have written our own encodable struct to handle saving. But it means that we can pass the parametric room information between apps and people very simply. Obviously, this only works if you have control over the whole process.
setNeedsUpdateOfSupportedInterfaceOrientations is a method of UIViewController it seems not UIWindow.
I may have a solution for finding the the local coordinates of the window in the wall. What I did was to rotate the centerpoint of window or door around by the angle of the wall (which should be the same as the window angle) to make them essentially parallel to the x axis. Then I check that the distance between their position.z is very small (so in the same plane) then it's relatively simple to find the relative center point of the windows by subtracting it from the wall center point. Then to top left and bottom right points are that center point plus the width and height of the window.
Roomkit occasionally puts windows and doors through the edge of the wall so I constrain it to just inside.
This function runs on the window surface
func surfaceIsWithinSurface(wall:CodableWall)->Bool{
var angle:Float = transform.eulerAngles.y
let wallPosition = CGPoint.init(wall.transform.position)
let myPosition = CGPoint.init(self.transform.position)
let newPosition = myPosition.pointRotated(aroundOrigin: wallPosition, byRadians: CGFloat(angle))
let offset = wallPosition - newPosition
let floorOffset = wall.position.y - wall.halfHeight
let heightOffset = self.position.y - floorOffset
let centerPoint:SCNVector3 = SCNVector3.init(x: Float(offset.x), y: heightOffset , z: Float(offset.y))
guard abs(centerPoint.z) < 0.1 else {return false}
var right = centerPoint.x + halfWidth + wall.halfWidth
var left = centerPoint.x - halfWidth + wall.halfWidth
var top = centerPoint.y + halfHeight
var bottom = centerPoint.y - halfHeight
let smidge:Float = 0.01
top = min (top, wall.dimensions.y - smidge)
right = min (right, wall.dimensions.x - smidge)
left = max (left, smidge)
bottom = max (bottom, smidge)
topLeft = CGPoint(x: left - wall.halfWidth, y: top)
bottomRight = CGPoint(x: right - wall.halfWidth, y: bottom)
return true
}
extension CGPoint
init (_ vector:SCNVector3){
self.init(x: vector.x, y: vector.z)
}
func pointRotated(aroundOrigin origin: CGPoint, byRadians: CGFloat) -> CGPoint {
let dx = self.x - origin.x
let dy = self.y - origin.y
let radius = sqrt(dx * dx + dy * dy)
let azimuth = atan2(dy, dx) // in radians
let newAzimuth = azimuth + byRadians // convert it to radians
let x = origin.x + radius * cos(newAzimuth)
let y = origin.y + radius * sin(newAzimuth)
return CGPoint(x: x, y: y)
}
this works for me
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))
But what I cannot get it to do is to honour that rotation change afterwards.
I've tried .setNeedsUpdateOfSupportedInterfaceOrientations()
but supportedInterfaceOrientations is ignored.
CapturedRoom.Surface has a transform simd_float4x4 and a dimensions simd_float3. The wall length is the dimensions.x and the position can be extracted from the transform with
extension matrix_float4x4 {
var position:SCNVector3 {
return SCNVector3(columns.3.x, columns.3.y, columns.3.z)
}
}
The Euler angles for the wall can be extracted using
extension float4x4 {
var eulerAngles: simd_float3 {
simd_float3(
x: asin(-self[2][1]),
y: atan2(self[2][0], self[2][2]),
z: atan2(self[0][1], self[1][1])
)
}
}