I've been having trouble trying to make a solidworks style Orbit Camera, nothing I do seems to work even though apparently it should (I've tried multiple methods and this seems to be the most promising).
I have a camera struct defined as such
Camera :: struct {
pos:vec3 = .{0,0,1}; // 1
target:vec3 = .{0,0,0};
up:vec3 = .{0,0,1};
right:vec3 = .{1,0,0};
// zoom:float = 1;
Tmat:mat4 = IDENTITY; // Translation
Rmat:mat4 = IDENTITY; // Rotation
Pmat:mat4 = IDENTITY; // Pivot matrix
view:mat4 = IDENTITY;
viewMat:mat4 = IDENTITY; // really inverse view mat
lastposx:float;
lastposy:float;
}
my rotate camera function is defined as such
rotate_cam :: (r:fwdpp_r,cam:*Camera,x:float,y:float) {
using cam;
rotation_origin := target;
dx := TAU / r.pipeline.Extent.width;
dy := PI / r.pipeline.Extent.height;
r_x := (lastposx - x) * dx;
r_y := (lastposy - y) * dy;
lastposx = x;
lastposy = y;
rotx:Quaternion = .{r_x,0,0,1};
roty:Quaternion = .{0,0,r_y,1};
camDir := normalize(pos - target);
right = xx normalize(cross(up,camDir));
up = xx normalize(cross(camDir,right));
rq := rotx * roty;
Rmat = rotate(Rmat,rq);
updateViewMatrix(cam);
}
with rotate being
rotate :: (q: Quaternion) -> Matrix4 {
m: Matrix4;
xs := q.x * 2;
ys := q.y * 2;
zs := q.z * 2;
wx := q.w * xs;
wy := q.w * ys;
wz := q.w * zs;
_xx := q.x * xs;
xy := q.x * ys;
xz := q.x * zs;
yy := q.y * ys;
yz := q.y * zs;
zz := q.z * zs;
m._11 = 1.0 - (yy + zz);
m._12 = xy - wz;
m._13 = xz + wy;
m._21 = xy + wz;
m._22 = 1.0 - (_xx + zz);
m._23 = yz - wx;
m._31 = xz - wy;
m._32 = yz + wx;
m._33 = 1.0 - (_xx + yy);
m._44 = 1;
return m;
}
update_view matrix being
updateViewMatrix :: (cam:*Camera) {
using cam;
Pmat = translate(IDENTITY,target);
viewMat = multiply(TO_VULKAN_COORDS_MATRIX,inverse(Pmat) * Rmat * Pmat * Tmat);
view = inverse(viewMat);
}
TO_VULKAN_COORDS_MATRIX :: Matrix4.{
0, -1, 0, 0,
0, 0, -1, 0,
1, 0, 0, 0,
0, 0, 0, 1,
};
This produces this result