Posts

Post not yet marked as solved
22 Replies
I've posted an article in which I go through the process of setting up an app and creating a 2D floor plan using SpriteKit: https://totheroot.io/content/create-a-2-d-floor-plan-with-room-plan-and-sprite-kit-part-i
Post not yet marked as solved
6 Replies
I’ve updated the solution with a sample project: https://developer.apple.com/forums/thread/713409?page=1#734583022
Post not yet marked as solved
22 Replies
I've created a project that creates a 2D floor plan out of RoomPlan data. I hope this answers anyone's questions. An article explaining every step is on its way. https://github.com/denniswave/RoomPlan-2D
Post not yet marked as solved
22 Replies
I'm aware my explanation is not the clearest. I'll write an article about this to explain things more clearly and provide a sample project.
Post not yet marked as solved
22 Replies
To clarify, the code below will generate SKShapeNodes for all walls captured in the CapturedRoom attribute. It uses the extensions mentioned in my previous answer. Hope this'll help. class Walls: SKNode { init() { for wall in CapturedRoom.walls { let wallNode = SKNode() addChild(wallNode) // Position wallNode wallNode.position.x = -CGFloat(wall.transform.position.x) * 200 wallNode.position.y = CGFloat(wall.transform.position.z) * 200 wallNode.zRotation = -CGFloat(wall.transform.eulerAngles.z - wall.transform.eulerAngles.y) // Create the path for the wall let surfacePath = CGMutablePath() let span = CGFloat(wall.dimensions.x) * 200 / 2 surfacePath.move(to: CGPoint(x: -span, y: 0)) surfacePath.addLine(to: CGPoint(x: span, y: 0)) // Draw the wall using an SKShapeNode and the path let wallShape = SKShapeNode(path: surfacePath) wallShape.strokeColor = .white wallShape.lineWidth = 5 wallShape.lineCap = .square wallNode.addChild(wallShape) } } }
Post not yet marked as solved
22 Replies
I've found a solution for this. As suggested, the simd_float4x4 matrix is the key to the solution here. Using SpriteKit I've created my 2D map using RoomPlan data. To start with, I've created a couple of extensions for simd_float4x4. These extract the data we need from the metrix so it's easier to work with: extension simd_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])         )     }     var position: simd_float3 {         simd_float3(x: self.columns.3.x,                     y: self.columns.3.y,                     z: self.columns.3.z         )     }     var positionVector: SCNVector3 {         SCNVector3(x: self.columns.3.x,                    y: self.columns.3.y,                    z: self.columns.3.z         )     } } To build my 2D map in SpriteKit, I created a separate SKNode for every RoomPlan surface. In each node I set the correct position and rotation using the sims_float4x4 matrix, create a path using the dimensions and draw the surface using an SKShapeNode. Using the eulerAngles and position extensions, I set the correct rotation and position of every surface: // Position surface position.x = -CGFloat(transform.position.x) * mapScale position.y = CGFloat(transform.position.z) * mapScale zRotation = -CGFloat(transform.eulerAngles.z - transform.eulerAngles.y) The mapScale is just a scaling factor I applied. The measurements that come out of RoomPlan are in meters. In SpriteKit they're in points. If you don't apply a scale, the whole map will display within a few pixels. Setting the mapScale to 100-300 will do fine, depending on the device's screen size and SpriteKit camera. The x position is the same in both RoomPlan's and SpriteKit's coordinate system. In RoomPlan however, the x- and y-axis are horizontal and vertical and the z-axis is the "depth" axis. We're interested in the "top" view, ignoring RoomPlan's y-axis so we'll need to use the z value for SpriteKit's y component (I hope my explanation makes any sense :p). The surfaceRotation is a weird one. I still don't fully get why this works like this, but it does xd. As pointed out by @ArthurPhilipenko the matrix only tells us about the position and rotation of the surface which will result in a point in space, but not a line, like we want to draw. For this, we also need the "dimension" component from the RoomPlan surface. This is a simd_float3. Using this dimension component, we can draw a line using the width of the surface (or the dimension.x) and positioning it equally on both sides of out position and rotation point of the node. // Create surface path let surfacePath = CGMutablePath() let span = CGFloat(dimensions.x) * mapScale / 2 surfacePath.move(to: CGPoint(x: -span, y: 0)) surfacePath.addLine(to: CGPoint(x: span, y: 0)) Finally, I create a SKShapeNode to draw the line on the screen: // Draw surface path func draw() { let surfaceShape = SKShapeNode(path: surfacePath) surfaceShape.strokeColor = surfaceColor surfaceShape.lineWidth = wallThickness surfaceShape.lineCap = .square addChild(surfaceShape) } If you do this for every surface you'll get a nice 2D map using the 3D RoomPlan data.
Post not yet marked as solved
6 Replies
I've posted a solution to this in this similar post: https://developer.apple.com/forums/thread/713409?page=1#734583022
Post not yet marked as solved
1 Replies
To illustrate in code:let emitter = SKEmitterNode(fileNamed: "FireWork_Flare_Standard") emitter?.particleColorSequence?.setKeyframeValue(UIColor.blue, for: 1)