mathematics – Quaternions distorting object in Metal


I’ve been trying to get rotations with quaternions to work for a while now, and I feel I am very close to it actually working but I just can’t get it to work.

I do not have a view matrix yet and am just working in 2D space to make this slightly easier to set at the moment. So I’m only rotating around the Z axis.

My model matrix is calculated like this

var modelMatrix: matrix_float4x4 {
    var modelMatrix = matrix_identity_float4x4
        
    modelMatrix.translate(_position)
        
    modelMatrix.rotate(_orientation)
        
    modelMatrix.scale(_scale)
        
    return matrix_multiply(matrix_identity_float4x4, modelMatrix)
}

_orientation is defined as

private var _orientation: quaternion = quaternion(angle: toRadians(0), axis: float3(0, 0, 1))

quaternion is just a typedef of simd_quatf

my rotate function is

mutating func rotate(_ quat: quaternion) {
    let quatMatrix = matrix_float4x4(simd_normalize(quat))
        
    self = matrix_multiply(self, quatMatrix)
}

I also tried to do it with the .act method

mutating func rotate(_ quat: quaternion, _ vec: float3) {
    let rotatedVec = quat.act(vec)
        
    self.translate(rotatedVec)
}

This did the seemingly same thing as the first rotate function.

When I initialize _orientation with a rotation of 0, the program acts as normal
normal operation

But when I initialize it with 45, it warps the rectangle:
Warped rect

and when I do it with 90, it produces the same result as with 0, which shouldn’t happen. I’m assuming the problem lies somewhere in the way I’m applying the rotation to the object, but I have no clue what it is.

Edit:

This is the quatMatrix when I put a break point on it if it helps at all:

quatMatrix Vals

Also A thought, maybe it is because of the way I am applying the modelMatrix to the shader positions. I’m pretty sure this is the right way but it might be slightly wrong.

vertex RastData vertexShader(const VertexIn vIn [[stage_in]],
                             constant ModelMat &modelMatrix [[buffer(1)]]) {
    RastData rd;
    
    rd.position = modelMatrix.modelMatrix * float4(vIn.position, 1.0);
    rd.color = vIn.color;
    
    return rd;
}

I tried storing the rotation as being around the rectangles current position like this

private var _orientation: quaternion {
        return quaternion(angle: toRadians(1), axis: _position)
}

but it gives strange clipping artifacts.

enter image description here



Source link

More To Explore

Share on facebook
Share on twitter
Share on linkedin
Share on email