connecting windows and doors to a wall.

Is there a simple way of finding out which wall the door or window is connected to?

I can see that if you serialise the CapturedRoom the Json does contain a field called parentIdentifier that links them. But there's no mention of it in the documentation.

Answered by DaneHale in 719685022

I never saw anyone answer this, but doors, windows, walls, and objects all have parentIdentifiers. I did confirm in a session that the door I scanned did have a parent identifier that belonged to the wall I scanned with it. So it works and yes, they use parentIdentifier to link those objects. I just want to see how to get the position of that door or that window inside of the wall as well. I still haven't found that out.

Accepted Answer

I never saw anyone answer this, but doors, windows, walls, and objects all have parentIdentifiers. I did confirm in a session that the door I scanned did have a parent identifier that belonged to the wall I scanned with it. So it works and yes, they use parentIdentifier to link those objects. I just want to see how to get the position of that door or that window inside of the wall as well. I still haven't found that out.

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)

    }

     

How are you getting your positions? I'm looking at this sims_float3 dimension and I don't know how to determine a length of wall for instance. But I see you have a wall.transform.position in there and I'm curious how you got that position?

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])            )

       }

}

connecting windows and doors to a wall.
 
 
Q