5

How to create a line between two points in 3d space with RealityKit?

There are examples of creating lines between two points in Scenekit, however, there are basically none using RealityKit.

To create the line, I've created a rectangle model entity and placed it between my first touched point and the current touched point. From here, all I would need to do is rotate the rectangle to face the current touched point. However, using the simd_quatf(from: to:) doesn't work as intended.

rectangleModelEntity.transform.rotation = simd_quatf(from: firstTouchedPoint, 
                                                       to: currTouchedPoint)

If I were to touch a point and then drag directly downwards, the rectangle model should be to be a straight line between first touched and current touched point, but it stays horizontal with a slight tilt.

To solve this, I tried getting the angle between my initially horzontal line as a vector and a vector from the first touched to current touched point

let startVec = currTouchedPoint - firstTouchedPoint
let endVec = endOfModelEntityPoint - modelEntityCenterPoint
let lengthVec = simd_length(cross(startVec, endVec))
        
let theta = atan2(lengthVec, dot(startVec, endVec))

This gives me the angle between two vectors in 3d space, which seems correct, when I checked it gave me 90 degrees when touching and dragging directly between it.

The problem is I don't know what the axis to rotate it on should be. Since this is 3d space, the line doesn't need to be on a 2d plane, the current touched position can be downwards and in front of the starting touch position.

rectangleModelEntity = simd_quatf(angle: theta, axis: ???)

Personally, I'm not even too sure if the above is the correct solution to creating a line between two points. In theory it's rather basic, create a rectangle with low height/depth to mimic a line, position it in the center of the starting and current touch point then rotate it so it's oriented correctly.

What should be the axis for the above degrees between two vectors?

Is there a better method of creating two lines between points in 3d space with RealityKit/ARKit?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
NeedHelp101
  • 599
  • 1
  • 9
  • 25

2 Answers2

3

I have implemented using a box. Let me know if you have a better way.

 let midPosition = SIMD3(x:(position1.x + position2.x) / 2,
                            y:(position1.y + position2.y) / 2,
                            z:(position1.z + position2.z) / 2)
    
    let anchor = AnchorEntity()
    anchor.position = midPosition
    anchor.look(at: position1, from: midPosition, relativeTo: nil)
    
    let meters = simd_distance(position1, position2)
    
    let lineMaterial = SimpleMaterial.init(color: .red,
                                           roughness: 1,
                                           isMetallic: false)
    
    let bottomLineMesh = MeshResource.generateBox(width:0.025,
                                                  height: 0.025/2.5,
                                                  depth: meters)
    
    let bottomLineEntity = ModelEntity(mesh: bottomLineMesh,
                                       materials: [lineMaterial])
    
    bottomLineEntity.position = .init(0, 0.025, 0)
    anchor.addChild(bottomLineEntity)
indrajit
  • 303
  • 1
  • 14
0

The axis is the cross product of the direction your object is facing at the beginning and the direction it should be facing now. Like if it's at position p1=[x1,y1,z1], initially facing d1=[0, 0, -1], and you want it to face a point p2=[x, y, z] the axis would be the cross product: |d1|✕|p2 - p1|.

May have to swap the two around, or just negate the angle though, depending on how it works out.

maxxfrazer
  • 1,173
  • 6
  • 15
  • By the direction the object is facing, if my line is on a vertical surface would the direction be [0, 1, 0]. Where y = 1 indicates the direction is straight outwards? Although, it seems like z = 1 based on this, https://stackoverflow.com/questions/59671828/what-is-the-orientation-of-arkits-camera-space Or does this mean the direction of the line object, since it starts off horizontally, that would be a vector from the position of the object to the right end of the line object. – NeedHelp101 Dec 14 '20 at 01:02
  • Yes straight up is [0, 1, 0]. Calculate the product of that and the direction you want it to face, [0, 0, 1]. The result is [1, 0, 0], this is the axis used by the quaternion. – maxxfrazer Dec 15 '20 at 07:43