Skip to content

Commit

Permalink
lib+blender: Fix up coordinate system mismatch
Browse files Browse the repository at this point in the history
My brain has a hard time keeping up with all the different things going
on, but I got it to the point that the camera seems to work as expected.
I ended up going the easy route, and just adding a toggle to the API to
switch a specified camera to use Blender's native coordinate system, and
still defaults to c-ray coords (y up, +z forward) so existing json
scenes work normally.
  • Loading branch information
vkoskiv committed Dec 12, 2023
1 parent 6f0ef5b commit 2ddf137
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 10 deletions.
7 changes: 5 additions & 2 deletions bindings/blender_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import ctypes as ct
from array import array
import math
import mathutils

from bpy.props import IntProperty
from bpy.props import PointerProperty
Expand Down Expand Up @@ -128,8 +130,8 @@ def sync_scene(self, renderer, depsgraph, b_scene):
bl_cam = bl_cam_eval.data

cr_cam = cr_scene.camera_new()
mtx = ob_main.matrix_world
euler = mtx.to_euler('ZXY')
mtx = fix_coord(ob_main.matrix_world)
euler = mtx.to_euler('XYZ')
loc = mtx.to_translation()
cr_cam.set_param(c_ray.cam_param.fov, 80) #todo
cr_cam.set_param(c_ray.cam_param.pose_x, loc[0])
Expand All @@ -140,6 +142,7 @@ def sync_scene(self, renderer, depsgraph, b_scene):
cr_cam.set_param(c_ray.cam_param.pose_yaw, euler[2])
cr_cam.set_param(c_ray.cam_param.res_x, self.size_x)
cr_cam.set_param(c_ray.cam_param.res_y, self.size_y)
cr_cam.set_param(c_ray.cam_param.blender_coord, 1)
# TODO: We don't tell blender that we support this, so it's not available yet
if bl_cam.dof.use_dof:
cr_cam.set_param(c_ray.cam_param.fstops, bl_cam.dof.aperture_fstop)
Expand Down
1 change: 1 addition & 0 deletions bindings/c_ray.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ class cam_param(IntEnum):
time = 9
res_x = 10
res_y = 11
blender_coord = 12

class camera:
def __init__(self, scene_ptr):
Expand Down
1 change: 1 addition & 0 deletions include/c-ray/c-ray.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ enum cr_camera_param {

cr_camera_res_x,
cr_camera_res_y,
cr_camera_blender_coord,
};

typedef cr_object cr_camera;
Expand Down
2 changes: 0 additions & 2 deletions src/common/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ struct intCoord {
int x, y;
};

static const struct vector g_world_up = { 0.0f, 1.0f, 0.0f };

//For defaults
static inline struct vector vec_zero() {
return (struct vector){ 0.0f, 0.0f, 0.0f };
Expand Down
11 changes: 11 additions & 0 deletions src/lib/api/c-ray.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ struct camera default_camera = {
.fstops = 0.0f,
.width = 800,
.height = 600,
.look_at = { 0.0f, 0.0f, 1.0f },
.forward = { 0.0f, 0.0f, 1.0f },
.right = { 1.0f, 0.0f, 0.0f },
.up = { 0.0f, 1.0f, 0.0f }
};

cr_camera cr_camera_new(struct cr_scene *ext) {
Expand Down Expand Up @@ -442,6 +446,13 @@ bool cr_camera_set_num_pref(struct cr_scene *ext, cr_camera c, enum cr_camera_pa
cam->height = num;
return true;
}
case cr_camera_blender_coord: {
cam->look_at = (struct vector){0.0f, 0.0f, -1.0f};
cam->forward = vec_normalize(cam->look_at);
cam->right = (struct vector){1.0f, 0.0f, 0.0f};
cam->up = (struct vector){0.0f, -1.0f, 0.0f};
return true;
}
}

cam_update_pose(cam, &cam->orientation, &cam->position);
Expand Down
8 changes: 2 additions & 6 deletions src/lib/datatypes/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@ void cam_recompute_optics(struct camera *cam) {
cam->aspect_ratio = (float)cam->width / (float)cam->height;
cam->sensor_size.x = 2.0f * tanf(deg_to_rad(cam->FOV) / 2.0f);
cam->sensor_size.y = cam->sensor_size.x / cam->aspect_ratio;
cam->look_at = (struct vector){0.0f, 0.0f, 1.0f};
//FIXME: This still assumes a 35mm sensor, instead of using the computed
//sensor width value from above. Just preserving this so existing configs
//work, but do look into a better way to do this here!
const float sensor_width_35mm = 0.036f;
cam->focal_length = 0.5f * sensor_width_35mm / deg_to_rad(0.5f * cam->FOV);
if (cam->fstops != 0.0f) cam->aperture = 0.5f * (cam->focal_length / cam->fstops);
cam->forward = vec_normalize(cam->look_at);
cam->right = vec_cross(g_world_up, cam->forward);
cam->up = vec_cross(cam->forward, cam->right);
}

void recomputeComposite(struct camera *cam) {
Expand All @@ -36,7 +32,7 @@ void recomputeComposite(struct camera *cam) {
struct vector positionAtT = spline_at(cam->path, cam->time);
transforms[0] = tform_new_translate(positionAtT.x, positionAtT.y, positionAtT.z);
} else {
transforms[0] = tform_new_translate(-cam->position.x, cam->position.y, cam->position.z);
transforms[0] = tform_new_translate(cam->position.x, cam->position.y, cam->position.z);
}
transforms[1] = tform_new_rot(cam->orientation.roll, cam->orientation.pitch, cam->orientation.yaw);

Expand Down Expand Up @@ -77,7 +73,7 @@ struct lightRay cam_get_ray(const struct camera *cam, int x, int y, struct sampl
const float jitter_x = triangleDistribution(getDimension(sampler));
const float jitter_y = triangleDistribution(getDimension(sampler));

const struct vector pix_x = vec_scale(vec_negate(cam->right), (cam->sensor_size.x / cam->width));
const struct vector pix_x = vec_scale(cam->right, (cam->sensor_size.x / cam->width));
const struct vector pix_y = vec_scale(cam->up, (cam->sensor_size.y / cam->height));
const struct vector pix_v = vec_add(
cam->forward,
Expand Down

0 comments on commit 2ddf137

Please sign in to comment.