()
| 308 | |
| 309 | |
| 310 | def setup_camera(): |
| 311 | cam_data = bpy.data.cameras.new("ReferenceCamera") |
| 312 | cam_data.sensor_fit = 'VERTICAL' |
| 313 | cam_data.lens_unit = 'FOV' |
| 314 | cam_data.angle_y = math.radians(CAM_FOVY_DEG) |
| 315 | cam_data.clip_start = 0.05 |
| 316 | cam_data.clip_end = 5000.0 |
| 317 | |
| 318 | cam_obj = bpy.data.objects.new("ReferenceCamera", cam_data) |
| 319 | bpy.context.collection.objects.link(cam_obj) |
| 320 | bpy.context.scene.camera = cam_obj |
| 321 | |
| 322 | # Position in Bloom space, convert to Blender |
| 323 | pos_b = Vector(bloom_to_blender(CAM_POS_BLOOM)) |
| 324 | cam_obj.location = pos_b |
| 325 | |
| 326 | # Forward vector per main.ts (Y-up): fwd = (-sin(yaw), sin(pitch), -cos(yaw)) |
| 327 | # with the separate Y component derived from pitch. main.ts computes the |
| 328 | # look target as camera + (cos(pitch)*fwdX*100, sin(pitch)*100, cos(pitch)*fwdZ*100). |
| 329 | fwd_x = -math.sin(CAM_YAW) |
| 330 | fwd_z = -math.cos(CAM_YAW) |
| 331 | look_bloom = ( |
| 332 | CAM_POS_BLOOM[0] + math.cos(CAM_PITCH) * fwd_x * 100.0, |
| 333 | CAM_POS_BLOOM[1] + math.sin(CAM_PITCH) * 100.0, |
| 334 | CAM_POS_BLOOM[2] + math.cos(CAM_PITCH) * fwd_z * 100.0, |
| 335 | ) |
| 336 | tgt_b = Vector(bloom_to_blender(look_bloom)) |
| 337 | up_b = Vector(bloom_to_blender((0.0, 1.0, 0.0))) # world up in Blender space |
| 338 | |
| 339 | # Build a look-at rotation: camera's local -Z points at target, local +Y |
| 340 | # aligns roughly with up. |
| 341 | direction = (tgt_b - pos_b).normalized() |
| 342 | rot = direction.to_track_quat('-Z', 'Y') |
| 343 | cam_obj.rotation_mode = 'QUATERNION' |
| 344 | cam_obj.rotation_quaternion = rot |
| 345 | |
| 346 | print(f"[cycles_reference] camera pos (Blender) = {tuple(pos_b)}") |
| 347 | print(f"[cycles_reference] camera target (Blender)= {tuple(tgt_b)}") |
| 348 | print(f"[cycles_reference] requested angle_y (deg)= {CAM_FOVY_DEG}") |
| 349 | print(f"[cycles_reference] actual cam.angle_y (deg)= {math.degrees(cam_data.angle_y)}") |
| 350 | print(f"[cycles_reference] actual cam.angle_x (deg)= {math.degrees(cam_data.angle_x)}") |
| 351 | print(f"[cycles_reference] sensor_fit={cam_data.sensor_fit} sensor_w={cam_data.sensor_width} sensor_h={cam_data.sensor_height} lens={cam_data.lens}") |
| 352 | |
| 353 | |
| 354 | def setup_render(out_path, samples, device, view, exposure_ev=0.0): |
no test coverage detected