Rotate model to face direction it's traveling in 3d with scenekit and swift - Boids implementation

795 Views Asked by At

I am implementing a boids simulation using Swift and Scenekit. Implementing the simulation itself has been fairly straight forward however I have been unable to make my models faces the direction they are flying (at least all the time and correctly) To see the full project, you can get it here (https://github.com/kingreza/Swift-Boids)

Here is what I am doing to rotate the models to face the direction they are going:

func rotateShipToFaceForward(ship: Ship, positionToBe: SCNVector3)
  {
    var source = (ship.node.position - ship.velocity).normalized();

    // positionToBe is ship.node.position + ship.velocity which is assigned to ship.position at the end of this call
    var destination = (positionToBe - ship.node.position).normalized();

    var dot = source.dot(destination)

    var rotAngle = GLKMathDegreesToRadians(acos(dot));
    var rotAxis = source.cross(destination);

    rotAxis.normalize();

    var q = GLKQuaternionMakeWithAngleAndAxis(Float(rotAngle), Float(rotAxis.x), Float(rotAxis.y), Float(rotAxis.z))

    ship.node.rotation = SCNVector4(x: CGFloat(q.x), y: CGFloat(q.y), z: CGFloat(q.z), w: CGFloat(q.w))


}

Here is how they are behaving right now

https://youtu.be/9k07wxod3yI

1

There are 1 best solutions below

1
On

Three years too late to help the original questioner, and the original YouTube video is gone, but you can see one at the project's GitHub page.

The original Boids code stored orientation as the three basis vectors of the boid’s local coordinate space, which can be thought of as the columns of a 3x3 rotation matrix. Each frame a behavioral “steering force” would act on the current velocity to produce a new velocity. Assuming “velocity alignment” this new velocity is parallel to the new forward (z) vector. It did a cross product of the old up (y) vector and the new forward vector to produce a new side vector. Then it crossed the new side and forward to get a new up vector. FYI, here is the code for that in OpenSteer

Since it looks like you want orientation as a quaternion, there is probably a constructor for your quaternion class that takes a rotation matrix as an argument.