How to measure horizontal plane surface(visible in camera) using ARKit-Scenekit before placing objects?

I want to measure the horizontal plane surface to find whether it fits the object that i am going to place. For ex. if i am going to place a cot 3D model(with fixed size) in a room using iOS 11 ARKit,

First i want to detect if that room surface is sufficient or not to place my 3D model by measuring the surface area(width and height etc.)

Second if the user tries to place it without sufficient place, i should not allow him to place the cot and show him error message.

I created a sample POC by following https://developer.apple.com/sample-code/wwdc/2017/PlacingObjects.zip using which i am able to detect the horizontal plane and place the cot. But the issue is whatever may be the surface, user is able to place the cot which shouldn't be allowed in real time.

I saw couple of demos in which they say we can measure the size of the room or a horizontal plane(https://www.curbed.com/2017/6/29/15894556/ar-measure-app-augmented-reality-ruler-measuring-tape-ios)

I am using ARKit Scenekit inorder to achieve this and i am new to AR and Scenekit. I need to know if this is doable, and if so how to achieve it.

Replies

Hey Yaali!


This is actuallly is a great question! In order to achieve what you decribed, you need to calulate if bounding box of the cot 3D model fits into the detected horizontal plane area. This is quite simple to acheve, the only thing that you need to do is to calculate the bootom part of the model from bounding box and then determine if model's plane is inside the surface plane - this has some intersections with bounding box collision determination technique. One simple method will be capable of determining it.


Lets assume that the detected horizontal plane is represented by the 4 corners for convinience - p1 (top left), p2 (top right), p3 (bottom left) and p4 (bottom right). Our con 3D model's bottom part of bounding box is represented by the other 4 corners as well - e1 (top left), e2 (top right), e3 (bottom left) and e4 (bottom right). Then method could be designed in the following manner:


/// Is a method that determines if Object's foundation is smaller or equal to Plane's foundation - returns true. Otherwise false will be returned.
func determineIfFoundationFits(for plane: Plane, and object: Object) -> Bool {
     if  plane.p1 >= object.p1 && plane.p2 <= object.p2 && plane && plane.p3 >= object.p3 && plane.p4 <= object.p4 { return true }
     return false
}

// Common protocol for Foundation type (better name may be needed)
protocol Foundation {
     var p1: Float {get, set}
     var p2: Float {get, set}
     var p3: Float {get, set}
     var p4: Float {get, set}
}

// Data source for Plane component
struct Plane: Foundation {
     var p1: Float
     var p2: Float
     var p3: Float
     var p4: Float
...
}

// Data source for Objet component (better name may be needed)
struct Object {
  var p1: Float
     var p2: Float
     var p3: Float
     var p4: Float
...
}


This will work for a case when both planes are oriented in the same direction. For cases when they are rotated in relation to each other needs to be designed better approach. But if accuracy is not the main goal and just need to find out if model is approximetely fits into the determined plane - then you can use the above method.

Thanks for the reply. But as far as i noticed, the detected plane is getting extended as we move through the room. Lets say the user scans one particular region alone and we still have some room in the left to place the object, in this case i will not allow the user to place the object even if there is more space to the left.

Right now i am showing the user a rectangle before placing the object indicating the amount of space required to place the object.


Is there any way i can ask the user to move through the room to scan the rectangle and diffuse some particles into the rectangle as the surface area gets extended(Something similar to debug visuals we had in the apple's placingobjects sample code with plane_grid.png), indicating the whole rectangle surface area has been detected and then place the object?