diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index f6443589631..7eb9eb437c7 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -65,17 +65,6 @@ enum_filter_types = ( ('BLACKMAN_HARRIS', "Blackman-Harris", "Blackman-Harris filter"), ) -enum_panorama_types = ( - ('EQUIRECTANGULAR', "Equirectangular", "Spherical camera for environment maps, also known as Lat Long panorama", 0), - ('EQUIANGULAR_CUBEMAP_FACE', "Equiangular Cubemap Face", "Single face of an equiangular cubemap", 5), - ('MIRRORBALL', "Mirror Ball", "Mirror ball mapping for environment maps", 3), - ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions", 1), - ('FISHEYE_EQUISOLID', "Fisheye Equisolid", - "Similar to most fisheye modern lens, takes sensor dimensions into consideration", 2), - ('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial", - "Defines the lens projection as polynomial to allow real world camera lenses to be mimicked", 4), -) - enum_curve_shape = ( ('RIBBONS', "Rounded Ribbons", "Render curves as flat ribbons with rounded normals, for fast rendering"), ('THICK', "3D Curves", "Render curves as circular 3D geometry, for accurate results when viewing closely"), @@ -1014,95 +1003,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): del bpy.types.Scene.cycles -class CyclesCameraSettings(bpy.types.PropertyGroup): - - panorama_type: EnumProperty( - name="Panorama Type", - description="Distortion to use for the calculation", - items=enum_panorama_types, - default='FISHEYE_EQUISOLID', - ) - fisheye_fov: FloatProperty( - name="Field of View", - description="Field of view for the fisheye lens", - min=0.1745, soft_max=2.0 * pi, max=10.0 * pi, - subtype='ANGLE', - default=pi, - ) - fisheye_lens: FloatProperty( - name="Fisheye Lens", - description="Lens focal length (mm)", - min=0.01, soft_max=15.0, max=100.0, - default=10.5, - ) - latitude_min: FloatProperty( - name="Min Latitude", - description="Minimum latitude (vertical angle) for the equirectangular lens", - min=-0.5 * pi, max=0.5 * pi, - subtype='ANGLE', - default=-0.5 * pi, - ) - latitude_max: FloatProperty( - name="Max Latitude", - description="Maximum latitude (vertical angle) for the equirectangular lens", - min=-0.5 * pi, max=0.5 * pi, - subtype='ANGLE', - default=0.5 * pi, - ) - longitude_min: FloatProperty( - name="Min Longitude", - description="Minimum longitude (horizontal angle) for the equirectangular lens", - min=-pi, max=pi, - subtype='ANGLE', - default=-pi, - ) - longitude_max: FloatProperty( - name="Max Longitude", - description="Maximum longitude (horizontal angle) for the equirectangular lens", - min=-pi, max=pi, - subtype='ANGLE', - default=pi, - ) - - fisheye_polynomial_k0: FloatProperty( - name="Fisheye Polynomial K0", - description="Coefficient K0 of the lens polynomial", - default=camera.default_fisheye_polynomial[0], precision=6, step=0.1, subtype='ANGLE', - ) - fisheye_polynomial_k1: FloatProperty( - name="Fisheye Polynomial K1", - description="Coefficient K1 of the lens polynomial", - default=camera.default_fisheye_polynomial[1], precision=6, step=0.1, subtype='ANGLE', - ) - fisheye_polynomial_k2: FloatProperty( - name="Fisheye Polynomial K2", - description="Coefficient K2 of the lens polynomial", - default=camera.default_fisheye_polynomial[2], precision=6, step=0.1, subtype='ANGLE', - ) - fisheye_polynomial_k3: FloatProperty( - name="Fisheye Polynomial K3", - description="Coefficient K3 of the lens polynomial", - default=camera.default_fisheye_polynomial[3], precision=6, step=0.1, subtype='ANGLE', - ) - fisheye_polynomial_k4: FloatProperty( - name="Fisheye Polynomial K4", - description="Coefficient K4 of the lens polynomial", - default=camera.default_fisheye_polynomial[4], precision=6, step=0.1, subtype='ANGLE', - ) - - @classmethod - def register(cls): - bpy.types.Camera.cycles = PointerProperty( - name="Cycles Camera Settings", - description="Cycles camera settings", - type=cls, - ) - - @classmethod - def unregister(cls): - del bpy.types.Camera.cycles - - class CyclesMaterialSettings(bpy.types.PropertyGroup): emission_sampling: EnumProperty( @@ -1837,7 +1737,6 @@ class CyclesView3DShadingSettings(bpy.types.PropertyGroup): def register(): bpy.utils.register_class(CyclesRenderSettings) - bpy.utils.register_class(CyclesCameraSettings) bpy.utils.register_class(CyclesMaterialSettings) bpy.utils.register_class(CyclesLightSettings) bpy.utils.register_class(CyclesWorldSettings) @@ -1858,7 +1757,6 @@ def register(): def unregister(): bpy.utils.unregister_class(CyclesRenderSettings) - bpy.utils.unregister_class(CyclesCameraSettings) bpy.utils.unregister_class(CyclesMaterialSettings) bpy.utils.unregister_class(CyclesLightSettings) bpy.utils.unregister_class(CyclesWorldSettings) diff --git a/intern/cycles/blender/camera.cpp b/intern/cycles/blender/camera.cpp index 053585718a7..5f0e7b39860 100644 --- a/intern/cycles/blender/camera.cpp +++ b/intern/cycles/blender/camera.cpp @@ -164,6 +164,26 @@ static float blender_camera_focal_distance(BL::RenderEngine &b_engine, return fabsf(dot(view_dir, dof_dir)); } +static PanoramaType blender_panorama_type_to_cycles(const BL::Camera::panorama_type_enum type) +{ + switch (type) { + case BL::Camera::panorama_type_EQUIRECTANGULAR: + return PANORAMA_EQUIRECTANGULAR; + case BL::Camera::panorama_type_EQUIANGULAR_CUBEMAP_FACE: + return PANORAMA_EQUIANGULAR_CUBEMAP_FACE; + case BL::Camera::panorama_type_MIRRORBALL: + return PANORAMA_MIRRORBALL; + case BL::Camera::panorama_type_FISHEYE_EQUIDISTANT: + return PANORAMA_FISHEYE_EQUIDISTANT; + case BL::Camera::panorama_type_FISHEYE_EQUISOLID: + return PANORAMA_FISHEYE_EQUISOLID; + case BL::Camera::panorama_type_FISHEYE_LENS_POLYNOMIAL: + return PANORAMA_FISHEYE_LENS_POLYNOMIAL; + } + /* Could happen if loading a newer file that has an unsupported type. */ + return PANORAMA_FISHEYE_EQUISOLID; +} + static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine &b_engine, BL::Object &b_ob, @@ -173,7 +193,6 @@ static void blender_camera_from_object(BlenderCamera *bcam, if (b_ob_data.is_a(&RNA_Camera)) { BL::Camera b_camera(b_ob_data); - PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles"); bcam->nearclip = b_camera.clip_start(); bcam->farclip = b_camera.clip_end(); @@ -194,21 +213,19 @@ static void blender_camera_from_object(BlenderCamera *bcam, break; } - bcam->panorama_type = (PanoramaType)get_enum( - ccamera, "panorama_type", PANORAMA_NUM_TYPES, PANORAMA_EQUIRECTANGULAR); + bcam->panorama_type = blender_panorama_type_to_cycles(b_camera.panorama_type()); + bcam->fisheye_fov = b_camera.fisheye_fov(); + bcam->fisheye_lens = b_camera.fisheye_lens(); + bcam->latitude_min = b_camera.latitude_min(); + bcam->latitude_max = b_camera.latitude_max(); + bcam->longitude_min = b_camera.longitude_min(); + bcam->longitude_max = b_camera.longitude_max(); - bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov"); - bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens"); - bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min"); - bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max"); - bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min"); - bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max"); - - bcam->fisheye_polynomial_k0 = RNA_float_get(&ccamera, "fisheye_polynomial_k0"); - bcam->fisheye_polynomial_k1 = RNA_float_get(&ccamera, "fisheye_polynomial_k1"); - bcam->fisheye_polynomial_k2 = RNA_float_get(&ccamera, "fisheye_polynomial_k2"); - bcam->fisheye_polynomial_k3 = RNA_float_get(&ccamera, "fisheye_polynomial_k3"); - bcam->fisheye_polynomial_k4 = RNA_float_get(&ccamera, "fisheye_polynomial_k4"); + bcam->fisheye_polynomial_k0 = b_camera.fisheye_polynomial_k0(); + bcam->fisheye_polynomial_k1 = b_camera.fisheye_polynomial_k1(); + bcam->fisheye_polynomial_k2 = b_camera.fisheye_polynomial_k2(); + bcam->fisheye_polynomial_k3 = b_camera.fisheye_polynomial_k3(); + bcam->fisheye_polynomial_k4 = b_camera.fisheye_polynomial_k4(); bcam->interocular_distance = b_camera.stereo().interocular_distance(); if (b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) { diff --git a/scripts/startup/bl_ui/properties_data_camera.py b/scripts/startup/bl_ui/properties_data_camera.py index 3a224a07251..d6f3e73e373 100644 --- a/scripts/startup/bl_ui/properties_data_camera.py +++ b/scripts/startup/bl_ui/properties_data_camera.py @@ -103,27 +103,26 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): elif cam.type == 'PANO': engine = context.engine if engine == 'CYCLES': - ccam = cam.cycles - col.prop(ccam, "panorama_type") - if ccam.panorama_type == 'FISHEYE_EQUIDISTANT': - col.prop(ccam, "fisheye_fov") - elif ccam.panorama_type == 'FISHEYE_EQUISOLID': - col.prop(ccam, "fisheye_lens", text="Lens") - col.prop(ccam, "fisheye_fov") - elif ccam.panorama_type == 'EQUIRECTANGULAR': + col.prop(cam, "panorama_type") + if cam.panorama_type == 'FISHEYE_EQUIDISTANT': + col.prop(cam, "fisheye_fov") + elif cam.panorama_type == 'FISHEYE_EQUISOLID': + col.prop(cam, "fisheye_lens", text="Lens") + col.prop(cam, "fisheye_fov") + elif cam.panorama_type == 'EQUIRECTANGULAR': sub = col.column(align=True) - sub.prop(ccam, "latitude_min", text="Latitude Min") - sub.prop(ccam, "latitude_max", text="Max") + sub.prop(cam, "latitude_min", text="Latitude Min") + sub.prop(cam, "latitude_max", text="Max") sub = col.column(align=True) - sub.prop(ccam, "longitude_min", text="Longitude Min") - sub.prop(ccam, "longitude_max", text="Max") - elif ccam.panorama_type == 'FISHEYE_LENS_POLYNOMIAL': - col.prop(ccam, "fisheye_fov") - col.prop(ccam, "fisheye_polynomial_k0", text="K0") - col.prop(ccam, "fisheye_polynomial_k1", text="K1") - col.prop(ccam, "fisheye_polynomial_k2", text="K2") - col.prop(ccam, "fisheye_polynomial_k3", text="K3") - col.prop(ccam, "fisheye_polynomial_k4", text="K4") + sub.prop(cam, "longitude_min", text="Longitude Min") + sub.prop(cam, "longitude_max", text="Max") + elif cam.panorama_type == 'FISHEYE_LENS_POLYNOMIAL': + col.prop(cam, "fisheye_fov") + col.prop(cam, "fisheye_polynomial_k0", text="K0") + col.prop(cam, "fisheye_polynomial_k1", text="K1") + col.prop(cam, "fisheye_polynomial_k2", text="K2") + col.prop(cam, "fisheye_polynomial_k3", text="K3") + col.prop(cam, "fisheye_polynomial_k4", text="K4") elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}: if cam.lens_unit == 'MILLIMETERS': diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index e0ee73b0f06..dc90f595de7 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -29,7 +29,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 16 +#define BLENDER_FILE_SUBVERSION 17 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenkernel/intern/camera.cc b/source/blender/blenkernel/intern/camera.cc index 9a133758554..a1af2b7de3d 100644 --- a/source/blender/blenkernel/intern/camera.cc +++ b/source/blender/blenkernel/intern/camera.cc @@ -31,6 +31,7 @@ #include "BKE_action.h" #include "BKE_anim_data.h" #include "BKE_camera.h" +#include "BKE_idprop.h" #include "BKE_idtype.h" #include "BKE_layer.h" #include "BKE_lib_id.h" @@ -103,10 +104,97 @@ static void camera_foreach_id(ID *id, LibraryForeachIDData *data) } } +struct CameraCyclesCompatibilityData { + IDProperty *idprop_prev = nullptr; + IDProperty *idprop_temp = nullptr; +}; + +static CameraCyclesCompatibilityData camera_write_cycles_compatibility_data_create(ID *id) +{ + auto cycles_data_ensure = [](IDProperty *group) { + IDProperty *prop = IDP_GetPropertyTypeFromGroup(group, "cycles", IDP_GROUP); + if (prop) { + return prop; + } + IDPropertyTemplate val = {0}; + prop = IDP_New(IDP_GROUP, &val, "cycles"); + IDP_AddToGroup(group, prop); + return prop; + }; + + auto cycles_property_int_set = [](IDProperty *idprop, const char *name, int value) { + IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_INT); + if (prop) { + IDP_Int(prop) = value; + } + else { + IDPropertyTemplate val = {0}; + val.i = value; + IDP_AddToGroup(idprop, IDP_New(IDP_INT, &val, name)); + } + }; + + auto cycles_property_float_set = [](IDProperty *idprop, const char *name, float value) { + IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_FLOAT); + if (prop) { + IDP_Float(prop) = value; + } + else { + IDPropertyTemplate val = {0}; + val.f = value; + IDP_AddToGroup(idprop, IDP_New(IDP_FLOAT, &val, name)); + } + }; + + /* For forward compatibility, still write panoramic properties as ID properties for + * previous blender versions. */ + IDProperty *idprop_prev = IDP_GetProperties(id, false); + /* Make a copy to avoid modifying the original. */ + IDProperty *idprop_temp = idprop_prev ? IDP_CopyProperty(idprop_prev) : + IDP_GetProperties(id, true); + + Camera *cam = (Camera *)id; + IDProperty *cycles_cam = cycles_data_ensure(idprop_temp); + cycles_property_int_set(cycles_cam, "panorama_type", cam->panorama_type); + cycles_property_float_set(cycles_cam, "fisheye_fov", cam->fisheye_fov); + cycles_property_float_set(cycles_cam, "fisheye_lens", cam->fisheye_lens); + cycles_property_float_set(cycles_cam, "latitude_min", cam->latitude_min); + cycles_property_float_set(cycles_cam, "latitude_max", cam->latitude_max); + cycles_property_float_set(cycles_cam, "longitude_min", cam->longitude_min); + cycles_property_float_set(cycles_cam, "longitude_max", cam->longitude_max); + cycles_property_float_set(cycles_cam, "fisheye_polynomial_k0", cam->fisheye_polynomial_k0); + cycles_property_float_set(cycles_cam, "fisheye_polynomial_k1", cam->fisheye_polynomial_k1); + cycles_property_float_set(cycles_cam, "fisheye_polynomial_k2", cam->fisheye_polynomial_k2); + cycles_property_float_set(cycles_cam, "fisheye_polynomial_k3", cam->fisheye_polynomial_k3); + cycles_property_float_set(cycles_cam, "fisheye_polynomial_k4", cam->fisheye_polynomial_k4); + + id->properties = idprop_temp; + + return {idprop_prev, idprop_temp}; +} + +static void camera_write_cycles_compatibility_data_clear(ID *id, + CameraCyclesCompatibilityData &data) +{ + id->properties = data.idprop_prev; + data.idprop_prev = nullptr; + + if (data.idprop_temp) { + IDP_FreeProperty(data.idprop_temp); + data.idprop_temp = nullptr; + } +} + static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_address) { + const bool is_undo = BLO_write_is_undo(writer); Camera *cam = (Camera *)id; + CameraCyclesCompatibilityData cycles_data; + if (!is_undo) { + cycles_data = camera_write_cycles_compatibility_data_create(id); + } + /* write LibData */ BLO_write_id_struct(writer, Camera, id_address, &cam->id); BKE_id_blend_write(writer, &cam->id); @@ -114,6 +202,10 @@ static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_addre LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) { BLO_write_struct(writer, CameraBGImage, bgpic); } + + if (!is_undo) { + camera_write_cycles_compatibility_data_clear(id, cycles_data); + } } static void camera_blend_read_data(BlendDataReader *reader, ID *id) diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 7f709336411..e619f5a3df6 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -13,6 +13,7 @@ #include "CLG_log.h" #include "DNA_brush_types.h" +#include "DNA_camera_types.h" #include "DNA_light_types.h" #include "DNA_lightprobe_types.h" #include "DNA_modifier_types.h" @@ -675,19 +676,7 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) FOREACH_NODETREE_END; } - /** - * Versioning code until next subversion bump goes here. - * - * \note Be sure to check when bumping the version: - * - #do_versions_after_linking_400 in this file. - * - `versioning_userdef.cc`, #blo_do_versions_userdef - * - `versioning_userdef.cc`, #do_versions_theme - * - * \note Keep this message at the bottom of the function. - */ - { - /* Keep this block, even when empty. */ - + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 17)) { if (!DNA_struct_find(fd->filesdna, "NodeShaderHairPrincipled")) { FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_SHADER) { @@ -697,6 +686,56 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) FOREACH_NODETREE_END; } + /* Panorama properties shared with Eevee. */ + if (!DNA_struct_elem_find(fd->filesdna, "Camera", "float", "fisheye_fov")) { + Camera default_cam = *DNA_struct_default_get(Camera); + LISTBASE_FOREACH (Camera *, camera, &bmain->cameras) { + IDProperty *ccam = version_cycles_properties_from_ID(&camera->id); + if (ccam) { + camera->panorama_type = version_cycles_property_int( + ccam, "panorama_type", default_cam.panorama_type); + camera->fisheye_fov = version_cycles_property_float( + ccam, "fisheye_fov", default_cam.fisheye_fov); + camera->fisheye_lens = version_cycles_property_float( + ccam, "fisheye_lens", default_cam.fisheye_lens); + camera->latitude_min = version_cycles_property_float( + ccam, "latitude_min", default_cam.latitude_min); + camera->latitude_max = version_cycles_property_float( + ccam, "latitude_max", default_cam.latitude_max); + camera->longitude_min = version_cycles_property_float( + ccam, "longitude_min", default_cam.longitude_min); + camera->longitude_max = version_cycles_property_float( + ccam, "longitude_max", default_cam.longitude_max); + /* Fit to match default projective camera with focal_length 50 and sensor_width 36. */ + camera->fisheye_polynomial_k0 = version_cycles_property_float( + ccam, "fisheye_polynomial_k0", default_cam.fisheye_polynomial_k0); + camera->fisheye_polynomial_k1 = version_cycles_property_float( + ccam, "fisheye_polynomial_k1", default_cam.fisheye_polynomial_k1); + camera->fisheye_polynomial_k2 = version_cycles_property_float( + ccam, "fisheye_polynomial_k2", default_cam.fisheye_polynomial_k2); + camera->fisheye_polynomial_k3 = version_cycles_property_float( + ccam, "fisheye_polynomial_k3", default_cam.fisheye_polynomial_k3); + camera->fisheye_polynomial_k4 = version_cycles_property_float( + ccam, "fisheye_polynomial_k4", default_cam.fisheye_polynomial_k4); + } + else { + camera->panorama_type = default_cam.panorama_type; + camera->fisheye_fov = default_cam.fisheye_fov; + camera->fisheye_lens = default_cam.fisheye_lens; + camera->latitude_min = default_cam.latitude_min; + camera->latitude_max = default_cam.latitude_max; + camera->longitude_min = default_cam.longitude_min; + camera->longitude_max = default_cam.longitude_max; + /* Fit to match default projective camera with focal_length 50 and sensor_width 36. */ + camera->fisheye_polynomial_k0 = default_cam.fisheye_polynomial_k0; + camera->fisheye_polynomial_k1 = default_cam.fisheye_polynomial_k1; + camera->fisheye_polynomial_k2 = default_cam.fisheye_polynomial_k2; + camera->fisheye_polynomial_k3 = default_cam.fisheye_polynomial_k3; + camera->fisheye_polynomial_k4 = default_cam.fisheye_polynomial_k4; + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "LightProbe", "float", "grid_flag")) { LISTBASE_FOREACH (LightProbe *, lightprobe, &bmain->lightprobes) { /* Keep old behavior of baking the whole lighting. */ @@ -711,4 +750,18 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } } + + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - #do_versions_after_linking_400 in this file. + * - `versioning_userdef.cc`, #blo_do_versions_userdef + * - `versioning_userdef.cc`, #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ + } } diff --git a/source/blender/makesdna/DNA_camera_defaults.h b/source/blender/makesdna/DNA_camera_defaults.h index f3b01b4082c..c8130ace5da 100644 --- a/source/blender/makesdna/DNA_camera_defaults.h +++ b/source/blender/makesdna/DNA_camera_defaults.h @@ -41,6 +41,20 @@ .ortho_scale = 6.0, \ .flag = CAM_SHOWPASSEPARTOUT, \ .passepartalpha = 0.5f, \ + \ + .panorama_type = CAM_PANORAMA_FISHEYE_EQUISOLID,\ + .fisheye_fov = M_PI,\ + .fisheye_lens = 10.5f,\ + .latitude_min = -0.5f * (float)M_PI,\ + .latitude_max = 0.5f * (float)M_PI,\ + .longitude_min = -M_PI,\ + .longitude_max = M_PI,\ + /* Fit to match default projective camera with focal_length 50 and sensor_width 36. */ \ + .fisheye_polynomial_k0 = -1.1735143712967577e-05f,\ + .fisheye_polynomial_k1 = -0.019988736953434998f,\ + .fisheye_polynomial_k2 = -3.3525322965709175e-06f,\ + .fisheye_polynomial_k3 = 3.099275275886036e-06f,\ + .fisheye_polynomial_k4 = -2.6064646454854524e-08f,\ \ .dof = _DNA_DEFAULT_CameraDOFSettings, \ \ diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h index 67541dd7fb9..680c1c18a95 100644 --- a/source/blender/makesdna/DNA_camera_types.h +++ b/source/blender/makesdna/DNA_camera_types.h @@ -91,6 +91,21 @@ typedef struct Camera { float shiftx, shifty; float dof_distance DNA_DEPRECATED; + char sensor_fit; + char panorama_type; + char _pad[2]; + + /** Fisheye properties. */ + float fisheye_fov; + float fisheye_lens; + float latitude_min, latitude_max; + float longitude_min, longitude_max; + float fisheye_polynomial_k0; + float fisheye_polynomial_k1; + float fisheye_polynomial_k2; + float fisheye_polynomial_k3; + float fisheye_polynomial_k4; + /** Old animation system, deprecated for 2.5. */ struct Ipo *ipo DNA_DEPRECATED; @@ -101,9 +116,6 @@ typedef struct Camera { /* CameraBGImage reference images */ struct ListBase bg_images; - char sensor_fit; - char _pad[7]; - /* Stereo settings */ struct CameraStereoSettings stereo; @@ -120,6 +132,16 @@ enum { CAM_PANO = 2, }; +/* panorama_type */ +enum { + CAM_PANORAMA_EQUIRECTANGULAR = 0, + CAM_PANORAMA_FISHEYE_EQUIDISTANT = 1, + CAM_PANORAMA_FISHEYE_EQUISOLID = 2, + CAM_PANORAMA_MIRRORBALL = 3, + CAM_PANORAMA_FISHEYE_LENS_POLYNOMIAL = 4, + CAM_PANORAMA_EQUIANGULAR_CUBEMAP_FACE = 5, +}; + /* dtx */ enum { CAM_DTX_CENTER = (1 << 0), diff --git a/source/blender/makesrna/intern/rna_camera.cc b/source/blender/makesrna/intern/rna_camera.cc index 7c7a710055a..ecb021a1d41 100644 --- a/source/blender/makesrna/intern/rna_camera.cc +++ b/source/blender/makesrna/intern/rna_camera.cc @@ -593,6 +593,41 @@ void RNA_def_camera(BlenderRNA *brna) {0, nullptr, 0, nullptr, nullptr}, }; + static const EnumPropertyItem panorama_type_items[] = { + {CAM_PANORAMA_EQUIRECTANGULAR, + "EQUIRECTANGULAR", + 0, + "Equirectangular", + "Spherical camera for environment maps, also known as Lat Long panorama"}, + {CAM_PANORAMA_EQUIANGULAR_CUBEMAP_FACE, + "EQUIANGULAR_CUBEMAP_FACE", + 0, + "Equiangular Cubemap Face", + "Single face of an equiangular cubemap"}, + {CAM_PANORAMA_MIRRORBALL, + "MIRRORBALL", + 0, + "Mirror Ball", + "Mirror ball mapping for environment maps"}, + {CAM_PANORAMA_FISHEYE_EQUIDISTANT, + "FISHEYE_EQUIDISTANT", + 0, + "Fisheye Equidistant", + "Ideal for fulldomes, ignore the sensor dimensions"}, + {CAM_PANORAMA_FISHEYE_EQUISOLID, + "FISHEYE_EQUISOLID", + 0, + "Fisheye Equisolid", + "Similar to most fisheye modern lens, takes sensor dimensions into consideration"}, + {CAM_PANORAMA_FISHEYE_LENS_POLYNOMIAL, + "FISHEYE_LENS_POLYNOMIAL", + 0, + "Fisheye Lens Polynomial", + "Defines the lens projection as polynomial to allow real world camera lenses to be " + "mimicked"}, + {0, nullptr, 0, nullptr, nullptr}, + }; + srna = RNA_def_struct(brna, "Camera", "ID"); RNA_def_struct_ui_text(srna, "Camera", "Camera data-block for storing camera settings"); RNA_def_struct_ui_icon(srna, ICON_CAMERA_DATA); @@ -817,6 +852,75 @@ void RNA_def_camera(BlenderRNA *brna) prop, "Harmonious Triangle B", "Display harmony B composition guide inside the camera view"); RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, nullptr); + /* Panoramic settings. */ + prop = RNA_def_property(srna, "panorama_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, panorama_type_items); + RNA_def_property_ui_text(prop, "Panorama Type", "Distortion to use for the calculation"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_fov", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, 0.1745, 10.0 * M_PI); + RNA_def_property_ui_range(prop, 0.1745, 2.0 * M_PI, 3, 2); + RNA_def_property_ui_text(prop, "Field of View", "Field of view for the fisheye lens"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_lens", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 100.0); + RNA_def_property_ui_range(prop, 0.01, 15.0, 3, 2); + RNA_def_property_ui_text(prop, "Fisheye Lens", "Lens focal length (mm)"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "latitude_min", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, -0.5 * M_PI, 0.5 * M_PI); + RNA_def_property_ui_range(prop, -0.5 * M_PI, 0.5 * M_PI, 3, 2); + RNA_def_property_ui_text( + prop, "Min Latitude", "Minimum latitude (vertical angle) for the equirectangular lens"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "latitude_max", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, -0.5 * M_PI, 0.5 * M_PI); + RNA_def_property_ui_range(prop, -0.5 * M_PI, 0.5 * M_PI, 3, 2); + RNA_def_property_ui_text( + prop, "Max Latitude", "Maximum latitude (vertical angle) for the equirectangular lens"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "longitude_min", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -M_PI, M_PI, 3, 2); + RNA_def_property_ui_text( + prop, "Min Longitude", "Minimum longitude (horizontal angle) for the equirectangular lens"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "longitude_max", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -M_PI, M_PI, 3, 2); + RNA_def_property_ui_text( + prop, "Max Longitude", "Maximum longitude (horizontal angle) for the equirectangular lens"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_polynomial_k0", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6); + RNA_def_property_ui_text(prop, "Fisheye Polynomial K0", "Coefficient K0 of the lens polynomial"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_polynomial_k1", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6); + RNA_def_property_ui_text(prop, "Fisheye Polynomial K1", "Coefficient K1 of the lens polynomial"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_polynomial_k2", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6); + RNA_def_property_ui_text(prop, "Fisheye Polynomial K2", "Coefficient K2 of the lens polynomial"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_polynomial_k3", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6); + RNA_def_property_ui_text(prop, "Fisheye Polynomial K3", "Coefficient K3 of the lens polynomial"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + + prop = RNA_def_property(srna, "fisheye_polynomial_k4", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, 6); + RNA_def_property_ui_text(prop, "Fisheye Polynomial K4", "Coefficient K4 of the lens polynomial"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); + /* pointers */ prop = RNA_def_property(srna, "dof", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "CameraDOFSettings");