Hi,
I'm trying to convert my SceneKit
code into pure Metal/MetalKit
and I feel confused about this code and how I should rewrite it.
I've made the code simple for this case with some pseudocode. The part where it says "SceneKit
magic" is where I feel lost.
The SCNNode
is just an empty placeholder just as it is – and it works for the calculations it is doing inside.
Any help and pointers are much appreciated :-)
class Scene
{
let ball = Ball()
let scnNode = SCNNode()
var quaternionAngleVelocity = float2(0, 0)
func update()
{
// pseudocode, the user press the up key
quaternionAngleVelocity.x -= 3
// pseudocode, the user press the down key
quaternionAngleVelocity.x += 3
// pseudocode, the user press the left key
quaternionAngleVelocity.y -= 3
// pseudocode, the user press the right key
quaternionAngleVelocity.y += 3
...
// apply friction
quaternionAngleVelocity *= (1 - 0.05) // i.e. decrease with 5%
// rotate
let newQuaternionAxisX = simd_quatf(angle: quaternionAngleVelocity.x.degreesToRadians,
axis: simd_float3(x: 1, y: 0, z: 0))
let newQuaternionAxisY = simd_quatf(angle: quaternionAngleVelocity.y.degreesToRadians,
axis: simd_float3(x: 0, y: 1, z: 0))
let finalQuaternion = simd_normalize(newQuaternionAxisX * newQuaternionAxisY)
// SceneKit magic…?
let matrix4 = SCNMatrix4Mult(scnNode.worldTransform, SCNMatrix4(simd_float4x4(finalQuaternion)))
scnNode.transform = matrix4
ball.quaternion = scnNode.simdWorldOrientation
}
}
class Ball
{
var position: float3 = [0, 0, 0]
var rotation: float3 = [0, 0, 0]
{
didSet
{
let rotationMatrix = float4x4(rotation: rotation)
quaternion = simd_quatf(rotationMatrix)
}
}
var scale: float3 = [1, 1, 1]
var forwardVector: float3 { return normalize([sin(rotation.y), 0, cos(rotation.y)]) }
var rightVector: float3 { return [forwardVector.z, forwardVector.y, -forwardVector.x] }
var upVector: float3 { return [0, forwardVector.z, 0] }
var quaternion = simd_quatf()
var modelMatrix: float4x4
{
let translateMatrix = float4x4(translation: position)
// let rotateMatrix = float4x4(rotation: rotation)
let rotateMatrix = float4x4(quaternion)
let scaleMatrix = float4x4(scaling: scale)
return (translateMatrix * rotateMatrix * scaleMatrix)
}
var worldTransform: float4x4
{
return modelMatrix
}
}